Figures were positioned by hand-written offsets. Every gap was a magic number tuned against the content that happened to be there, so a label that grew two characters landed on the next tensor, and two stages started from two different x shared no rail. Both failures compile cleanly. Replace it with a cursor. Objects placed with an empty coordinate argument reserve their own width -- including a stack's offset sheets and a bracket's overhang -- and gaps are declared once (\stgutter, \strowgap, \stblockgap). The gap belongs to the object that follows it and the first object in a band gets none, so every band starts flush on a shared rail and gap=0pt states that two shards tile exactly. \stlink makes a connector's label a flow object, which is what removes the label-wider-than-its-arrow failure entirely. \stcol is a vertical sub-flow for a split along the contracted axis. \strow declares its height, so an object that does not fit -- or a column that does not add up to what it declared, and is therefore drawn off-center -- becomes a package warning, which build.sh fails on. Absolute placement is unchanged: passing a coordinate takes the original code path, and \sttrack folds a hand-placed node back into the cursor. All three golden examples and the new tests/flow.tex are converted and build clean.
62 lines
3.4 KiB
Markdown
62 lines
3.4 KiB
Markdown
# Anti-patterns
|
||
|
||
Every figure below compiles cleanly. `build.sh` is happy with all of them. They are still
|
||
wrong, because the compiler checks TeX syntax and not whether the picture is true.
|
||
|
||
Render `examples/antipatterns.tex` and look at
|
||
`examples/build/antipatterns.png` once before your first figure.
|
||
|
||
## 1. The transpose that only changed its label
|
||
|
||
A face captioned `Kᵀ` that is still `T × d_h`. The reader looks for the contracted axis,
|
||
finds two faces of the same height, and concludes the contraction runs along the wrong
|
||
dimension. **Fix:** swap the arguments — `\ststack{KT}{...}{dh}{T}{3}`. See `geometry.md` §3.
|
||
|
||
## 2. Shards that do not tile their parent
|
||
|
||
Two shards drawn with a gap, or stretched to fill a parent whose other shards were elided.
|
||
Both assert a width that the tensor does not have. **Fix:** draw the shards in one band
|
||
and give every shard after the first `gap=0pt`, which *states* that they are adjacent
|
||
instead of arranging for it; draw an ellipsis for anything omitted. See `geometry.md` §5–6.
|
||
|
||
## 3. An index drawn as a heatmap
|
||
|
||
Expert ids or token positions rendered with a lightness ramp. The ramp is a magnitude
|
||
channel, so it says `expert 3 > expert 0`, which is meaningless. **Fix:** `\stindexface`.
|
||
See `semantics.md`.
|
||
|
||
Same family: a Boolean mask drawn with graded cells (it has one level, not three), and a
|
||
score matrix drawn as flat blocks (it has magnitude, and hiding it wastes the figure).
|
||
|
||
## 4. One pale level everywhere
|
||
|
||
A whole tensor in `role!10`. At full size it looks tasteful; at thumbnail size — which is
|
||
how it will be seen on a slide — it is a blank rectangle. **Fix:** three separated levels,
|
||
`role!30 / role!55 / role!80`. Contrast comes from lightness, not saturation.
|
||
See `style.md`.
|
||
|
||
## Not in the gallery, but just as common
|
||
|
||
- **Periodic texture.** A polynomial hash reduced mod 3 repeats every 3 rows, and the eye
|
||
reads the resulting stripe as real structure. `pattern=dense` avoids it; if you write
|
||
your own filler, check that rows 1, 2, 4, 5 of a tall face are not identical.
|
||
- **A label wider than its connector.** The white underlay then covers the target tensor.
|
||
`\stlink` makes this unrepresentable: the label reserves its own width in the band and
|
||
the arrow is drawn to whatever lands beside it. See `layout.md`.
|
||
- **A new hue for a regrouped view of the same data.** `X` and the per-expert buffers
|
||
gathered out of `X` are the same object in a different order; a second hue claims they
|
||
are different tensors.
|
||
- **Captions hanging at different depths** because the faces in a row have different
|
||
heights. Use `\strow`/`\strowend`, which arms `\stlane` for you.
|
||
- **Hand-tuned offsets.** Each one is a magic number valid only for the content that was
|
||
there when you tuned it; the figure that breaks is the *next* one, when a label grows two
|
||
characters and lands on a face. Use the cursor. See `layout.md`.
|
||
- **A formula line placed first.** It can only be centered on a figure whose width is not
|
||
known yet, so it ends up visibly off-center. Call `\sttopformula` after the bands.
|
||
- **A floating commentary card between two operands.** If it is not a real operation, it
|
||
belongs in the stage subtitle or the bottom box.
|
||
- **A meaning box that repeats the shapes.** The shapes are already under every block. The
|
||
box is for what the axes *mean* and what the operation *does*.
|
||
- **Solving crowding by shrinking type.** The type hierarchy is a hard floor; move the
|
||
stage to another row instead.
|