- Python 98.2%
- Shell 1.8%
| hanzi_data | ||
| input | ||
| lib | ||
| output | ||
| tests | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| DEVELOPMENT.md | ||
| hanzi_generator.py | ||
| pyproject.toml | ||
| README.md | ||
| requirements-dev.txt | ||
| requirements.txt | ||
| setup.sh | ||
Hanzi Template Generator
Generate practice templates for Chinese characters (hanzi) for Supernote A5 X2 Manta e-ink tablet.
Features
- 1920×2560 px output - Perfect for Supernote A5 X2 Manta
- Tiled layout - 4×6 grid (24 cells) for practice
- Greyed-out tracing cells - First 3 cells show the character in grey for tracing practice
- Empty practice cells - Remaining cells with dotted cross-hairs for reference
- Character information - Header shows character, pinyin, and definition
- Multiple formats - PNG, JPG, JPEG, WEBP support
- Batch processing - Process single characters or files
- Offline operation - Uses Make Me a Hanzi dataset (included)
Installation
Prerequisites
- Python 3.9 or higher
uv(recommended) orpip
Quick Setup (recommended, with uv)
Run the setup script which handles everything automatically:
./setup.sh
This will:
- Check for a compatible Python version on your system
- Prefer
uvif available (falls back to classicvenv+pip) - Create a virtual environment
- Install all dependencies
- Download data files if needed
Manual setup with uv
-
Clone or download this repository
-
Create and sync a virtual environment:
UV_PYTHON=python3 uv sync --group dev
- Activate the environment:
source .venv/bin/activate
- (Optional) Ensure Make Me a Hanzi data files are present:
ls hanzi_data/dictionary.txt hanzi_data/graphics.txt
If they are missing, the setup.sh script will download them for you, or you can download them manually as shown later.
Setup with pip (alternative)
-
Clone or download this repository
-
Create a virtual environment (recommended):
# Use python3 or python, whichever is available and is 3.9+
python3 -m venv .venv
source .venv/bin/activate
- Install dependencies:
pip install -e .
- Download the Make Me a Hanzi data files (same as above)
Usage
Single Character
Generate a template for a single character:
# Using the script directly
python hanzi_generator.py 中
# Or using the installed entry point (after pip install -e .)
hanzi-generator 中
This creates a template file under the output/progressive/ directory by default.
Batch Processing
Create a text file with one character per line (see input/characters.txt for example):
python hanzi_generator.py --file input/characters.txt
Options
# Specify output root directory (per-template subdirs are created automatically)
python hanzi_generator.py 中 --output my_output/
# Change output format
python hanzi_generator.py 中 --format JPG
# Overwrite existing files (skip duplicate check)
python hanzi_generator.py 中 --overwrite
# Specify desired number of columns (canonical layout for that count)
python hanzi_generator.py 中 --columns 7
# Specify explicit cell size (solver will fit as many cells as possible)
python hanzi_generator.py 中 --cell-size 240
# Adjust page padding (left/right/bottom minimum padding)
python hanzi_generator.py 中 --page-padding 30
# Use multi-character template (multiple characters per page, one row per character)
python hanzi_generator.py --file input/characters.txt --template multi-character
# Or pass multiple characters directly on the CLI (no spaces) for multi-character template
python hanzi_generator.py 中国人 --template multi-character
# Add a header title for the page(s)
python hanzi_generator.py 中国人 --template multi-character --title "Chapter 1: groceries"
# Specify custom data directory
python hanzi_generator.py 中 --data-dir /path/to/hanzi_data/
Output Format
Each generated page is a 1920×2560 px image with:
- Header section: Character (rendered from SVG stroke data), pinyin, and definition
- Grid layout: Practice cells arranged in a grid
- Progressive template: stroke-by-stroke grid, where the first cell shows stroke 1, the second shows strokes 1–2, etc. After all strokes are shown, remaining cells are empty with cross-hairs for reference.
- Multi-character template: one row per character, with a filled reference cell, tracing cells, and practice cells for each character.
- All cells have black borders for clear separation
Output files are organized by template type:
- Progressive template:
- Default root:
output/ - Files:
output/progressive/<character>_<pinyin>.webp(or the chosen format)
- Default root:
- Multi-character template:
- Default root:
output/ - Files:
output/multi-character/<chars>_<pinyin>_multi.webp- If the characters span multiple pages, filenames become:
..._multi_p1.webp,..._multi_p2.webp, etc.- The
_pNsuffix is only added when there is more than one page.
- If the characters span multiple pages, filenames become:
- Default root:
Input File Format
Create a text file with one character per line:
中
国
人
好
Lines starting with # are treated as comments and ignored.
Development
See DEVELOPMENT.md for development setup, code quality tools, and guidelines.
Data Source
This project uses the Make Me a Hanzi dataset, which provides:
- Stroke order data for ~9,000+ Chinese characters
- SVG path data for each stroke
- Dictionary information (pinyin, definitions, etymology)
Features
- Customizable grid size
- SVG-based character rendering (no fonts needed)
- Multiple templates
- Helper gridlines
- Progressive stroke order (first cell = stroke 1, second = strokes 1-2, etc.)
License
This project uses data from Make Me a Hanzi, which is licensed under the Arphic Public License.
Project Structure
At a high level, the repository is structured as:
hanzi_generator.py– main CLI scriptpyproject.toml– project configuration and dependenciessetup.sh– helper script for creating a virtual environment and installing depshanzi_data/– Make Me a Hanzi data files (dictionary and stroke graphics)output/– generated practice sheets (subdirectories per template type)input/– example input files with characterslib/– library code for:- loading Hanzi data
- layout solving and template generation
- SVG rendering for characters and strokes