feat(diagram-engine): flex knobs (grow/align/pad) + inline rich-text labels

The expressiveness gap between engine output and hand-written XML came down
to two missing capabilities, both generic:

- Block layout inside a box: nested containers already existed, but there was
  no way to split space by weight, pin a child to an edge, or tighten padding.
  Added grow (flex-grow over the parent's leftover flow-axis space, TeX's
  glue), align (start/center/end/stretch on the cross axis) and pad
  (per-group interior padding). All three round-trip via dai_grow/dai_align/
  dai_pad markers.

- Inline rich text: labels already render HTML (html=1 on every style, esc()
  entities decode back), but the measure pass counted markup as text. The
  visibleText() strip makes autoBoxSize measure what draw.io draws: <br> is a
  line, other inline tags are invisible.

Graphviz (HTML-like table labels), D2 (grid containers + markdown-in-shape)
and TeX (box+glue) converged on exactly this design: nested boxes for block
structure, proportional glue, a small inline set for text — never full HTML.

Prompts teach the composition with a comparison-card recipe; verified by
rebuilding the CoT poster end to end in the real editor.
This commit is contained in:
dayuan.jiang
2026-08-09 20:55:12 +09:00
parent e78322ca52
commit db9db1ff4e
9 changed files with 432 additions and 23 deletions

View File

@@ -104,11 +104,26 @@ Use restructure_diagram when the diagram's meaning is in NESTING or in a fixed f
This applies to BOTH creating and editing.
Use restructure_diagram ALSO for poster-style layouts — paper summaries, cheat sheets,
infographics, comparison sheets: a col container as the page, a banner box as the masthead
(no set_title — the banner IS the title), a row of col containers as columns, each section
a "heading"-role container with its own group name (sections sharing a group share a hue).
Give boxes roles (callout, good/bad, metric, muted) — roles are the visual hierarchy,
groups are the colour, and the engine guarantees nothing overlaps.
infographics, comparison sheets. The layout model is flexbox: row/col containers nest
freely, and a box with INTERNAL structure is just an invisible col container (pad 10-14)
holding smaller boxes. Three knobs, use them everywhere:
- grow: columns split leftover width by weight (grow 3 / grow 2 makes a 3:2 page).
- align "stretch": a child fills its parent's cross axis — headings, highlight bars and
body boxes should almost always stretch, or the column looks ragged.
- pad: small (8-14) for tight cards, default 24 for roomy sections.
Labels take inline HTML — <b>, <i>, <font color="#1B5E20">, <br> — so one box can hold a
bold keyword, a second paragraph, a coloured verdict line. Emoji in headings (💡 Core Idea)
cost nothing and read instantly.
Recipe: a col container as the page (banner box as masthead, align stretch — no set_title,
the banner IS the title), a row of col containers with grow weights as columns, each section
a heading-role box + content. Roles (callout/good/bad/metric/muted) are the hierarchy,
group names are the colour, and the engine guarantees nothing overlaps.
A comparison card, concretely:
add_container id=std dir=col gap=8 pad=12 grow=1 role=bad (a red panel)
add_box parent=std label="<b>Standard Prompting</b>" align=stretch
add_box parent=std label="Q: …the problem text…" align=stretch
add_box parent=std role=bad label="A: The answer is 11." align=stretch
add_box parent=std label="<font color=\\"#B85450\\"><b>✗ Often Wrong</b></font>" align=start
Use display_diagram only for diagrams that need ABSOLUTE positioning, where the engine's layout
would be wrong rather than merely different: