Skip to content

without_html

HTML as immutable Python values: build a node tree, render it to a string.

without_html

DOCTYPE module-attribute

DOCTYPE = Markup('<!doctype html>')

AnyElement

AnyElement = Element | VoidElement

Attributes

Attributes = Mapping[str, AttributeValue]

AttributeValue

AttributeValue = str | int | bool | None

Child

Child = Element | VoidElement | str | SupportsHtml | None

ClassNames

ClassNames = (
    str | Sequence[str | None] | Iterator[str | None] | None
)

Node

SupportsHtml

Bases: Protocol

An object that can represent itself as markup, via the __html__ convention.

The protocol MarkupSafe established and the wider templating ecosystem honours. Accepting it is what lets a value that knows its own markup (a domain type, a template rendered elsewhere) sit in a child position without this package knowing anything about it.

Element dataclass

Element(
    tag: str,
    attributes: tuple[Attribute, ...] = (),
    children: tuple[Child, ...] = (),
)

An element with content: a tag, its rendered attributes, and its children.

Build these through a named constructor in without_html.elements, or element for a tag HTML does not define, and change one with with_attributes and with_children. The fields here are the already-parsed form, with attributes escaped and children flattened to a tuple, so writing them directly is writing the output of a parse that never ran: an attribute value assembled at the call site reaches the markup unescaped.

tag instance-attribute

tag: str

attributes class-attribute instance-attribute

attributes: tuple[Attribute, ...] = ()

children class-attribute instance-attribute

children: tuple[Child, ...] = ()

with_attributes

