📖 Documentation site · 🧪 API reference (rustdoc) · 📦 Releases & binaries · 📝 Changelog
Aozora Flavored Markdown (afm) is a Markdown dialect, modelled after
GitHub Flavored Markdown (GFM), that
layers Aozora Bunko (青空文庫) typography — ruby, bouten, 縦中横,
[#…] annotations, gaiji, accent decomposition — on top of
CommonMark + GFM for Japanese vertical and horizontal writing.
Like GFM, afm is a strict superset of CommonMark + GFM: any pure
CommonMark / GFM document parses identically under afm, and the Aozora
extensions kick in only where the input actually uses them. The file
extension remains .md. A single Rust crate set and a single afm
binary drop into the same slot you would otherwise use a CommonMark
parser in.
This repository hosts both the specification of afm (rendered as
the mdbook site under
crates/afm-book/) and its reference
implementation — the same split GFM uses.
Each dialect in the Markdown family extends the one before it. afm is the Japanese-typography layer:
CommonMark ──▶ GFM ──▶ Aozora Flavored Markdown
(structural (tables, (ruby, bouten, 縦中横, 字下げ, 外字,
Markdown) task lists, 返り点, 割注, アクセント分解, …)
~strikethrough~)
The Aozora Bunko community has maintained a rich annotation notation for typesetting Japanese prose for over twenty years. afm picks it up wholesale, maps it onto a modern Markdown AST, and lets you embed the result in any pipeline that speaks CommonMark.
- 100% CommonMark / GFM compatibility — the full spec test suites pass verbatim (652 CommonMark 0.31.2 cases + the GFM 0.29 cases).
- 100% Aozora Bunko compatibility target — every notation listed at
https://www.aozora.gr.jp/annotation/ parses; afm preserves the
Tier-A invariant (no unconsumed
[#markers in the rendered HTML). - Single binary, no runtime process dependencies.
- Pure-functional parse pipeline — zero parse-time hooks in
vendored comrak; Aozora recognition lives in
aozora(sibling repo) and is spliced into the comrak AST byafm-markdown::post_process.
# 第一章 (Markdown heading)
[#「第一篇」は大見出し] (Aozora heading, aliased to the same AST)
彼は|青梅《おうめ》に行った。 (Ruby)
それは《《強調したい》》ことだった。 (Bouten / emphasis dots)
令和[#縦中横]2[#縦中横終わり]年。 (Tate-chu-yoko)
[#ここから字下げ] (Block indent)
段落……
[#ここで字下げ終わり]afm/
upstream/comrak/ # vendored comrak 0.52.0, verbatim (0-line diff)
crates/
afm-markdown/ # CommonMark + GFM + 青空文庫記法 HTML integration layer
afm-cli/ # `afm` binary (render / check)
afm-book/ # mdbook documentation site (excluded from cargo workspace)
xtask/ # upstream-sync, spec-refresh, new-adr
spec/ # CommonMark / GFM / Aozora fixtures
docs/adr/ # Architecture Decision Records
The Aozora-specific lexer / AST / renderer (aozora-syntax,
aozora-pipeline, aozora-render, aozora-encoding, aozora-spec,
aozora-proptest) live in the sibling
P4suta/aozora repository and are
consumed here as a git dependency (ADR-0010).
| Repo | What it is |
|---|---|
P4suta/aozora |
Pure 青空文庫記法 parser — lexer, AST, renderer, gaiji table. |
P4suta/aozora-tools |
Authoring tools: aozora-fmt formatter, aozora-lsp Language Server, tree-sitter grammar, VS Code extension. |
All operations run inside Docker. The host toolchain is never invoked directly (ADR-0002).
just test # cargo nextest via Docker
just lint # fmt + clippy + typos + strict-code
just coverage # llvm-cov regions, CI floor at 96%
just spec-commonmark # full CommonMark 0.31.2 spec
just spec-gfm # GFM 0.29 spec
just upstream-diff # verify the upstream comrak tree stays 0-line (verbatim v0.52.0)
just ci # replicate the full CI matrix locally
just book-serve # mdbook live preview at http://localhost:3000Aozora-only test surfaces (spec-aozora, spec-golden-56656,
corpus-sweep) live in the sibling
P4suta/aozora repo. Run them
from there.
See CLAUDE.md for the project guide, docs/adr/ for architectural decisions, and CONTRIBUTING.md for how to hack on afm.
Short end-to-end snippets live under
crates/afm-markdown/examples/:
render-utf8.rs— parse a UTF-8 file and emit HTML on stdout.render-sjis.rs— parse a Shift_JIS Aozora Bunko text viaaozora-encoding.ast-walk.rs— walk the parsed AST and tally AozoraNode variants.serialize-round-trip.rs— verifyserialize ∘ parse ≡ idon one file.
Run any of them with:
cargo run --example <name> -p afm-markdown -- <path/to/input.md>Pre-built binaries for Linux x86_64, macOS arm64, and Windows
x86_64 are attached to every GitHub Release — see
the releases page and pick a
afm-vX.Y.Z-<target>.{tar.gz,zip}. SHA256 sums are published as
SHA256SUMS next to the archives.
Or build from source:
cargo install --git https://github.com/P4suta/afm --locked afm-cliVulnerabilities go through GitHub Security Advisories — see
SECURITY.md for the disclosure flow.
Dual-licensed under Apache-2.0 OR MIT at your option, matching Rust community convention.
The vendored upstream/comrak/ tree remains under its upstream license
(BSD-2-Clause). See upstream/comrak/COPYING.
Sample 青空文庫 texts used by the parser-side spec / golden / corpus
fixtures live in the sibling
P4suta/aozora repo (public
domain, attributed per work). afm itself ships only the CommonMark
0.31.2 and GFM 0.29 spec fixtures under spec/.
See NOTICE for the full third-party attribution index (vendored comrak, CommonMark / GFM spec fixtures, Aozora Bunko material).