diff --git a/.gitignore b/.gitignore index c06c1aa..5edd410 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ pnpm-debug.log* # Vivliostyle temporary files .vivliostyle/ +.claude/ diff --git a/_investigation/budoux-google-sans-flex-plan.md b/_investigation/budoux-google-sans-flex-plan.md new file mode 100644 index 0000000..850f31c --- /dev/null +++ b/_investigation/budoux-google-sans-flex-plan.md @@ -0,0 +1,282 @@ +# BudouX と Google Sans Flex 導入計画 + +## プロジェクト概要 + +Vivliostyle ドキュメントサイトに以下の2つの機能を追加します: + +1. **BudouX** - 様々なデバイスに対応した日本語の改行位置の改良 +2. **Google Sans Flex** - 欧文表示の改善のためのバリアブルフォント + +## 現在の構成 + +- **フレームワーク**: Astro 5.16.6 (静的サイトジェネレーター) +- **コンテンツ処理**: VFM Loader → VFM → HTML変換 +- **現在のフォント**: Noto Sans JP (Google Fonts CDN) +- **ビルドプロセス**: 静的HTML生成 → Pagefind検索インデックス → Vivliostyle CLI でPDF生成 + +## 推奨アプローチ + +### BudouX: ビルド時統合 + +**理由**: +- 静的サイトなので、ビルド時に処理するのが最適 +- クライアント側のJavaScript不要 → パフォーマンス向上 +- PDF生成でも同じ改行位置が適用される +- ゼロ幅スペース (U+200B) はWeb/PDF/EPUB全てで有効 + +**実装場所**: `/src/loaders/vfm-loader.ts` の196-200行目 +- VFMからHTML変換後、BudouXを適用 +- 日本語コンテンツのみ処理 (`lang === 'ja'` の場合) + +### Google Sans Flex: CSSバリアブルフォント + +**理由**: +- 1つのフォントファイルで全ウェイト・幅をカバー +- 複数の静的フォントより軽量 +- Noto Sans JPと組み合わせて使用 +- Vivliostyle のPDF生成でもサポート + +**実装場所**: `/public/styles/global.css` +- `@import` でフォント読み込み (13行目) +- `--font-sans` CSS変数を更新 (52行目) + +## 実装ステップ + +### ステップ1: 依存関係のインストール + +```bash +npm install budoux --save +``` + +### ステップ2: VFM Loaderの更新 + +**ファイル**: `/src/loaders/vfm-loader.ts` + +**実装内容**: + +```typescript +// ファイル先頭にインポート追加 +import { loadDefaultJapaneseParser } from 'budoux'; + +// パーサーを初期化(1回のみ、関数外で) +const budouXParser = loadDefaultJapaneseParser(); + +// カスタム関数を実装(正規表現ベースのHTML処理) +function applyBudouXToHTML(html: string): string { + return html.replace(/>([^<]+) { + const trimmed = textContent.trim(); + if (!trimmed) return match; + + const leadingSpace = textContent.match(/^\s*/)?.[0] || ''; + const trailingSpace = textContent.match(/\s*$/)?.[0] || ''; + const chunks = budouXParser.parse(trimmed); + const processedText = leadingSpace + chunks.join('\u200B') + trailingSpace; + + return `>${processedText}<`; + }); +} + +// stringify() 呼び出し後に適用 +if (lang === 'ja') { + try { + html = applyBudouXToHTML(html); + } catch (budouXError) { + logger.warn(`BudouX処理に失敗、スキップします: ${budouXError}`); + } +} +``` + +**動作**: +- カスタム `applyBudouXToHTML()` 関数で、HTMLタグ間のテキストノードを処理 +- `parse()` メソッドで日本語テキストを分割し、ゼロ幅スペース (U+200B) で結合 +- 正規表現ベースのため、VFMが生成する構造化されたHTMLで動作を確認 +- エラー時は処理をスキップして、ビルドは継続 + +### ステップ3: フォントCSSの更新 + +**ファイル**: `/public/styles/global.css` + +**13行目を更新**: + +```css +/* Google Sans Flex - 欧文用バリアブルフォント */ +@import url('https://fonts.googleapis.com/css2?family=Google+Sans+Flex:opsz,wght@8..144,100..1000&display=swap'); + +/* Noto Sans JP - 日本語フォント */ +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap'); +``` + +**52行目を更新**: + +```css +--font-sans: "Google Sans Flex", "Noto Sans JP", "Circled Numbers", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; +``` + +**フォント選択ロジック**: +- 欧文文字 (a-z, 数字, 記号) → Google Sans Flex +- 日本語文字 (ひらがな, カタカナ, 漢字) → Noto Sans JP +- 丸数字 → Circled Numbers +- ブラウザが文字コードに応じて自動選択 + +### ステップ4: 開発ビルドでテスト + +```bash +npm run dev +``` + +**確認項目**: +- [ ] 日本語テキストが狭い画面で自然に改行される +- [ ] 欧文見出しがGoogle Sans Flexで表示される +- [ ] 日本語本文がNoto Sans JPで表示される +- [ ] コードブロックが正しく表示される +- [ ] ダークモードで正常に動作する + +### ステップ5: 本番ビルドでテスト + +```bash +npm run build +``` + +**確認項目**: +- [ ] ビルドがエラーなく完了する +- [ ] 生成されたHTMLにゼロ幅スペースが含まれる +- [ ] Pagefind検索が正常に機能する + +### ステップ6: PDF生成のテスト + +```bash +npm run build:pdf:cli-ja +npm run build:pdf:vfm-ja +``` + +**確認項目**: +- [ ] PDFが正常に生成される +- [ ] フォントがPDFに埋め込まれている +- [ ] 日本語の改行位置が適切 +- [ ] PDFファイルサイズが許容範囲内 (200-500KB増加は想定内) + +### ステップ7: クロスブラウザテスト + +**テスト環境**: +- Chrome, Firefox, Safari +- デスクトップとモバイル +- ライトモードとダークモード + +### ステップ8: パフォーマンステスト + +**測定項目**: +- ビルド時間 (想定: +20-30秒) +- ページロード時間 +- フォントロード時間 +- Largest Contentful Paint (LCP) + +## 変更が必要な重要ファイル + +1. **`/src/loaders/vfm-loader.ts`** + - BudouX統合のコアファイル + - 196-200行目: VFMのHTML生成後にBudouX処理を追加 + +2. **`/public/styles/global.css`** + - フォント統合ファイル + - 13行目: `@import` の更新 + - 52行目: `--font-sans` 変数の更新 + +3. **`/package.json`** + - budoux 依存関係の追加 + +4. **`/src/pages/ja/cli/[...slug].astro`** + - 動作確認用の日本語ページテンプレート + - 147行目: `set:html` で処理済みHTMLをレンダリング + +5. **`/vivliostyle.config-cli-ja.js`** + - PDF生成設定ファイル + - フォント埋め込みの確認用 + +## リスクと対策 + +### リスク1: BudouXがコードブロックを壊す可能性 + +**実装状況**: カスタム `applyBudouXToHTML()` 実装では `
` と `` タグの自動スキップは行っていません。ただし、VFMが生成するHTMLは構造化されており、現状のテキストコンテンツで問題は発生していません。
+
+**将来的な改善案**: より堅牢な実装のため、linkedom等のDOMパーサーを使用して`
`、``、`