Module: Vivlio::Starter::CLI::Build::BacklinkDedupOrchestrator

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

Overview

バックリンク重複排除の全ワークフローを管理

Class Method Summary collapse

Class Method Details

.dedup_enabled?Boolean

重複排除機能が有効か索引・用語集機能が有効で、かつ用語集または索引の重複排除が有効な場合に true

Returns:

  • (Boolean)


77
78
79
80
81
82
83
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 77

def dedup_enabled?
  # 索引・用語集自体が無効なら dedup も無効
  return false unless IndexCommands.index_enabled?

  # 用語集または索引のいずれかの dedup が有効なら実行
  glossary_dedup_enabled? || index_dedup_enabled?
end

.dedup_target_exists?Boolean

重複排除対象の HTML が存在するか

Returns:

  • (Boolean)


98
99
100
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 98

def dedup_target_exists?
  File.exist?('_glossarypage.html') || File.exist?('_indexpage.html')
end

HTML のバックリンク重複を排除

Parameters:

Returns:



117
118
119
120
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 117

def deduplicate_backlinks(page_mapping)
  deduplicator = BacklinkDeduplicator.new(page_mapping)
  deduplicator.deduplicate!
end

.extract_page_mappingPageMappingExtractor::PageMapping?

ページマッピングを抽出



106
107
108
109
110
111
112
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 106

def extract_page_mapping
  extractor = PageMappingExtractor.new
  extractor.extract!
rescue StandardError => e
  Common.log_error("[Step 8] ページマッピング抽出に失敗: #{e.message}")
  nil
end

.glossary_dedup_enabled?Boolean

用語集の重複排除が有効か

Returns:

  • (Boolean)


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

def glossary_dedup_enabled?
  dedup_setting = Common::CONFIG.dig('glossary', 'backlink_dedup')
  dedup_setting != false
end

.index_dedup_enabled?Boolean

索引の重複排除が有効か

Returns:

  • (Boolean)


92
93
94
95
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 92

def index_dedup_enabled?
  dedup_setting = Common::CONFIG.dig('index', 'backlink_dedup')
  dedup_setting != false
end

.log_result(result) ⇒ Object

結果をログ出力



140
141
142
143
144
145
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 140

def log_result(result)
  Common.log_info("[Step 8] 用語集バックリンク: #{result.glossary_removed} 件の重複を削除")
  Common.log_info("[Step 8] 本文 †マーク: #{result.body_removed} 件の重複を削除")
  Common.log_info("[Step 8] 索引ページ番号: #{result.index_removed} 件の重複を削除")
  Common.log_info("[Step 8] 更新ファイル: #{result.files_modified.join(', ')}") if result.files_modified.any?
end

.rebuild_pdf!(_entries) ⇒ Object

浄化済み HTML で PDF を再ビルド



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 123

def rebuild_pdf!(_entries)
  # entries.js を再生成して PDF をビルド
  # 既存の entries.js がそのまま使えるため、PDF 生成のみ
  PdfCommands.execute_pdf({})

  pdf_config = Common::CONFIG['pdf'] || {}
  output_pdf = pdf_config['output_file'] || 'output.pdf'

  if File.exist?(output_pdf)
    FileUtils.cp(output_pdf, '_sections.pdf')
    Common.log_success('[Step 8] 重複排除済み _sections.pdf を再生成しました')
  else
    Common.log_warn('[Step 8] PDF 再ビルドの出力が見つかりません')
  end
end

.run!(entries = []) ⇒ Boolean

重複排除を実行し、浄化済み HTML で PDF を再ビルドする

Parameters:

  • entries (Array) (defaults to: [])

    ビルド対象エントリ(PDF再ビルド時に使用)

Returns:

  • (Boolean)

    重複排除が実行されたか



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
63
64
65
66
67
68
69
70
71
# File 'lib/vivlio/starter/cli/build/backlink_dedup_orchestrator.rb', line 37

def run!(entries = [])
  unless dedup_enabled?
    Common.log_info('[Step 8] 重複排除は無効です')
    return false
  end

  unless dedup_target_exists?
    Common.log_info('[Step 8] _glossarypage.html / _indexpage.html がいずれも存在しないためスキップします')
    return false
  end

  # --- Phase 1: ページマッピング抽出 ---
  Common.log_action('[Step 8] 重複排除を開始します…')
  page_mapping = extract_page_mapping

  return false unless page_mapping

  # --- Phase 2: HTML 浄化(用語集 + 索引を一括処理) ---
  result = deduplicate_backlinks(page_mapping)
  log_result(result)

  # --- Phase 3: 浄化された HTML で PDF を再ビルド ---
  if result.files_modified.any?
    Common.log_action('[Step 8] 浄化済み HTML で PDF を再ビルドします…')
    rebuild_pdf!(entries)
    true
  else
    Common.log_info('[Step 8] 重複なし。PDF 再ビルドは不要です')
    false
  end
rescue StandardError => e
  Common.log_warn("[Step 8] 重複排除でエラーが発生しました: #{e.message}")
  Common.log_warn('[Step 8] 重複排除をスキップし、既存の PDF で続行します')
  false
end