Lists
A <x:list> is a vertical stack of <x:li> items, each flowed and wrapped like a mini <x:textbox>
but with a hanging indent: the marker sits in the gutter and continuation lines align to the text
column, not back under the marker. It is the ordered/unordered list SVG never got, and lowers to a
<g> of drawn bullet shapes plus one plain <text> of positioned <tspan>s — live and selectable.
Syntax
<x:list x="40" y="80" width="300" list="bullet" font-size="14" item-spacing="5">
<x:li>Top-level item that wraps under its own text column</x:li>
<x:li indent="1">A nested item — one indent step in</x:li>
<x:li indent="2">Deeper still</x:li>
</x:list>
Hanging indent and nesting
Each <x:li> is one item; indent="N" sets its nesting level (0 is the top). Every level steps
the text column right by the indent step, and continuation lines of a wrapped item align to that
column — the marker hangs in the gutter to its left. An empty item still advances one line.
Markers cycle by depth
Bullet markers are drawn shapes, not font glyphs, so they don't vary by font and stay optically
balanced. They cycle every three levels: a filled disc, a hollow ring, then a filled
square. The shapes are area-compensated — the square's side is r·√π so its area matches the
disc's, and the ring's outer diameter is enlarged about 12% since a hollow mark reads lighter.
With list="number", markers cycle decimal → lower-alpha → lower-roman by depth and keep an
outline counter per level. The counter restarts whenever nesting pops back to a shallower level,
so a top item after a sublist resumes where it left off — 1. 2. a. b. 3. Numbers are right-aligned
into the gutter, so 1. and 10. share a column edge.
list="none" suppresses the marker but keeps the indent. A marker on the list — or on a single
<x:li> — forces a named drawn shape (disc / circle / square / dash) or any literal string
(▸, —, ★, …), overriding the cycle.
Flowing inside a shape
Instead of x / y / width, give the list in="#rect" to take its left edge, top, and width from
a referenced shape's bounding box (a baked reference). That box also supplies the height for valign,
so a list can sit top, middle, or bottom inside a card.
Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
list | bullet / number / none | bullet | Marker style for the whole list. |
marker | disc / circle / square / dash, or a literal string | — | Force a marker (drawn shape or literal text); overrides the list cycle. |
marker-size | number | 1 | Scale factor on the drawn bullet shapes. |
marker-fill | color | fill | Marker color (shapes and number/character markers). |
x y width | length | — | The block's left edge, top, and content width. |
in | #id | — | Bind geometry to a referenced shape's bounding box; also supplies the height for valign. |
valign | top / middle / bottom | top | Vertical placement within the height. |
indent | length | 1.5em | Per-level indent step. |
marker-gap | length | 0.5em | Gap between the marker and the text column. |
item-spacing | length | 0.35em | Extra vertical gap between items. |
font-*, line-height, fill | as text | — | Base style for every item. |
An <x:li> may set indent="N", marker="…", and font-size="…" (a smaller sub-point). It inherits
the list's size and line-height otherwise, and its marker scales to match its size.
How it lowers
A <x:list> compiles to a <g> containing the drawn bullet shapes plus one plain <text> whose
positioned <tspan>s carry the item text and any number/character markers — no runtime, fully
selectable.
v0 limits
One style per item beyond font-size (inline <tspan> fill/weight inside an item is not yet applied).
No shrink-to-fit or height clipping — the list flows from valign within the height but doesn't shrink
to fit it. Number, roman, and character markers are live text (the glyphs must exist in the font);
bullet shapes are drawn and font-independent.
See also
- Paragraphs — stacked paragraphs in one textbox.
- Tables — content-driven grids of wrapped cells.
- Wrapping and flow into shapes.