View on GitHub

AozoraEpub3-JDK21

AozoraEpub3 - Aozora Bunko to EPUB 3 Converter (JDK 21)

開発者向けガイド

AozoraEpub3の開発に参加する方、または内部実装を理解したい方向けのドキュメントです。

目次


開発環境のセットアップ

必要な環境

リポジトリのクローン

git clone https://github.com/Harusame64/AozoraEpub3-JDK21.git
cd AozoraEpub3-JDK21

IDE での開発

VS Code

  1. Java Extension Pack をインストール
  2. フォルダを開く
  3. Gradle タスクが自動認識される

IntelliJ IDEA

  1. File → Open → build.gradle を選択
  2. “Import Gradle Project” で自動設定

Eclipse

./gradlew eclipse

その後、Eclipse で Import → Existing Projects


ビルドとテスト

基本的なビルド

## クリーンビルド
./gradlew clean build

## FAT JAR 作成(すべての依存関係を含む)
./gradlew jar

## 配布パッケージ作成 (ZIP + TAR.GZ)
./gradlew dist

重要: distZip タスクは無効化されています。配布パッケージは dist タスクを使用してください。

テストの実行

## すべてのテスト実行
./gradlew test

## レポート生成
./gradlew test --rerun-tasks
## → build/reports/tests/test/index.html

生成物の場所

実行方法

## GUI起動(引数なし)
java -jar build/libs/AozoraEpub3.jar

## CLI使用(UTF-8テキストから EPUB 生成)
java -jar build/libs/AozoraEpub3.jar -of -d out input.txt

## 縦書きサンプル
java -jar build/libs/AozoraEpub3.jar -enc UTF-8 test_data/test_title.txt

## 横書きサンプル
java -jar build/libs/AozoraEpub3.jar -enc UTF-8 -y test_data/test_yoko.txt

プロジェクト構造

AozoraEpub3/
├── src/                       # メインソースコード
│   ├── AozoraEpub3.java       # CLI エントリポイント
│   ├── AozoraEpub3Applet.java # GUIエントリポイント
│   └── com/github/hmdev/      # パッケージルート
│       ├── converter/         # テキスト→EPUB変換
│       ├── epub/              # EPUB仕様関連
│       ├── io/                # ファイル・アーカイブ処理
│       ├── image/             # 画像処理
│       ├── config/            # 設定ファイル解析
│       └── pipeline/          # 変換パイプライン
│
├── test/                      # テストコード
│   ├── AozoraEpub3SmokeTest.java
│   ├── IniCssIntegrationTest.java
│   └── com/github/hmdev/      # 各パッケージのテスト
│
├── template/                  # Velocity テンプレート
│   ├── mimetype               # EPUB mimetype ファイル
│   ├── META-INF/
│   │   └── container.xml      # EPUB コンテナ定義
│   └── OPS/
│       ├── package.vm         # package.opf 生成
│       ├── toc.ncx.vm         # NCX 目次生成
│       └── css/               # CSS テンプレート
│           ├── vertical_text.vm
│           └── horizontal_text.vm
│
├── test_data/                 # テスト用データ
│   ├── test_title.txt         # タイトル・著者テスト
│   ├── test_ruby.txt          # ルビ変換テスト
│   ├── test_gaiji.txt         # 外字変換テスト
│   └── img/                   # テスト用画像
│
├── presets/                   # デバイスプリセット
│   ├── kobo__full.ini         # Kobo 最大サイズ
│   ├── kindle_pw.ini          # Kindle Paperwhite
│   └── reader.ini             # Sony Reader
│
├── chuki_*.txt                # 注記定義ファイル
│   ├── chuki_tag.txt          # 注記 → タグ変換
│   ├── chuki_alt.txt          # 外字 → 代替文字
│   ├── chuki_utf.txt          # 外字 → UTF-8
│   ├── chuki_ivs.txt          # 外字 → IVS
│   └── chuki_latin.txt        # ラテン文字変換
│
├── build.gradle               # Gradle ビルド定義
├── gradlew, gradlew.bat       # Gradle Wrapper
├── README.md                  # ユーザー向けドキュメント
└── DEVELOPMENT.md             # 本ドキュメントの原本

主要クラスの役割

エントリポイント

変換パイプライン

I/O・アーカイブ

画像処理

設定


コード構造とリファクタリング

最近の改善(v1.2.4以降)

モジュール化とクラス抽出

大規模な AozoraEpub3.java(元々645行)から責任を分離し、保守性を向上しました:

抽出されたクラス:

  1. OutputNamer (com.github.hmdev.io): ファイル名生成ロジック(50行)
    • creator/title ベースの自動命名
    • ファイル名のサニタイズ(無効文字除去)
    • 拡張子のデフォルト設定
  2. WriterConfigurator (com.github.hmdev.pipeline): Writer設定の集約(110行)
    • 画像パラメータ設定
    • 目次ネスト設定
    • スタイル設定(余白・行高・フォント)
  3. ArchiveTextExtractor (com.github.hmdev.io): アーカイブ処理の統一(90行)
    • zip/rar/txtからのテキスト抽出
    • テキストファイル数のカウント
    • キャッシュ機構との連携

リファクタリング効果:

