The Problem Developers who spend many hours in terminals and IDEs need a monospace font that combines clean round‑corner glyphs, extensive ligatures, and built‑in Nerd‑Font icons while still preserving a perfect 2:1 Chinese‑to‑English width ratio. Existing fonts either lack the required ligature set, miss the icon coverage, or force a separate Chinese‑specific build.
What This Does maple-font ships the source for Maple Mono, a variable‑weight TTF that includes:
- round‑corner glyphs and custom italics (
source/MapleMono[wght].vfc,source/MapleMono[wght]-VF.ttf) - a full set of OpenType feature files under
source/features/(regular.fea,italic.fea,cn.fea, etc.) that drive ligatures, contextual alternates, and stylistic sets - Nerd‑Font icon patches generated by the
source/py/task/nerdfont.pyhelper
The Python tooling in source/py/ builds the font from the feature files, merges optional subsets, and publishes the final archives. The Dockerfile (Dockerfile) provides an isolated build environment, and pyproject.toml/requirements.txt list the required Python packages (e.g., fontTools, requests).
How It Is Wired
- Entry points – The CLI starts in
build.pyatmain(line 1677).mainparses command‑line arguments, loads the configuration (source/config.yaml), and invokes the build pipeline. A secondary entry pointrunlives insource/py/utils.py(line 13) and is used by several task scripts.
- Core flow –
main→check_ftcli→parse_args→parse_scale_factor→__load_config. The configuration feedssource/py/feature/__init__.pywhich generates the OpenType feature string (generate_fea_string). This string is handed tofontToolsviasource/py/task/merge_font/merger.pyto produce the final TTF.
- High‑blast‑radius modules –
source/py/feature/ast.pyis imported by 46 other modules, making it the primary hub. Changes here ripple widely.source/py/feature/__init__.pysits in a circular import withsource/py/feature/calt/__init__.py; breaking this cycle will reduce coupling.
- Key functions –
subst_map(called from 43 places) andjoinPaths(26 places) perform the bulk of glyph substitution logic.gly,cls, andignare also heavily reused.
- External effects – The build writes font files (
archive_fontsinbuild.py) and computes a SHA‑256 hash (hashlib.sha256).source/py/utils.pyruns a subprocess (subprocess.run) for Git commands and other shell tools. No network I/O beyond optional HTTP fetches for Nerd‑Font patches.
- Task modules –
source/py/task/merge_font/__init__.pyvalidates the merge configuration,source/py/task/nerdfont.pypatches icons, andsource/py/task/publish.pyuploads assets via a GitHub release workflow (.github/workflows/release.yml).
How To Use It
# Clone the repo
git clone https://github.com/moses-y/maple-font
cd maple-font
# Build the container (Dockerfile pins python:3.11-slim)
docker build -t maple-font-builder .
# Run the build inside the container
docker run --rm -v "$(pwd)":/src maple-font-builder \
python build.py --config source/config.yaml --output dist/
The repo supplies a Dockerfile that installs the Python dependencies from requirements.txt and runs build.py. No additional environment variables are required.
If you prefer a local build, install the Python deps (pip install -r requirements.txt) and invoke the same command without Docker.
Real‑World Use A CI pipeline for a custom IDE theme can invoke the container step above to regenerate MapleMono[wght].ttf whenever a new ligature set is added. The resulting font can be dropped into VS Code or iTerm2, and the Nerd‑Font icons will appear automatically in the terminal prompt.
Code Health & Issues
- High – No LICENSE – repository root lacks a licence file. Add MIT or Apache‑2.0.
- High – No test suite – 91 source files, zero test files. Introduce unit tests for public functions (
main,run, feature generation). - High – No lockfile –
pyproject.tomlis present without a lockfile; commitpoetry.lockorrequirements.txtgenerated by pip‑freeze. - High – Continue‑on‑error in CI –
.github/workflows/custom.ymlline 108 allows failures to pass; remove or isolate advisory steps. - Medium – Dependabot missing – No automated dependency updates; add
.github/dependabot.yml. - Medium – Docker base image not pinned –
python:3.11-slimis mutable; replace with a digest. - Medium – No vulnerability scan – CI lacks a dependency‑review or OSV scan; add one.
- Medium – Unbounded HTTP request –
source/py/utils.pymakes arequestscall without timeout; supplytimeout=. - Medium – Checkout persists token –
.github/workflows/custom.ymlshould setpersist-credentials: false. - Medium – Container runs as root – Dockerfile lacks a non‑root
USER; create an unprivileged user.
The Bottom Line maple-font provides a well‑documented, feature‑rich monospace font with a reproducible Python‑based build pipeline, but the code base suffers from missing licensing, tests, and a few architectural smells (import cycle, large hub module). Adding a licence, lockfile, and test suite will make it safe for integration into production tooling or downstream font customisation projects.