|
| 1 | +--- |
| 2 | +description: Use when editing Typst files — covers general patterns, CeTZ drawing, plotting, and utility functions |
| 3 | +globs: ["*.typ"] |
| 4 | +--- |
| 5 | + |
| 6 | +# Typst Editing Reference |
| 7 | + |
| 8 | +Reference files: ~/Documents/private-note/notes/typst-learn/ (typst-tricks.typ, typst-drawing.typ, typst-my-utils.typ) |
| 9 | + |
| 10 | +## General Typst Patterns |
| 11 | + |
| 12 | +### Page Setup |
| 13 | +- Standalone figures: `#set page(width: auto, height: auto, margin: 5pt)` |
| 14 | +- Standard notes: `#set page(margin: 2cm)` + `#set text(size: 10pt)` + `#set heading(numbering: "1.1.")` |
| 15 | +- Numbered equations: `#set math.equation(numbering: "(1)")` |
| 16 | + |
| 17 | +### Common Packages |
| 18 | +- CeTZ: `@preview/cetz:0.4.0`, `@preview/cetz-plot:0.1.2` |
| 19 | +- Algorithms: `@preview/algorithmic:1.0.3` — `Function`, `For`, `While`, `If`, `ElseIf`, `Else`, `Assign`, `Return`, `Comment` |
| 20 | +- Math: `@preview/physica:0.9.3` (physics notation), `@preview/ouset:0.2.0` (over/under sets) |
| 21 | +- Theorems: `@preview/ctheorems:1.1.2` or `@preview/unequivocal-ams:0.1.2` |
| 22 | +- Random: `@preview/suiji:0.3.0` — `gen-rng(seed)`, `uniform(rng, size: n)`, `shuffle(rng, arr)` |
| 23 | + |
| 24 | +### Math Notation |
| 25 | +- Bra-ket: `$|psi chevron.r$`, `$chevron.l phi|$` |
| 26 | +- Blackboard bold: `$bb(I)$`, calligraphic: `$cal(E)$` |
| 27 | +- Accents: `$hat(N)$`, `$tilde(H)$`, `$overline(X)$` |
| 28 | +- Cases: `$ f(x) = cases(x^2 &"if" x > 0, 0 &"otherwise") $` |
| 29 | +- Matrices with ellipses: `$mat(a, dots; dots.v, dots.down;)$` |
| 30 | + |
| 31 | +### Citations |
| 32 | +- Inline: `@Author2024`, with locator: `@Author2024[Ch. 4]` |
| 33 | +- Prose: `#cite(<Author2024>, form: "prose")` |
| 34 | +- Compact slides style: `#set cite(style: "author-journal-year.csl")` |
| 35 | + |
| 36 | +### Functional Idioms |
| 37 | +- `range(n).map(_ => 0)` — zeros array |
| 38 | +- `a.zip(b).map(((x, y)) => ...)` — pairwise ops |
| 39 | +- `for (k, (i, j)) in pts.enumerate() { ... }` — destructuring enumerate |
| 40 | +- `dict.at(key, default: 0)` — dict with default |
| 41 | + |
| 42 | +### Content Helpers |
| 43 | +- Infobox: `rect(stroke: color, inset: 8pt, radius: 4pt, width: 100%, [*Title:*\ body])` |
| 44 | +- Inline image alignment: `box(image(...), baseline: (size - 20pt) / 2 + offset)` |
| 45 | +- Image clipping: `box(clip: true, img, inset: (top: -top, bottom: -bottom, ...))` |
| 46 | +- Two columns: `grid(columns: (1fr, 1fr), gutter: 20pt, left, right)` |
| 47 | + |
| 48 | +## CeTZ Drawing |
| 49 | + |
| 50 | +### Core Rules |
| 51 | +1. **Name all objects** that will be referenced later: `circle(..., name: "c")`, `line(..., name: "edge")` |
| 52 | +2. **Connect objects by name + anchor**, never by raw coordinates: `line("a.east", "b.west")`, not `line((2, 0), (5, 0))` |
| 53 | +3. **Use `set-origin`** for sub-figures instead of manual coordinate offsets |
| 54 | +4. **Use `on-layer`** for layering: -1 for backgrounds, 0 for main content, 1 for labels |
| 55 | +5. **Use `content()` with `frame: "rect"`** for labeled boxes; use `fill: white, stroke: none` for edge labels |
| 56 | +6. **Inside CeTZ functions**, always `import draw: *` for unqualified access |
| 57 | + |
| 58 | +### Gotchas |
| 59 | +- **`arc`**: first parameter is the **start point** of the arc, not the center of the circle |
| 60 | +- **`bezier`**: first two args are **start and end points**; remaining args are control points |
| 61 | +- **Arrows**: prefer `mark: (end: "straight")` style — do NOT use `">"` |
| 62 | +- **Stroke dict**: use `(paint: color, thickness: 1pt, dash: "dashed")` — NOT `stroke(...)` constructor |
| 63 | + |
| 64 | +### Quick Reference |
| 65 | +- Shapes: `circle`, `rect`, `line`, `arc`, `bezier`, `hobby`, `catmull`, `merge-path`, `grid` |
| 66 | +- Anchors: `"name.north"`, `.south`, `.east`, `.west`, `.center`, `.start`, `.mid`, `.end` |
| 67 | +- Coordinates: `(x, y)`, `(rel: (dx, dy), to: "name")`, `("a", 50%, "b")`, `("a", "|-", "b")` |
| 68 | +- Marks (arrows): `"straight"`, `">"`, `"stealth"`, `"|"`, `"o"`, `"<>"`, `"hook"`, `"]"` |
| 69 | +- Strokes: `(dash: "dashed")`, `(dash: "dotted")`, `(dash: "dash-dotted")`, `2pt + red` |
| 70 | +- Colors: `blue.lighten(60%)`, `green.darken(20%)`, `rgb("#f0f0fe")` |
| 71 | +- Decorations: `decorations.brace`, `.flat-brace`, `.zigzag`, `.wave`, `.coil` |
| 72 | +- Trees: `tree.tree((...), direction: "down", grow: 1.5, spread: 1.8)` |
| 73 | + |
| 74 | +### Drawing Patterns |
| 75 | +- **Graph rendering**: name vertices as `str(k)`, connect with `line(str(k), str(l))` |
| 76 | +- **Circular layout**: use `vrotate(v, theta)` helper to place vertices on a circle |
| 77 | +- **Edge labels**: `content("edge.mid", label, fill: white, frame: "rect", padding: 0.08, stroke: none)` |
| 78 | +- **Data-driven diagrams**: store layout as list of tuples, iterate with `for` loops |
| 79 | +- **Tensor networks**: `tensor` (circle + label), `deltatensor` (small filled dot), `labeledge` (line + midpoint label) |
| 80 | +- **Intersections**: `intersections("ix", { ...shapes... })` then reference `"ix.0"`, `"ix.1"` |
| 81 | + |
| 82 | +## CeTZ Plotting |
| 83 | +- `plot.plot(size: (w, h), axis-style: "scientific", x-tick-step: 1, y-tick-step: 2, { ... })` |
| 84 | +- Line: `plot.add(domain: (a, b), x => f(x), label: $f$, style: (stroke: blue))` |
| 85 | +- Data: `plot.add(data, mark: "o", line: "spline")` — line types: `"linear"`, `"spline"`, `"vh"`, `"hv"` |
| 86 | +- Scatter marks: `"*"`, `"o"`, `"square"`, `"triangle"`, `"+"`, `"|"`, `"-"`, `"<>"` |
| 87 | +- Fill between: `plot.add-fill-between(f, g, domain: (a, b))` |
| 88 | +- Reference lines: `plot.add-hline(y)`, `plot.add-vline(x)` |
| 89 | +- Annotations: `plot.add-anchor("name", (x, y))`, `plot.annotate({ ... })` |
| 90 | +- Bar chart: `chart.barchart(data, size: ..., mode: "clustered", labels: (...))` |
| 91 | +- Pie chart: `chart.piechart(data, inner-radius: 0.5, outer-label: (content: auto, radius: 130%))` |
0 commit comments