with_attributes(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> Element

A new element with cls and attrs laid over this one's attributes.

The transform half of the constructors, taking its arguments in the same shape they do, so that changing an element during a walk is spelled the way building one is and goes through the same escaping:

el.with_attributes(attrs={"nonce": nonce}) if el.tag == "script" else el

A name already on the element is replaced where it stands, an attrs entry set to None removes it, and cls replaces the classes when given. See merged_attributes for why replacing in place is the only correct arm of that.

with_children

with_children(children: Node) -> Element

A new element with children in place of this one's.

Wholesale rather than an insert or an append, because the children are already a value: el.with_children([*el.children, footer]) adds one and reads as what it does, and nothing here has to grow a second way to say it.

A raw-text element (<script>, <style>) keeps its own rule about content, which is why this exists rather than dataclasses.replace: replace would put an escaped string inside a <script>, where nothing escapes and the entities are the program.

ElementConstructor

Bases: Protocol

The call signature every named element constructor shares, and its tag identity.

RawTextElementConstructor

Bases: Protocol

The call signature every raw-text element constructor shares, and its tag identity.

VoidElement dataclass

VoidElement(
    tag: str, attributes: tuple[Attribute, ...] = ()
)

An element with no content and no closing tag: <br>, <img>, <input>.

A separate type rather than a flag, so that giving one children is not a mistake to be caught but a thing that cannot be written: there is no field to put them in and no parameter on the constructors that build these.

tag instance-attribute

tag: str

attributes class-attribute instance-attribute

attributes: tuple[Attribute, ...] = ()

with_attributes

with_attributes(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

A new element with cls and attrs laid over this one's attributes.

Element.with_attributes, for an element with no content; the semantics are described there.

VoidElementConstructor

Bases: Protocol

The call signature every named void element constructor shares, and its tag identity.

element

element(
    tag: str,
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

Build one element with any tag, without naming a constructor first.

The one-shot form of element_type, for a tag used once (an SVG child, a custom element that appears in a single component). Where the tag appears more than once, element_type reads better and moves the tag check out of the call.

element_type

element_type(tag: str) -> ElementConstructor

Define a constructor for tag, equal in standing to the named ones.

How a custom element joins the vocabulary: bind it once at module scope and use it exactly like div, rather than repeating a tag string at every call site.

chart = element_type("x-chart")
chart(attrs={"data-series": series}, children=caption)

Whether the tag is one this package handles specially is settled here, when the constructor is defined, so calling it does no checking at all. That is the same trade the generated constructors make, available to a tag that was not known when they were generated.

void_element_type

void_element_type(tag: str) -> VoidElementConstructor

Define a constructor for tag as an element with no content and no closing tag.

The other arm of element_type, for a tag whose content model is empty. HTML's own void elements are named already and a custom element may not be void, so this is for markup that is not quite HTML: an XML-ish document, or a foreign vocabulary rendered through the same tree.

render_chunks

render_chunks(
    node: Node,
    *,
    fragments_per_chunk: int = FRAGMENTS_PER_CHUNK,
) -> Iterator[str]

Render a node tree to markup a chunk at a time.

The same walk render does and the same bytes in the same order, handed back as they are produced rather than held whole, so a large page starts reaching a client while the rest of it is still being built and the process never holds the finished string. "".join(render_chunks(node)) is render(node).

A chunk is fragments_per_chunk fragments joined, not a byte budget: counting bytes on every fragment costs several times what batching them does, and the point of the knob is to bound how often a consumer is called, not to hand it uniform buffers. Chunks are therefore roughly even in size but not exactly, and a single large Markup child goes out whole in whatever chunk it lands in.

What streaming costs is worth choosing deliberately rather than defaulting into: the total length is not known until the walk ends, and once the first chunk has been handed on there is no taking it back, so a failure partway through a tree can no longer be turned into something else.

a

a(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <a> element.

abbr

abbr(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <abbr> element.

address

address(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <address> element.

area

area(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <area> element.

article

article(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <article> element.

aside

aside(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <aside> element.

audio

audio(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <audio> element.

b

b(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <b> element.

base

base(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <base> element.

bdi

bdi(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <bdi> element.

bdo

bdo(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <bdo> element.

blockquote

blockquote(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <blockquote> element.

body

body(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <body> element.

br

br(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <br> element.

button

button(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <button> element.

canvas

canvas(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <canvas> element.

caption

caption(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <caption> element.

cite

cite(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <cite> element.

code

code(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <code> element.

col

col(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <col> element.

colgroup

colgroup(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <colgroup> element.

data

data(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <data> element.

datalist

datalist(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <datalist> element.

dd

dd(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <dd> element.

del_

del_(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <del> element.

details

details(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <details> element.

dfn

dfn(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <dfn> element.

dialog

dialog(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <dialog> element.

div

div(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <div> element.

dl

dl(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <dl> element.

dt

dt(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <dt> element.

em

em(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <em> element.

embed

embed(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <embed> element.

fieldset

fieldset(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <fieldset> element.

figcaption

figcaption(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <figcaption> element.

figure

figure(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <figure> element.

footer

footer(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <footer> element.

form

form(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <form> element.

h1

h1(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h1> element.

h2

h2(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h2> element.

h3

h3(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h3> element.

h4

h4(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h4> element.

h5

h5(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h5> element.

h6

h6(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <h6> element.

head

head(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <head> element.

header

header(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <header> element.

hgroup

hgroup(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <hgroup> element.

hr

hr(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <hr> element.

html

html(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <html> element.

i

i(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <i> element.

iframe

iframe(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <iframe> element.

img

img(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <img> element.

input_

input_(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <input> element.

ins

ins(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <ins> element.

kbd

kbd(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <kbd> element.

label

label(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <label> element.

legend

legend(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <legend> element.

li

li(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <li> element.

link(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <link> element.

main

main(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <main> element.

map_

map_(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <map> element.

mark

mark(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <mark> element.

menu

menu(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <menu> element.

meta

meta(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <meta> element.

meter

meter(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <meter> element.

nav

nav(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <nav> element.

noembed

noembed(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <noembed> element.

noframes

noframes(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <noframes> element.

noscript

noscript(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <noscript> element.

object_

object_(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <object> element.

ol

ol(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <ol> element.

optgroup

optgroup(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <optgroup> element.

option

option(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <option> element.

output

output(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <output> element.

p

p(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <p> element.

picture

picture(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <picture> element.

pre

pre(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <pre> element.

progress

progress(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <progress> element.

q

q(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <q> element.

rp

rp(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <rp> element.

rt

rt(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <rt> element.

ruby

ruby(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <ruby> element.

s

s(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <s> element.

samp

samp(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <samp> element.

script

script(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <script> element.

search

search(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <search> element.

section

section(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <section> element.

select

select(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <select> element.

slot

slot(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <slot> element.

small

small(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <small> element.

source

source(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <source> element.

span

span(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <span> element.

strong

strong(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <strong> element.

style

style(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <style> element.

sub

sub(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <sub> element.

summary

summary(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <summary> element.

sup

sup(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <sup> element.

svg

svg(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <svg> element.

table

table(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <table> element.

tbody

tbody(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <tbody> element.

td

td(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <td> element.

template

template(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <template> element.

textarea

textarea(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <textarea> element.

tfoot

tfoot(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <tfoot> element.

th

th(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <th> element.

thead

thead(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <thead> element.

time

time(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <time> element.

title

title(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <title> element.

tr

tr(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <tr> element.

track

track(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <track> element.

u

u(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <u> element.

ul

ul(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <ul> element.

var

var(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <var> element.

video

video(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Node = None,
) -> Element

The <video> element.

wbr

wbr(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
) -> VoidElement

The <wbr> element.

xmp

xmp(
    *,
    cls: ClassNames = None,
    attrs: Attributes | None = None,
    children: Markup | None = None,
) -> Element

The <xmp> element.