青空文庫の .txt を HTML に変換する最短手順

Share

青空文庫 で配布されている .txt ファイルを HTML に変換したい、という用途向けの手順。Rust の知識は要らない。コマンド 1 行で済む。

1. CLI バイナリを取ってくる

aozora の Releases ページ から自分の OS 向けのアーカイブを落とす。

OS アーカイブ名
Linux x86_64 aozora-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz
macOS arm64 aozora-vX.Y.Z-aarch64-apple-darwin.tar.gz
Windows x86_64 aozora-vX.Y.Z-x86_64-pc-windows-msvc.zip

SHA256SUMS も同梱されているので、必要なら shasum -a 256 -c SHA256SUMS で検証できる。

展開すると aozora (Windows なら aozora.exe) というバイナリが出てくる。これを PATH の通った場所に置くか、その場で実行する。

2. 変換する

青空文庫の .txt は Shift_JIS なので、-E sjis を付ける (これを付けないと UTF-8 として読まれて文字化けする)。

aozora render -E sjis kokoro.txt > kokoro.html

これで kokoro.html ができる。標準出力に流すので、ファイル名は自由に決められる。

ファイルの代わりに標準入力から流すこともできる。

cat kokoro.txt | aozora render -E sjis - > kokoro.html

事前に書式が正しいか確かめたい場合は check サブコマンドを使う (HTML は出力されず、警告だけが表示される)。

aozora check -E sjis kokoro.txt

3. 出てくる HTML

入力:

|青梅《おうめ》の山に、[#「ふと」に傍点]気が向いた。

出力 (抜粋):

<p>
  <ruby>青梅<rt>おうめ</rt></ruby>の山に、<em class="bouten">ふと</em>気が向いた。
</p>

ルビは HTML5 の <ruby> <rt> 要素に、傍点は class="bouten" 付きの <em> に変換される。CSS でブラウザ表示を整える場合は .bouten { text-emphasis: filled; } のような指定で点を出せる。

縦中横や字下げコンテナ、外字も同様にセマンティックなマークアップに対応している。詳細は handbook の Notation 章 に各記法の入出力例が並んでいる。

4. データの取得元と注意

青空文庫の .txt ファイルは 作品リスト からダウンロードできる。各作品ページに「テキストファイル(ルビあり)」のリンクがあって、その zip を解凍すると .txt が出てくる。

  • 公開されているのは 著作権切れ (パブリックドメイン) の作品のみ。再配布も自由
  • 一部「公開中の作家による寄贈作品」は別ライセンスがあるので作品ページの注記を確認すること
  • 青空文庫のテキストには「底本情報」のヘッダ・フッタが付いている。aozora はそれを通常の本文として処理するので、必要なら手で削るか、独自の前処理を挟む

関連プロジェクト

  • P4suta/aozora-tools — 編集者向け: フォーマッタ、LSP サーバ、tree-sitter 文法、VS Code 拡張
  • P4suta/afm — Markdown と青空文庫記法を混在させて書きたい場合のパーサ

aozora の handbook 全体: https://p4suta.github.io/aozora/

Read more

外字と訓点を compile-time hash で解く

aozora は青空文庫の外字参照 (※[#「魚+師」、第3水準1-94-37] のような形) を約 14,000 件のテーブルで解決する。このテーブルを runtime の HashMap ではなく phf (perfect hash function) で持ち、コンパイル時に static 配列に焼き込んでいる。この記事はその選択の根拠と、JIS X 0213 → Unicode フォールバックの設計をまとめたもの。 handbook の対応章: Shift_JIS + 外字 resolver。 外字テーブルの形 外字エントリには 3 種類の解決結果があり、それぞれに対応する variant を GaijiEntry に持たせている。 static GAIJI_TABLE: phf::Map<

By Sakashita Yasunobu

50,000 ノードの AST を 16 回のアロケーションで: bumpalo 借用アリーナの実例

aozora の AST は bumpalo 単一アリーナの上に構築されている。Box<Node> を素直に並べた版に比べてパースが 6.4 倍速、ピーク RSS が 30% 減という結果が出ている。この記事は、その設計判断と Rust ライフタイムの取り回しを実装の視点から整理したもの。 handbook の対応章: Borrowed-arena AST。 問題設定 青空文庫の典型的な作品は約 500KiB のソースで、aozora がパースすると約 50,000 ノードの木に展開される。素直に Rust らしく書けば次のような形になる。 enum Node { Plain(String), Ruby { target: String, gloss: String }, Container { kind:

By Sakashita Yasunobu

7 個のトリガーバイトを 12 GB/s で探す: Teddy を選んだ理由

aozora は青空文庫記法の Rust パーサで、字句解析の最初のフェーズが「ソース全体から 7 種類のトリガーバイトを探す」というマルチパターンスキャンになっている。この記事は、その 1 フェーズに Intel Hyperscan 由来の Teddy アルゴリズムを採用した経緯と、対立候補に勝った算術的な根拠を整理したもの。 handbook の対応章: SIMD scanner backends。 問題設定 aozora-pipeline の Phase 1 (字句解析の最初のフェーズ) は、ソース文字列の中から次の 7 文字の出現位置を全て列挙する。 | 《 》 ※ [ ] 全角空白 これらは青空文庫記法の構文トリガー (ルビ・注釈・字下げの開始/終了マーカ) で、出現する位置だけが分かれば後段のフェーズで「これは何の構文か」を解釈できる。 UTF-8 で見ると 7 文字 × 3 バイト

By Sakashita Yasunobu