Skip to content

Commit 1d7372e

Browse files
GiggleLiuclaude
andcommitted
chore: add Typst drawing rule for CeTZ conventions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5481e29 commit 1d7372e

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

.claude/rules/typst-drawing.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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

Comments
 (0)