Extracted from the tensor-formula-viz skill and rebuilt around the idea that the geometry rules should be enforced by construction rather than restated as prose an agent has to remember. - assets/supertensor.sty: faces, stacks, index faces, shared caption lanes, meaning box, signature. Macros take a declared axis and a declared role, so equal shapes get equal edges, a x a is square, a transpose swaps the face, and contracted axes share an edge length -- without any manual alignment. - scripts/preflight.sh: decide the TikZ/CJK path before drawing. - scripts/build.sh: compile and fail on silent corruption (missing CJK glyphs, overfull boxes, undeclared roles), then export pdf/svg/png/thumb. - scripts/test.sh: build every figure as a regression test for the package. - examples/: three golden figures (TP-FFN, causal MHA, MoE top-k gather) plus an anti-pattern gallery of figures that compile cleanly and still lie. - SKILL.md + references/: lean entry point, details loaded on demand.
90 lines
3.0 KiB
Markdown
90 lines
3.0 KiB
Markdown
# Layout invariants
|
||
|
||
Everything on the canvas is a bounding box: tensors, full offset stacks, brackets,
|
||
operators, arrow labels, annotations, symbols, shape labels, stage headings, the meaning
|
||
box, the signature. **Tangency counts as collision.**
|
||
|
||
## Gutters
|
||
|
||
Define one base gutter `g ≥ 1 em`. Unrelated boxes stay at least `g` apart; stage bands at
|
||
least `1.5g`. In practice: `right=5mm–9mm` between an operator and its operands, `7mm–9mm`
|
||
between the last caption of one row and the next stage heading.
|
||
|
||
Overlap is allowed only inside one declared composite:
|
||
|
||
- tiles inside their own face,
|
||
- shards tiling a parent,
|
||
- outline sheets in one `\ststack`,
|
||
- a bracket around its own tensor,
|
||
- a connector endpoint touching its source/target border.
|
||
|
||
Every other intersection or occlusion is forbidden.
|
||
|
||
## Lanes
|
||
|
||
Reserve separate vertical lanes and never put anything else in them:
|
||
|
||
```
|
||
stage heading
|
||
(connector annotations)
|
||
tensor / operator row
|
||
symbols <- \stcaption arg 2
|
||
shapes <- \stcaption arg 3
|
||
```
|
||
|
||
Faces of different heights would otherwise hang their captions at different depths. Fix it
|
||
with a shared baseline:
|
||
|
||
```tex
|
||
\node[inner sep=0pt, fit=(Q)(KT)(S)] (rowA) {};
|
||
\stlane{rowA}
|
||
\stcaption{Q}{$\mathbf Q^{(i)}$}{$h\times T\times d_h$}
|
||
...
|
||
\stnolane
|
||
```
|
||
|
||
Every `\stcaption` between `\stlane` and `\stnolane` hangs from the bottom of `rowA`, so
|
||
symbols and shapes form two flat lanes.
|
||
|
||
Stage headings share one left rail. Anchor each heading below the previous row but at the
|
||
previous *heading's* x, not at the previous row's content:
|
||
|
||
```tex
|
||
\coordinate (cy) at ($(I-shape.south)+(0,-9mm)$);
|
||
\node[st stage, anchor=north west] (SC) at (SB.west |- cy) {...};
|
||
```
|
||
|
||
Explanatory prose belongs in the stage subtitle, the bottom box, or above its own
|
||
connector. Never drop a floating commentary card between two operands unless it is a real
|
||
operation node (`st comm`).
|
||
|
||
## Layers
|
||
|
||
The package declares three: `stbg` (connectors), `main` (tensors, operators), `stfg`
|
||
(text). `\starrow` and `\starrowlabel` route on `stbg` automatically, so a connector can
|
||
never cover a face. Two consequences you still own:
|
||
|
||
- A connector may not cross a box that is not one of its endpoints. Move the row, don't
|
||
route over.
|
||
- A label's white underlay may cover only its own connector — never a tensor, never
|
||
another label. If the label is wider than the arrow, shorten the label or widen the gap.
|
||
This is the single most common failure after a first draft.
|
||
|
||
## Stacks
|
||
|
||
`\ststack` includes its offset sheets in the bounding box, so neighbours can be spaced
|
||
against the real extent. Back sheets are outline-only and must carry no semantic content
|
||
of their own. If individual slices need to be read, use separate panels instead of overlap.
|
||
|
||
## When it does not fit
|
||
|
||
In this order:
|
||
|
||
1. shorten or remove secondary annotation,
|
||
2. widen the natural crop,
|
||
3. increase row spacing,
|
||
4. move the whole stage to another row.
|
||
|
||
Never solve crowding by shrinking below the type hierarchy, closing the gutter, or covering
|
||
another object.
|