Module: Vivlio::Starter::CLI::Build::Utilities

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

Overview

ビルド共通ユーティリティモジュール

Class Method Summary collapse

Class Method Details

.chapter_numbers_for_book(entries_or_keep = nil) ⇒ Array<Integer>

1..89 範囲の章番号(整数)の配列を返す(新仕様)

Parameters:

  • entries_or_keep (Array<TokenResolver::Entry>, Array<String>, nil) (defaults to: nil)

    Entry 配列または basename 配列

Returns:

  • (Array<Integer>)

    1..89 範囲の章番号配列



57
58
59
60
61
62
63
64
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 57

def chapter_numbers_for_book(entries_or_keep = nil)
  entries = resolve_entries(entries_or_keep)
  entries
    .filter_map { it.number&.to_i }
    .grep(1..89)
    .uniq
    .sort
end

.chapter_numbers_for_outline(entries_or_keep = nil) ⇒ Array<Integer>

PDF アウトライン生成対象の章番号リストを取得(新仕様)

Parameters:

  • entries_or_keep (Array<TokenResolver::Entry>, Array<String>, nil) (defaults to: nil)

    Entry 配列または basename 配列

Returns:

  • (Array<Integer>)

    アウトライン対象の章番号配列



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

def chapter_numbers_for_outline(entries_or_keep = nil)
  # 新仕様: 0=PREFACE, 1-89=CHAPTERS, 90-98=APPENDICES, 99=POSTFACE
  allowed_numbers = [0, 99] + (1..89).to_a + (90..98).to_a
  entries = resolve_entries(entries_or_keep)

  numbers = entries
            .filter_map { it.number&.to_i }
            .select { allowed_numbers.include?(it) }

  # TOC (_toc.html) はアウトライン生成時に別途処理されるため、ここでは追加不要

  numbers.uniq!
  numbers.sort!
  numbers
end

.ensure_blank_page_pdf(path = 'blank_page.pdf') ⇒ Object

空白1ページPDFを生成



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 117

def ensure_blank_page_pdf(path = 'blank_page.pdf')
  return path if File.exist?(path)

  w_pt, h_pt = Build::Utilities.page_size_points_from_config
  require 'vivlio/starter/cli/pdf/provider'
  Vivlio::Starter::Pdf.provider.ensure_blank_page_pdf(path, w_pt, h_pt)

  # --- 旧実装(MIT化動作確認後に削除予定) ---
  # doc = HexaPDF::Document.new
  # w_pt, h_pt = Build::Utilities.page_size_points_from_config
  # doc.pages.add([0, 0, w_pt, h_pt])
  # doc.write(path, optimize: true)
  # path
end

.extract_basenames(entries_or_keep) ⇒ Array<String>

Entry 配列または basename 配列から basename 配列を抽出

Parameters:

Returns:

  • (Array<String>)

    basename 配列



88
89
90
91
92
93
94
95
96
97
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 88

def extract_basenames(entries_or_keep)
  raw = Array(entries_or_keep).compact
  return [] if raw.empty?

  if raw.first.respond_to?(:basename)
    raw.map(&:basename)
  else
    raw.map { |s| File.basename(s.to_s, '.md') }
  end
end

.page_count(file) ⇒ Object

PDF のページ数を取得(pdfinfo → HexaPDF フォールバック → MIT版へ変更)



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

def page_count(file)
  return nil unless File.exist?(file)

  # pdfinfo を優先
  if system('which pdfinfo >/dev/null 2>&1')
    info = `pdfinfo "#{file}" 2>/dev/null`
    pages = info[/^Pages:\s+(\d+)/i, 1]
    return pages.to_i if pages
  end

  # 新実装 (MIT版 Provider への委譲)
  require 'vivlio/starter/cli/pdf/provider'
  Vivlio::Starter::Pdf.provider.page_count(file)

  # --- 旧実装(MIT化動作確認後に削除予定) ---
  # doc = HexaPDF::Document.open(file)
  # doc.pages.count
rescue StandardError
  nil
end

.page_size_points_from_configObject

現在の設定からページサイズ(pt)を取得



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 146

def page_size_points_from_config
  width_s, height_s = page_size_strings_from_config
  mm_to_pt = 72.0 / 25.4
  parse_len = lambda { |s|
    str = s.to_s.strip.downcase
    if str.end_with?('mm')
      str.sub(/mm\z/, '').to_f * mm_to_pt
    elsif str.end_with?('pt')
      str.sub(/pt\z/, '').to_f
    else
      str.to_f
    end
  }
  w_pt = parse_len.call(width_s)
  h_pt = parse_len.call(height_s)
  if w_pt <= 0 || h_pt <= 0 || w_pt.nan? || h_pt.nan?
    w_pt = 182.0 * mm_to_pt
    h_pt = 257.0 * mm_to_pt
  end
  [w_pt, h_pt]
end

.page_size_strings_from_configObject

現在の設定からページサイズ(文字列: mm/pt)を取得



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 133

def page_size_strings_from_config
  page_cfg = Common::CONFIG['page'] || {}
  result = Common.resolve_page_size(page_cfg)
  if result.is_a?(Array) && result.size == 2 && result.all? do |dim|
    dim.to_s.strip.match?(/\A[0-9.]+(mm|pt)?\z/)
  end
    result
  else
    %w[182mm 257mm]
  end
end

.resolve_entries(entries_or_keep) ⇒ Array<TokenResolver::Entry>

Entry 配列または basename 配列を Entry 配列に解決

Parameters:

Returns:



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 102

def resolve_entries(entries_or_keep)
  raw = Array(entries_or_keep).compact
  if raw.empty?
    # 全ファイルを解決
    resolver = TokenResolver::Resolver.new
    Dir[File.join(Common::CONTENTS_DIR, '*.md')].map { resolver.resolve_file(it) }
  elsif raw.first.respond_to?(:kind)
    raw
  else
    resolver = TokenResolver::Resolver.new
    raw.map { resolver.resolve_file(it) }
  end
end

.total_page_count(files) ⇒ Object

複数 PDF の合計ページ数を返す



50
51
52
# File 'lib/vivlio/starter/cli/build/utilities.rb', line 50

def total_page_count(files)
  files.sum { |f| page_count(f).to_i }
end