- Shell 61.2%
- Python 21.8%
- TeX 17%
| data | ||
| docs | ||
| img | ||
| lists | ||
| tools | ||
| .gitignore | ||
| .python-version | ||
| build-pdfs.sh | ||
| character-pdf.sh | ||
| chars-pdf.sh | ||
| custom-pdfs.sh | ||
| grid.tex | ||
| hsk-1-pdf.sh | ||
| hsk-1-trace-all-pdf.sh | ||
| lib-pdf.sh | ||
| LICENSE-apache.txt | ||
| README.md | ||
| strokes-pdf-big.sh | ||
| strokes-pdf.sh | ||
| strokes-trace-all-pdf.sh | ||
| tcc-pdf.sh | ||
| TCC.md | ||
| test-chars.sh | ||
| test-strokes.sh | ||
| zi4.sh | ||
Chinese Character Practice Grid
Printable grids for practicing Chinese characters — Hànzì (汉字). These are the classic practice sheets: rice grid (mǐzìgé, 米字格) and field grid (tiánzìgé, 田字格), in whatever size and paper format you need.
PDFs
Ready-to-print PDFs are in the PDF/ folder.
They are organized by the two things you already know: your paper size
and whether you have a color printer.
PDF/<paper>/<color>/grid-<paper>-<color>-<guide>-<style>-<size>.pdf
| Part | Choices |
|---|---|
| paper | a4, letter |
| color | color (red lines) or bw (gray lines, for B&W printers) |
| guide | solid or dashed guide lines |
| style | grid style — see Grid styles |
| size | box size in millimetres |
For example, PDF/letter/color/grid-letter-color-solid-star-15mm.pdf is a
15 mm rice grid (mǐzìgé, 米字格) on Letter paper with solid red lines.
Which box size?
| Size | Good for |
|---|---|
| 10 mm | dense writing, lots of characters per page |
| 15 mm | everyday practice |
| 20 mm | beginners and stroke-order practice |
| 25 mm | extra room, young learners |
| 50 mm | brush calligraphy |
| 80 mm | large brush calligraphy |
| 10 mm | 25 mm |
|---|---|
![]() |
![]() |
Grid styles
Make your own
Edit the settings at the top of grid.tex, then build:
lualatex grid.tex
This produces grid.pdf.
Settings
All settings are in the USER SETTINGS block at the top of grid.tex.
Sizes are in centimetres.
| Setting | What it does |
|---|---|
\PaperOption |
Paper: letterpaper, a4paper, a5paper, add ,landscape to rotate, or paperwidth=10cm,paperheight=15cm |
\BoxSize |
Size of one box (e.g. 1.5) |
\ColGap / \RowGap |
Space between columns / rows (0 for none) |
\InnerStyle |
Grid style (see above) |
\GuideColor |
Line color, e.g. red!70 or black!40 (fainter) |
\GuideStyle |
dashed or solid |
\BorderColor |
Outer box color (default black) |
\HMode / \VMode |
auto to center, manual for fixed margins |
\MarginLeft etc. |
Margins for manual mode (great for binder holes) |
The number of rows and columns is worked out automatically to fit.
Overriding without editing the file
Set any value on the command line before \input{grid.tex}:
lualatex "\def\BoxSize{1.0}\def\PaperOption{a4paper}\input{grid.tex}"
Chain as many as you like, and use -jobname to name the output:
lualatex -jobname=mygrid "\def\BoxSize{2.0}\def\GuideColor{black!40}\input{grid.tex}"
Regenerate all the PDFs
./build-pdfs.sh
Stroke-order practice sheets
Print the stroke order of one character in the first boxes of the sheet: box 1 shows stroke 1, box 2 shows strokes 1–2, and so on (newest stroke in red), wrapping to the next row for many-stroked characters. Faint tracing boxes then fill the rest of the final step row, followed by empty practice boxes. Pinyin and meaning sit in a sans-serif header above the grid.
A simple character — 二 (èr, two), 2 strokes:
A medium character — 中 (zhōng, middle; China), 4 strokes:
A complex character — 鱻 (xiān, fresh), 33 strokes wrapping across four rows (tracing boxes fill the last one):
./character-pdf.sh --char 二 --pinyin "èr" --meaning "two"
This writes PDF/practice-u4e8c.pdf.
Requirements: the Python venv at venv/ (Python 3.13, standard library
only) and the stroke data in data/ — both are committed to the repo, so
there is nothing to install or download. Pinyin and meaning are printed
exactly as given (no conversion of any kind).
Every grid setting has a matching flag, plus stroke-specific options such
as --stroke-color, --new-stroke-color, --trace-color, --extract
(single natural-size stroke), --direction on (stroke-direction arrows,
off by default) and --trace-all on (tracing character in every box after
the steps). Run ./character-pdf.sh --help for the full list, and see
docs/PLAN.md for the design.
Multi-character practice sheets
chars-pdf.sh puts several characters on one page, in the classic
row-per-character school worksheet style: each character occupies whole
rows, in order, with its own pinyin/meaning label (the first character's
label sits in the header band, the rest in the row gaps above their
blocks).
./chars-pdf.sh --chars 天地玄黄
./chars-pdf.sh --list lists/tcc-simplified.tsv --range 1:8
--chars is for quick unlabeled sheets; --list (with optional
--range A:B, 1-based inclusive data rows) pulls characters and labels
from the same 4-column TSV format used by the HSK/strokes lists (a 5th
carrier:index column, as in lists/strokes.tsv, extracts single
strokes instead of whole characters). The layout is chosen with
--layout:
| Policy | Sheet |
|---|---|
steps (default) |
one stroke-order block per character: step boxes, tracing fills the final step row |
steps-empty |
steps + one practice row per character: 3 faint traces, rest empty (the school worksheet's 描三写八 — trace three, write the rest) |
trace-row |
one tracing row per character |
model-row |
one row per character: solid model + 2 faint traces, rest empty |
sequence |
characters flow one per box in reading order (copybook style) |
Labels can be turned off with --labels off (needed if you set
--row-gap below 0.4). In the sequence layout there are no per-block
labels, but --seq-labels on prints each character's pinyin above
its box — the 拼音描红本 learner-copybook form. All grid/stroke options
from character-pdf.sh work unchanged, including --direction on and
--trace-all on (which
makes every remaining row a tracing row, cycling through the characters
in order — with one character the whole page traces it, as before).
One page too few for the list? The blocks must fit the grid —
if they don't, the build aborts and tells you to use a smaller box size
or fewer characters. Run ./chars-pdf.sh --help for the full list, and
./test-chars.sh for the validation suite.
HSK-1 workbook
Build practice sheets for all 174 HSK-1 characters (HSK 2.0 list, sorted from fewest to most strokes) plus a merged 174-page workbook:
./hsk-1-pdf.sh
Output goes to PDF/letter/color/custom/HSK-1/ — one PDF per character,
named hsk-1-NNN-<pinyin>.pdf (e.g. hsk-1-158-ying3.pdf; NNN = stroke-
count order = workbook page), plus hsk-1-workbook.pdf. The character list
is lists/hsk-1.tsv (character, pinyin, meaning,
tone-number slug); future levels follow the same pattern (hsk-2-pdf.sh
with lists/hsk-2.tsv).
Stroke inventory workbook
Build practice sheets for the 25-stroke Chinese inventory (笔画) — diǎn, héng, shù, piě, nà, plus all hooked and folded compounds (shùgōu, wògōu, héngzhégōu, …):
./strokes-pdf.sh
This builds two sets — a plain set in
PDF/letter/color/custom/strokes/ and a set with stroke-direction arrows
in PDF/letter/color/custom/strokes-arrows/ — each as individual sheets
(stroke-NNN-<name>.pdf) plus a merged 25-page workbook. Each stroke is
extracted from a carrier character and shown at its natural size — small
strokes (丶, ㇀) are placed clear of the guide lines. The inventory is
lists/strokes.tsv.
The arrows show which way each stroke is written — here ㇂ (xiégōu, the slanting hook) sweeping down and flicking up at the end:
Thousand Character Classic copybook (千字文)
Build 描红本 (trace-over copybook) workbooks of the whole Thousand Character Classic — the poem flows one faint character per mizige box in poem order, with its poem-reading pinyin above each box (the 拼音描红本 learner form), page breaks on couplet boundaries, exactly the way the TCC has been practiced in China for centuries:
./tcc-pdf.sh
One run builds four workbooks in PDF/letter/color/custom/TCC/, in the
two Chinese grid sizes (大格/小格): tcc-simplified-big.pdf and
tcc-traditional-big.pdf at the 2.0 cm grid (the mainland
primary-school learner size: 8×10 boxes, 10 couplets per page, 13 pages,
every grid row exactly two four-character poem lines), plus
tcc-simplified-small.pdf and tcc-traditional-small.pdf at the 1.5 cm
grid (the upper-grade/adult size: 12×12 boxes, 18 couplets per page, 7
pages). Per-page PDFs are intermediates — staged in a temp dir, merged,
discarded — so only the workbooks are left behind. --box-size 2.0|1.5
builds just one edition, --script simplified|traditional builds just
one script, and --limit N builds only the first N couplets (smoke
test). Each workbook's final page is partial; its empty rows are the
临写 copying space Chinese practice books traditionally end with. The
lists are lists/tcc-simplified.tsv and
lists/tcc-traditional.tsv — see
TCC.md for sources, edition decisions, and pinyin notes.
License
Apache 2.0 License. See LICENSE-apache.txt for details.
Copyright © 2026 Jeff Moe moe@spacecruft.org
Loveland, Colorado, USA











