Universe

Configurable grid backgrounds for printable worksheets, in Typst, drawn with CeTZ. Square grid, ruled paper (horizontal or vertical lines only) or dot grid, with an optional darker “major” line/dot every N steps — the classic look of engineering/milimetrado paper.

Square grid with major lines every 2 steps Dot grid with major dots every 2 steps

Ruled paper, horizontal lines only Custom background and line colors

Usage

#import "@preview/meshpad:0.1.1": grid-paper

#grid-paper(size: (6, 4), kind: "square", step: 0.5, major-every: 2)

This is exactly the first image in the gallery above. Use it standalone, wrapped in a box/place behind other content, or as a whole-page background — meshpad doesn’t need to know about pages, Typst already handles that:

#set page(background: grid-paper(size: (21, 29.7), step: 0.5, major-every: 2))

Parameters

Parameter Default Meaning
size (10, 10) (width, height). Plain numbers are CeTZ units (cm by convention), but you can pass explicit Typst lengths instead — (5cm, 3cm), (4in, 3in), etc.
kind "square" "square" (lines) or "dot" (dot grid).
lines "both" "both", "horizontal" or "vertical" — only meaningful for kind: "square"; "horizontal" gives ruled/pautado paper.
step 0.5 Spacing between minor lines/dots. Same rule as size: a plain number is cm, or pass an explicit length like 5mm.
major-every none Every Nth line/dot is drawn as “major” (thicker/darker). none disables it.
background none Fill color behind the pattern. none is transparent.
color gray Color of minor lines/dots.
major-color none Color of major lines/dots. none defaults to a darker shade of color.
frame true Draw a border around the rectangle.

Sizes that aren’t a multiple of the step

size and step are independent, and neither is silently rounded: the grid draws every full cell that fits and leaves the remainder as a narrower strip against the frame. It never overflows.

#grid-paper(size: (7, 3), step: 0.6, major-every: 3)

Here 7 ÷ 0.6 = 11.67, so you get 11 columns of 0.6 (6.6 wide in total) and a 0.4 strip left over on the right; the height divides exactly (3 ÷ 0.6 = 5), so there is no strip at the top. That is the same thing real graph paper does at the edge of the page. For a flush fit, pick a size that is a whole multiple of step(7.2, 3) in this example.

What is rejected, and why

size, step and major-every are checked before anything is drawn, so a typo gives you a meshpad: message instead of an error from inside CeTZ:

You pass You get
step: 0 or a negative step meshpad: step must be positive (got 0)
size: (0, 0), or any negative side meshpad: size must be positive (got (0, 0))
major-every: 0, -2 or 2.5 meshpad: major-every must be a positive whole number or none (got 2.5)
size: (5cm, 3cm) with step: 0.5 meshpad: size and step must be all plain numbers or all Typst lengths, not a mix (…)
An unknown kind or lines meshpad: unknown kind "isometric" (expected "square" or "dot")

That last mix is the easy one to hit: plain numbers and Typst lengths cannot be combined, so pick one and use it for both. Integers and floats do mix freely, so size: (6, 4) with step: 0.5 is fine.

Compatibility

  • Typst >= 0.14.0
  • CeTZ 0.5.2

Known limitations

See ROADMAP.md for the current limits and the improvements on the list.

License

MIT.