Module: Vivlio::Starter::CLI::Build::PartTitleGenerator

Defined in:
lib/vivlio/starter/cli/build/part_title_generator.rb

Overview

中扉(Part Title Page)の生成モジュール

catalog.yml の部タイトルから _partN.md を .cache/vs/ に生成し、VFM 変換で _partN.html をプロジェクトルートに出力する。中扉は右ページ(奇数ページ)に部タイトルを印刷し、裏面は白紙となる。

Class Method Summary collapse

Class Method Details

.convert_to_html!(basename) ⇒ Object

中扉 Markdown を VFM 変換して HTML を生成するSectionBuilder の既存パイプライン(pre_process → convert → post_process)を再利用

Parameters:

  • basename (String)

    中扉の basename(例: “_part1”)



85
86
87
88
89
# File 'lib/vivlio/starter/cli/build/part_title_generator.rb', line 85

def convert_to_html!(basename)
  PreProcessCommands.execute_pre_process({}, [basename])
  ConvertCommands.execute_convert({}, [basename])
  PostProcessCommands.execute_post_process({}, [basename])
end

.existing_part_htmls(base_dir = '.') ⇒ Array<String>

生成済みの中扉 HTML ファイルパスを返すentries.js 構築時に、各部の先頭章の直前に挿入するために使用する

Parameters:

  • base_dir (String) (defaults to: '.')

    ベースディレクトリ

Returns:

  • (Array<String>)

    中扉 HTML のパス配列(存在するもののみ)



95
96
97
# File 'lib/vivlio/starter/cli/build/part_title_generator.rb', line 95

def existing_part_htmls(base_dir = '.')
  Dir.glob(File.join(base_dir, '_part*.html'))
end

.generate_all!Array<String>

中扉ページを一括生成するcatalog.yml に部タイトルがなければ何もしない

Returns:

  • (Array<String>)

    生成された中扉の basename 配列(例: [“_part1”, “_part2”])



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/vivlio/starter/cli/build/part_title_generator.rb', line 37

def generate_all!
  parts = CatalogLoader.load_part_titles
  if parts.empty?
    Common.log_info('[PartTitle] 部タイトルが定義されていません。中扉生成をスキップします。')
    return []
  end

  Common.ensure_cache_dir!
  generated = []

  parts.each do |part|
    basename = "_part#{part[:number]}"
    md_path = File.join(Common::CACHE_DIR, "#{basename}.md")

    # --- Phase: Markdown 生成 ---
    write_part_markdown!(md_path, part[:title])

    # --- Phase: HTML 変換 ---
    convert_to_html!(basename)

    generated << basename
  end

  Common.log_success("[PartTitle] 中扉を #{generated.size} 件生成しました: #{generated.join(', ')}")
  generated
end

.insert_part_titles_into(chapter_htmls, base_dir = '.') ⇒ Array<String>

部タイトル情報と章 HTML リストから、中扉を適切な位置に挿入した HTML リストを返す各部の先頭章の直前に _partN.html を挿入する

Parameters:

  • chapter_htmls (Array<String>)

    章 HTML のパス配列(ソート済み)

  • base_dir (String) (defaults to: '.')

    ベースディレクトリ

Returns:

  • (Array<String>)

    中扉が挿入された HTML パス配列



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/vivlio/starter/cli/build/part_title_generator.rb', line 104

def insert_part_titles_into(chapter_htmls, base_dir = '.')
  parts = CatalogLoader.load_part_titles
  return chapter_htmls if parts.empty?

  # 各部の先頭章番号 → 中扉 HTML のマッピングを構築
  insertion_map = {}
  parts.each do |part|
    next unless part[:first_chapter]

    part_html = File.join(base_dir, "_part#{part[:number]}.html")
    next unless File.exist?(part_html)

    # 先頭章番号をゼロ埋め2桁にして、対応する HTML ファイル名のプレフィックスを生成
    prefix = format('%02d-', part[:first_chapter])
    insertion_map[prefix] = part_html
  end

  return chapter_htmls if insertion_map.empty?

  # 章 HTML リストを走査し、各部の先頭章の直前に中扉を挿入
  result = []
  inserted = Set.new

  chapter_htmls.each do |html_path|
    bn = File.basename(html_path)
    insertion_map.each do |prefix, part_html|
      if bn.start_with?(prefix) && !inserted.include?(part_html)
        result << part_html
        inserted << part_html
      end
    end
    result << html_path
  end

  result
end

.write_part_markdown!(path, title) ⇒ Object

中扉の Markdown を .cache/vs/ に書き出すfrontmatter の class: part-title で CSS を適用し、title で PDF アウトラインに反映する

Parameters:

  • path (String)

    書き込み先パス

  • title (String)

    部タイトル(例: “歴史篇”)



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/vivlio/starter/cli/build/part_title_generator.rb', line 68

def write_part_markdown!(path, title)
  content = <<~MD
    ---
    class: part-title
    title: #{title}
    ---

    # #{title}
  MD

  FileUtils.mkdir_p(File.dirname(path))
  File.write(path, content, encoding: 'utf-8')
end