Module: Vivlio::Starter::CLI::PostProcessCommands::BodyClassInjector

Defined in:
lib/vivlio/starter/cli/post_process/body_class_injector.rb

Overview

Module: BodyClassInjector


【役割】

  • HTMLファイルの <body> タグにファイルタイプクラスを付与

【処理内容】

  • ファイル名から chapter/preface/appendix などを判定

  • <body> を <body class=“file_type”> に置換

  • 最初の本文章には chapter-first クラスを追加(pageカウンタリセット用)

Class Method Summary collapse

Class Method Details

.detect_first_main_chapterString?

catalog.yml から最初の本文章を検出

Returns:

  • (String, nil)

    最初の本文章の basename、または nil



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/vivlio/starter/cli/post_process/body_class_injector.rb', line 60

def detect_first_main_chapter
  @detect_first_main_chapter ||= begin
    require_relative '../build/catalog_loader'
    catalog = Build::CatalogLoader.load_catalog
    chapters = catalog['CHAPTERS']
    return nil if chapters.nil? || chapters.empty?

    # CHAPTERSセクションの最初のエントリを取得
    first_item = chapters.first
    case first_item
    when String
      first_item.sub(/\.md\z/, '')
    when Hash
      # 部タイトルの場合は配下の最初の章を取得
      sub_items = first_item.values.first
      sub_items.is_a?(Array) && sub_items.first ? sub_items.first.to_s.sub(/\.md\z/, '') : nil
    end
  rescue StandardError
    nil
  end
end

.first_main_chapter?(html_file) ⇒ Boolean

最初の本文章かどうかを判定

Parameters:

  • html_file (String)

    HTMLファイルのパス

Returns:

  • (Boolean)


50
51
52
53
54
55
56
# File 'lib/vivlio/starter/cli/post_process/body_class_injector.rb', line 50

def first_main_chapter?(html_file)
  basename = File.basename(html_file, '.html')
  first_chapter = detect_first_main_chapter
  return false unless first_chapter

  basename == first_chapter
end

.inject_body_class(html_file, entry) ⇒ Boolean

HTMLファイルの <body> タグにファイルタイプクラスを付与

Parameters:

  • html_file (String)

    HTMLファイルのパス

  • entry (TokenResolver::Entry)

    章情報を持つ Entry オブジェクト

Returns:

  • (Boolean)

    変更があったかどうか



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/vivlio/starter/cli/post_process/body_class_injector.rb', line 27

def inject_body_class(html_file, entry)
  content = File.read(html_file, encoding: 'utf-8')
  file_type = entry.kind.to_s
  classes = [file_type]

  # 最初の本文章には chapter-first クラスを追加
  classes << 'chapter-first' if entry.kind == :chapter && first_main_chapter?(html_file)

  class_attr = classes.join(' ')

  # 単純置換で <body> にクラスを付与
  # - 既存 class 属性が無いテンプレ構成を前提に、文字列置換で高速に処理
  updated = content.gsub('<body>', "<body class=\"#{class_attr}\">")

  return if updated == content

  File.write(html_file, updated, encoding: 'utf-8')
  Common.log_info("#{html_file}: <body>→class追加(#{class_attr})")
end