Skip to content

The Operators

Carl Smith edited this page May 30, 2018 · 5 revisions

Elements are just mutable containers that can be rendered as HTML. That idea is where HTME began. We use constructor functions to initialize elements and use operators to mutate them.

The four most important operators are update children, replace children, update attributes and replace attributes.

You can append one or more children to an element like this:

element *= childA, childB, childC

You can replace all of an element's children with one or more new children like this:

element /= childA, childB, childC

You can update one or more of an element's attributes like this:

element **= { A: value, B: value, C: value … }

And, you can replace all of the attributes of an element with one or more new attributes like this:

element //= { A: value, B: value, C: value … }

Square Bracket Operators

You can use square brackets to reference and assign to the attributes of an element by key:

>>> paragraph = P()
>>> paragraph['id'] = 'synopsis'
>>> paragraph
<p id="synopsis"></p>

>>> paragraph['id']
'synopsis'

You can also use square brackets to reference children by index (recursively). This expression evaluates to the second child of the first child of element:

element[0][1]

Naturally, you can assign to an index, replacing the child that was there:

>>> div = DIV(P("first"), P("second"))
>>> div[0] = ASIDE("replacement")
>>> div
<div><aside>replacement</aside><p>second</p></div>

If you assign more than one child to an index, all of the children are inserted (in the same order):

>>> div = DIV(P("first"), P("second"))
>>> div[0] = SPAN("one"), SPAN("two"), SPAN("three")
>>> div
<div><span>one</span><span>two</span><span>three</span><p>second</p></div>

Equality Operators

When elements are compared for equality (using the == and != operators), it is their HTML string representations that are actually compared. Attributes are rendered deterministically (the names are sorted asciibetically), so this always works:

>>> DIV({'class': 'A', 'id': 'B'}) == DIV({'id': 'B', 'class': 'A'})
True

Element Iteration

You can directly iterate over an element’s children:

ids = [ child["id"] for child in element ]

Each element has properties named attributes and children that refer to its attributes dict and child array, so you can do stuff like this too:

for key, value in element.attributes.items(): print(key, "->", value)

Slicing Children

You can slice an element just like a list:

element[:]  # a list of every child
element[2:] # a list of all but the first two children

Slice operations actually evaluate to an instance of Nodes, which is a pure superset of list. Instances of Nodes do everything that lists do, but also support the element operators, operating on every element in the slice. For example, the following statement updates the class attribute of each child of element, except the first two:

element[2:] **= {"class": "button"}

Compound Expressions

Naturally, you can combine operators in anyway that makes sense:

element[0][-1] **= {"class": "button"}

Note that, as only one attribute is being assigned to in the last example, this would be more idiomatic:

element[0][-1]["class"] = "button"
Clone this wiki locally