詳細は notes/refactor-plan.md を参照。

パフォーマンス最適化 🚀

問題: 1ファイルあたり4回のアーカイブスキャンが発生していました:

  1. テキストファイル数のカウント
  2. 書誌情報の取得
  3. 画像リストの読み込み
  4. 実際の変換処理

解決策: アーカイブキャッシュ機構の導入

最適化効果:

メモリ管理:

詳細は notes/archive-cache-optimization.md を参照。


テンプレート (Velocity)

設計方針

Epub3Writer は Velocity のグローバル初期化に依存しないよう VelocityEngine の注入 に対応しています。

コンストラクタ

// 推奨:VelocityEngine を注入(テスト容易・カスタマイズ可能)
new Epub3Writer(templatePath, velocityEngine)

// または旧方式(後方互換)
new Epub3Writer(templatePath)  // グローバル初期化を利用

テストでの使用例

Properties p = new Properties();
p.setProperty("resource.loaders", "file");
p.setProperty("resource.loader.file.class", 
    "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
p.setProperty("resource.loader.file.path", 
    projectRoot.resolve("template").resolve("OPS").toString());
VelocityEngine ve = new VelocityEngine(p);

VelocityContext ctx = new VelocityContext();
ctx.put("title", "サンプルタイトル");
ctx.put("bookInfo", bookInfoObject);
ctx.put("sections", sectionList);
// ... その他のコンテキスト設定

Template t = ve.getTemplate("package.vm", "UTF-8");
StringWriter out = new StringWriter();
t.merge(ctx, out);
String opf = out.toString();

テンプレートファイル一覧

テンプレート 用途 出力ファイル
package.vm EPUB メタデータ・マニフェスト package.opf
toc.ncx.vm 目次(NCX形式) toc.ncx
css/vertical_text.vm 縦書きテキスト CSS vertical_text.css
css/horizontal_text.vm 横書きテキスト CSS horizontal_text.css
xhtml/*.vm 本文 XHTML *.xhtml

INI値の CSS 反映

INI設定ファイルの値(font_size, line_height など)は Velocity コンテキストに配置され、テンプレートで CSS変数として利用されます。

例(vertical_text.vm):

:root {
  --font-size: ${fontSize}%;
  --line-height: ${lineHeight};
}

関連テスト:


EPUB 3.3 準拠への対応

検証項目(CI で自動化)

mimetype ファイル

package.opf (OPF ファイル)

container.xml

Kindle (iPhone) 対応

package.vm L60 に以下を記載(ImageOnlyかつKindle時):

<meta name="primary-writing-mode" content="horizontal-rl"/>

保持テスト: PackageTemplateKindleMetaTest.java

epubcheck による検証

## Gradle タスク(カスタム)
./gradlew epubcheck \
  -PepubDir=build/epub_local \
  -PepubcheckJar=build/tools/epubcheck-5.3.0/epubcheck.jar

epubcheck の取得方法:

mkdir -p build/tools
cd build/tools
curl -L -o epubcheck-5.3.0.zip \
  https://github.com/w3c/epubcheck/releases/download/v5.3.0/epubcheck-5.3.0.zip
unzip epubcheck-5.3.0.zip

対応している注記

基本的な注記(設定ファイルで対応)

プログラムで処理する注記

- ページの左右中央
- ルビ付き注記の自動変換 [#「○」に「△」のルビ] → |○《△》
- 傍点の自動変換 [#「○」に×傍点] → ×ルビ化
- 字下げ複合処理(fold/indent計算)
- 割り注の改行追加
- 底本: による改ページ

未対応の注記

- 訂正と「ママ」(無視される)
- 左ルビ
- 行内の地付き
- 2段組

外字処理

青空文庫注記から外字を抽出・変換します:

※[#「字名」、U+6DB6]                          → Unicode直接指定
※[#「字名」、第3水準1-85-57]                  → JISコード → UTF-8
※[#「さんずい+垂」、UCS6DB6]                → UCS形式

対応コードが無い外字は chuki_alt.txt で代替文字に置換されます。


GitHub Actions CI

ワークフロー一覧

ci.yml(ビルド・テスト・EPUB生成・検証)

以下の処理を自動実行:

手動実行方法:
GitHub → Actions → CI → Run workflow

オプション入力:

test.yml(ユニットテストのみ)


貢献ガイドライン

バグ報告・機能提案

GitHub Issues で以下の情報を提供してください:

バグの場合

機能提案の場合

プルリクエスト

  1. リポジトリを fork して feature ブランチを作成
  2. 変更を加え、テストを追加
  3. ./gradlew test で全テストをパス確認
  4. PR を作成(説明・関連Issue記載)

コーディング規約


よくある問題

Velocity リソース解決に失敗

症状: テスト実行時に template/*.vm が見つからない

原因: Gradle Worker が異なる作業ディレクトリで実行される

解決策:

Windows パス問題

症状: \ がエスケープで失敗する

解決策:

テスト不安定性

症状: ローカルでは成功するが CI で失敗する

原因:

解決策:


パフォーマンス最適化のヒント

大容量テキスト変換時

画像処理

EPUB 生成速度


リンク


ライセンス

GPL v3 - 詳細は README を参照