supertensor: shape-aware tensor figure toolkit
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.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user