The render tree#
renderer.render() returns a render tree: the pieces each handler returned, nested
the way the nodes are nested. complete() receives it. With the built-in handlers, the
tree uses three shapes, which is all join_item needs to understand.
Shape |
Means |
Produced by |
|---|---|---|
|
A whole line |
headings, comment lines, parameter grids, multi-line calcs, |
|
One line, as parts to be joined with |
calculation lines ( |
|
A block: a header line, then a body of items one level deeper |
|
A falsy item ("", None, []) renders nothing: it is what a comment command or an
ignored line leaves behind.
A block whose header is empty is a flat group: its body stays at the current depth.
That is how a run of calculation lines is kept together (so the LaTeX renderer can put it
in one aligned environment) without being indented.
['# Check',
['', [['a', '=', '2'], ['b', '=', 'a * 3', '=', '2 * 3', '=', '6', '(note)']]],
['Since (b>5) -> (6>5) is True:',
[['', [['c', '=', 'b - 5', '=', '6 - 5', '=', '1']]]]]]
from
## Check
a = 2
b = a * 3 # note
if b > 5:
c = b - 5
Reading it from the outside in: a heading string; a flat group (header '') holding the
two calculation lines; and the if (an ElifBlock renders as its true branch), which is
a header string and a body containing a flat group with one line.
Your own shapes#
Handlers can return anything, as long as your complete() (and join_item, if you use
join) knows what to do with it. The structured data example returns
dicts from its line handlers; the Excel renderer returns row objects; the Word renderer
returns OMML strings for calc lines and small objects for headings and params tables. If you keep the
base handlers for some node types and use join, keep their outputs in the three shapes
above.
Next: Example: a Unicode renderer.