Module: Vivlio::Starter::CLI::Import::YamlProcessor
- Defined in:
- lib/vivlio/starter/cli/import/yaml_processor.rb
Overview
YAML 設定ファイル変換モジュール
Class Method Summary collapse
-
.build_config_updates(config, config_starter) ⇒ Array<Array>
config.yml / config-starter.yml から更新リストを構築する.
-
.convert_catalog!(starter_dir) ⇒ void
catalog.yml を変換する.
-
.convert_config!(starter_dir) ⇒ void
config.yml / config-starter.yml を book.yml に変換する.
-
.extract_additional_fields(additional) ⇒ Object
additional フィールドから発行者・連絡先を抽出.
-
.extract_text(value) ⇒ Object
複数行テキストやハッシュから文字列を抽出.
-
.format_yaml_scalar(value) ⇒ Object
YAML スカラー値をフォーマットする.
-
.replace_yaml_value_in_lines!(lines, path, value) ⇒ Object
YAML 行内の値を置換する.
-
.strip_re_extension(value) ⇒ Object
.re 拡張子を再帰的に除去する.
-
.update_book_yaml_with_values(updates) ⇒ Boolean
book.yml を更新する.
-
.update_cover_config!(cover_filename) ⇒ Boolean
表紙設定を book.yml に反映する.
Class Method Details
.build_config_updates(config, config_starter) ⇒ Array<Array>
config.yml / config-starter.yml から更新リストを構築する
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 127 def build_config_updates(config, config_starter) updates = [] # 書籍タイトル main_title = extract_text(config['booktitle']) if config['booktitle'] updates << [%w[book main_title], main_title] if main_title && !main_title.empty? # サブタイトル subtitle = extract_text(config['subtitle']) if config['subtitle'] updates << [%w[book subtitle], subtitle] if subtitle && !subtitle.empty? # 言語 updates << [%w[book language], config['language']] if config['language'] # プロジェクト名・バージョン if config['bookname'] updates << [%w[project name], config['bookname']] updates << [%w[project version], '0.1.0'] end # 著者 if config['aut'] = Array(config['aut']) = .map { |a| a.is_a?(Hash) ? a['name'] : a.to_s } .reject { |name| name.to_s.strip.empty? } updates << [%w[book author], .first] if .any? end # additional フィールドから発行者・連絡先を抽出 updates.concat(extract_additional_fields(config['additional'])) if config['additional'] # 発行履歴 if config['history'] history = Array(config['history']).flatten release = history.find { |entry| !extract_text(entry).to_s.empty? } release_text = extract_text(release) if release updates << [%w[book release], release_text] if release_text && !release_text.empty? end # イベント名 updates << [%w[book series], config['pubevent_name']] if config['pubevent_name'] # ページサイズ if config_starter.dig('starter', 'pagesize') pagesize = config_starter.dig('starter', 'pagesize') page_use = case pagesize.to_s.upcase when 'B5' then 'b5_airy' when 'A5' then 'a5_compact' else 'a4_standard' end updates << [%w[page use], page_use] end updates end |
.convert_catalog!(starter_dir) ⇒ void
This method returns an undefined value.
catalog.yml を変換する
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 34 def convert_catalog!(starter_dir) Common.log_action('[Step 5] catalog.yml を変換します') starter_catalog = File.join(starter_dir, 'catalog.yml') unless File.exist?(starter_catalog) Common.log_warn(" catalog.yml が見つかりません: #{starter_catalog}") return end catalog = YAML.safe_load_file(starter_catalog, permitted_classes: [Symbol]) key_map = { 'PREDEF' => 'PREFACE', 'CHAPS' => 'CHAPTERS', 'APPENDIX' => 'APPENDICES', 'POSTDEF' => 'POSTFACE' } new_catalog = {} catalog.each do |key, value| new_key = key_map[key] || key new_catalog[new_key] = strip_re_extension(value) end Build::CatalogUpdater.save_catalog(new_catalog) Common.log_info(' config/catalog.yml を更新しました(コメント保持)') end |
.convert_config!(starter_dir) ⇒ void
This method returns an undefined value.
config.yml / config-starter.yml を book.yml に変換する
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 66 def convert_config!(starter_dir) Common.log_action('[Step 6] config.yml を変換します') starter_config = File.join(starter_dir, 'config.yml') starter_config_starter = File.join(starter_dir, 'config-starter.yml') unless File.exist?(starter_config) Common.log_warn(" config.yml が見つかりません: #{starter_config}") return end config = YAML.safe_load_file(starter_config, permitted_classes: [Symbol]) config_starter = if File.exist?(starter_config_starter) YAML.safe_load_file(starter_config_starter, permitted_classes: [Symbol]) else {} end updates = build_config_updates(config, config_starter) if update_book_yaml_with_values(updates) Common.log_info(' config/book.yml を更新しました(コメント保持)') else Common.log_info(' config/book.yml に反映すべき値がありませんでした') end end |
.extract_additional_fields(additional) ⇒ Object
additional フィールドから発行者・連絡先を抽出
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 184 def extract_additional_fields(additional) updates = [] additional.each do |item| next unless item.is_a?(Hash) case item['key'] when '発行者' value = extract_text(item['value']) updates << [%w[book publisher], value] if value && !value.empty? when '連絡先' contacts = Array(item['value']) email = contacts.find { |c| c.to_s.include?('@') } updates << [%w[book contact], email] if email end end updates end |
.extract_text(value) ⇒ Object
複数行テキストやハッシュから文字列を抽出
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 203 def extract_text(value) case value when Hash value['name'] || value.values.first when String value.gsub("\n", ' ').strip else value.to_s end end |
.format_yaml_scalar(value) ⇒ Object
YAML スカラー値をフォーマットする
271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 271 def format_yaml_scalar(value) case value when Numeric value.to_s when TrueClass, FalseClass value.to_s else str = value.to_s return "''" if str.empty? escaped = str.gsub(/["\\]/) { |m| "\\#{m}" } "\"#{escaped}\"" end end |
.replace_yaml_value_in_lines!(lines, path, value) ⇒ Object
YAML 行内の値を置換する
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 241 def replace_yaml_value_in_lines!(lines, path, value) stack = [] lines.each_with_index do |line, idx| next if line.lstrip.start_with?('#') match = line.match(/^(\s*)([A-Za-z0-9_]+):(.*)$/) next unless match indent = match[1].length key = match[2] stack.pop while stack.any? && stack.last[:indent] >= indent stack << { key: key, indent: indent } next unless stack.map { |item| item[:key] } == path comment = match[3]&.match(/(\s+#.*)$/)&.[](1) scalar = format_yaml_scalar(value) new_line = "#{match[1]}#{key}: #{scalar}" new_line += comment.to_s new_line << "\n" lines[idx] = new_line return true end false end |
.strip_re_extension(value) ⇒ Object
.re 拡張子を再帰的に除去する
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 108 def strip_re_extension(value) case value when Array value.map { |v| strip_re_extension(v) } when Hash value.transform_keys { |k| k.to_s.sub(/\.re$/, '') } .transform_values { |v| strip_re_extension(v) } when String value.sub(/\.re$/, '') else value end end |
.update_book_yaml_with_values(updates) ⇒ Boolean
book.yml を更新する
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 218 def update_book_yaml_with_values(updates) book_yml_path = 'config/book.yml' unless File.exist?(book_yml_path) Common.log_warn(" #{book_yml_path} が見つからなかったため、更新をスキップします") return false end lines = File.readlines(book_yml_path, encoding: 'utf-8') updated = false updates.each do |path, value| next if value.nil? replaced = replace_yaml_value_in_lines!(lines, path, value) Common.log_warn(" #{book_yml_path} 内で #{path.join('.')} を更新できませんでした") unless replaced updated ||= replaced end File.write(book_yml_path, lines.join, encoding: 'utf-8') if updated updated end |
.update_cover_config!(cover_filename) ⇒ Boolean
表紙設定を book.yml に反映する
97 98 99 100 101 102 |
# File 'lib/vivlio/starter/cli/import/yaml_processor.rb', line 97 def update_cover_config!(cover_filename) return false unless cover_filename updates = [[%w[output pdf cover front], cover_filename]] update_book_yaml_with_values(updates) end |