Washi(和紙)
縦組み・ルビ・右綴じに強い、依存ゼロの macOS 用 EPUB 3 ツールキット
macOS EPUB 3 toolkit with first-class Japanese typography
Washi(和紙)は、macOS のシステムフレームワークだけで実装した EPUB 3 ツールキットです。第三者パッケージには依存せず、ZIP の読み取りから自前で実装しています。縦組み・ルビ・縦中横・圏点・右綴じといった日本語組版を第一級の機能として扱います。
構成は 2 層です。解析層の WashiCore は Foundation / CoreFoundation / Compression / CryptoKit / CoreGraphics / ImageIO だけを使うので、GUI セッションのない CLI・索引・サーバなどのヘッドレス用途でも動きます。表示層の Washi はそこに AppKit / WebKit を加え、リーダービュー(EPUBReaderView)、全文ページ数の census、サムネイルを提供します。import Washi だけで両層の公開 API が見えます。
Mac 用コミックビューア cooViewer から独立した MIT ライセンスの SwiftPM パッケージで、単体で再利用できます。解析だけのヘッドレス用途から AppKit / SwiftUI アプリでの表示まで、macOS アプリの開発者が自分のアプリに組み込んで使うことを想定しています。
特徴
- 依存ゼロ: ZIP 読み取り(zip64 対応・CRC 検証)から自前実装。解析層はヘッドレスで利用可能
- 日本語組版: 縦組み(
vertical-rl)・ルビ・縦中横・圏点・右綴じを第一級でサポート。電書連(DPFJ)の制作ガイドが使う抽象フォント名をヒラギノへ結び付ける@font-faceポリフィルも同梱 - 攻撃的 EPUB への耐性: zip 爆弾、XML 実体爆弾(billion laughs)、異常な深さの XML、パス走査・シンボリックリンク脱出を入口で遮断(テスト付き)
- EPUB 3.3 の RS 要件に準拠する設計(EPUB 2.0.1 後方互換込み): OCF コンテナ、パッケージ文書、EPUB 3 nav + NCX フォールバック、page-list など
- WebKit を使わない本文抽出・全文検索: 大小文字・ダイアクリティカルマーク・全半角の区別を
EPUBSearchOptionsで個別指定 - 見開き表示: ウインドウ幅で単ページと見開きを自動切替。縦書きの見開きは右綴じの正順で、中央にノド、下部中央にノンブルを表示。ライト / ダークテーマに対応
- 固定レイアウト: 「画像 1 枚だけのページ」を検出し、WebKit を介さず画像を直接取り出せます(日本の漫画 EPUB の大多数がこの形)。複雑なページは
EPUBPageRasterizerでオフスクリーンラスタライズ - メディアオーバーレイ(SMIL)の再生、IDPF / Adobe のフォント難読化の透過解除。DRM(ADEPT / LCP / FairPlay)は検出して報告するのみで、復号はしません
- ピンチでフォント倍率(0.5〜3.0 倍)、
EPUBLocatorによる読書位置の保存・復元、内部リンク・脚注の delegate 制御、選択範囲 API、VoiceOver への確定ページ通知
対応環境と入手方法
macOS 14 以降・Swift 6(strict concurrency)。Apple Silicon・Intel の両方に対応しています。GitHub Release に配布物はなく、SwiftPM で導入するか、リポジトリをクローンして使います。
Xcode から追加する: File → Add Package Dependencies… に https://github.com/shunnag/Washi.git を入力し、Up to Next Major Version で最新のリリースを指定して追加します。アプリのターゲットには、表示するなら Washi、解析・表紙・検索だけなら WashiCore を選びます。通常の SwiftPM 利用で WashiDynamic を選ぶ必要はありません。
Package.swift に追加する:
// Package.swift
.package(url: "https://github.com/shunnag/Washi.git", from: "1.23.0")
まず動作を見る: AppKit 版と SwiftUI 版の独立したサンプルを同梱しています。どちらも小さな EPUB を含み、ファイル選択、ページ送り、検索とハイライト、読書位置の保存・復元を試せます。
git clone https://github.com/shunnag/Washi.git
cd Washi
Scripts/run-sample.sh AppKitReader
Scripts/run-sample.sh SwiftUIReader
API リファレンスと導入ガイドは公開 DocC ドキュメントにまとめてあります。
スクリーンショット