Module: VivlioStarter::CLI::PreProcessCommands::TalkRegistry
- Defined in:
- lib/vivlio_starter/cli/pre_process/talk_registry.rb
Overview
config/talk.yml の読み込みと正規化
Defined Under Namespace
Classes: Character, Registry, TalkDisplay
Constant Summary collapse
- DISPLAY_KEY =
表示設定を置くトップレベルの予約キー(これ以外はすべて話者とみなす)。
'display'- STYLES =
受理する表示形式。
%i[chat inline].freeze
- AVATAR_MODES =
アバターの表示モード(talk-auto-avatar-spec.md §1.1)。 :on … avatar: に画像を指定した話者だけ表示 :auto … 画像があればそれ、無ければ簡易アバターを自動生成 :off … 表示しない
%i[on auto off].freeze
- AVATAR_AUTO =
話者の avatar: にファイル名の代わりに書くと自動生成になる値。
'auto'- DEFAULT_DISPLAY =
組み込み既定(talk.yml に display: が無い/キーが欠けているときの値)。
TalkDisplay.new(style: :chat, name: true, avatar: :on, separator: ':').freeze
Class Method Summary collapse
- .allowed_colors ⇒ Object
- .blank_to_nil(value) ⇒ Object
-
.build_characters(raw) ⇒ Array<Character>
display: を除くトップレベルのキーをすべて話者として正規化する。.
-
.build_display(raw) ⇒ Object
display: セクションを TalkDisplay へ正規化する。キーが無ければ組み込み既定を使う。.
-
.color_valid?(value) ⇒ Boolean
ThemeValidator の色検証を流用する(遅延 require でロード循環を回避)。.
-
.default_path ⇒ Object
config/talk.yml の既定パス(config ディレクトリ直下)。.
-
.extract(spec, key) ⇒ Array(String, String, String, String)
1 エントリの値(簡易形=色文字列 / 詳細形=マップ)から属性 4 つを取り出す。.
-
.from_hash(raw) ⇒ Object
Hash(YAML 相当)から Registry を組む。テストと load から共用する。.
-
.load(path = default_path) ⇒ Registry
ファイルを読んで Registry を返す。存在しなければ空(present: false)。.
-
.parse_avatar_mode(raw) ⇒ Object
アバターの表示モードを解決する。
autoを先に見てから真偽解釈する (Common.truthy? は 'auto' を偽と判定するため)。. -
.parse_flag(raw, key, fallback) ⇒ Object
真偽キーを解決する。キーが無ければ既定を引き継ぐ(明示 false と区別する)。.
-
.parse_style(raw) ⇒ Object
style 値を Symbol へ。未指定は既定、未知値は 🟡 で既定へフォールバック。.
-
.read_yaml(path) ⇒ Object
壊れた YAML は 🔴+行番号で報告し、空({})として扱う(ビルドは止めない)。.
- .reset! ⇒ Object
-
.shared ⇒ Object
ビルド 1 回につき 1 度だけ読む共有インスタンス(前処理は章ごとに走るため)。 無効色などの警告もここで一度きりに集約される。テストは reset! で破棄する。.
-
.validate_color(raw, key) ⇒ Object
色の妥当性を検証する。無効値は 🟡 で警告してテーマ色へフォールバック(nil を返す)。 未指定(空)は警告せず nil(=テーマアクセント色を使う)。.
Class Method Details
.allowed_colors ⇒ Object
213 214 215 216 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 213 def allowed_colors require_relative 'frontmatter_generator' FrontmatterGenerator::ALLOWED_COLORS end |
.blank_to_nil(value) ⇒ Object
218 219 220 221 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 218 def blank_to_nil(value) s = value.to_s.strip s.empty? ? nil : s end |
.build_characters(raw) ⇒ Array<Character>
display: を除くトップレベルのキーをすべて話者として正規化する。
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 163 def build_characters(raw) # side 省略時は「出現順」で left, right, left, … と交互に割当てる(位置ベース)。 # 明示指定は値のみ上書きし、位置カウンタ自体は全話者で進める——そうすれば # 一部だけ side を明示しても、残りの自動割当が出現順の交互ストライプを保つ。 position = 0 raw.filter_map do |key, spec| key = key.to_s.strip next if key.empty? || key == DISPLAY_KEY name, color, avatar, side = extract(spec, key) side = position.even? ? 'left' : 'right' unless %w[left right].include?(side) position += 1 Character.new(key:, name:, color:, avatar:, side:) end end |
.build_display(raw) ⇒ Object
display: セクションを TalkDisplay へ正規化する。キーが無ければ組み込み既定を使う。
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 123 def build_display(raw) return DEFAULT_DISPLAY unless raw.is_a?(Hash) DEFAULT_DISPLAY.with( style: parse_style(raw['style']), name: parse_flag(raw, 'name', DEFAULT_DISPLAY.name), avatar: raw.key?('avatar') ? parse_avatar_mode(raw['avatar']) : DEFAULT_DISPLAY.avatar, separator: raw.key?('separator') ? raw['separator'].to_s : DEFAULT_DISPLAY.separator ) end |
.color_valid?(value) ⇒ Boolean
ThemeValidator の色検証を流用する(遅延 require でロード循環を回避)。
208 209 210 211 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 208 def color_valid?(value) require_relative 'theme_validator' ThemeValidator.valid_color?(value) end |
.default_path ⇒ Object
config/talk.yml の既定パス(config ディレクトリ直下)。
99 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 99 def default_path = File.join(Common.config_dir, 'talk.yml') |
.extract(spec, key) ⇒ Array(String, String, String, String)
1 エントリの値(簡易形=色文字列 / 詳細形=マップ)から属性 4 つを取り出す。
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 181 def extract(spec, key) if spec.is_a?(Hash) name = blank_to_nil(spec['name'] || spec[:name]) || key [name, validate_color(spec['color'] || spec[:color], key), blank_to_nil(spec['avatar'] || spec[:avatar]), (spec['side'] || spec[:side]).to_s.strip.downcase] else # 簡易形: 値が色(テーマ色名 or HEX)。表示名はキー、アバターなし、side 自動。 [key, validate_color(spec, key), nil, ''] end end |
.from_hash(raw) ⇒ Object
Hash(YAML 相当)から Registry を組む。テストと load から共用する。
117 118 119 120 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 117 def from_hash(raw) hash = raw.is_a?(Hash) ? raw : {} Registry.new(build_characters(hash), display: build_display(hash[DISPLAY_KEY]), present: true) end |
.load(path = default_path) ⇒ Registry
ファイルを読んで Registry を返す。存在しなければ空(present: false)。
104 105 106 107 108 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 104 def load(path = default_path) return Registry.new([], display: DEFAULT_DISPLAY, present: false) unless File.exist?(path) from_hash(read_yaml(path)) end |
.parse_avatar_mode(raw) ⇒ Object
アバターの表示モードを解決する。auto を先に見てから真偽解釈する
(Common.truthy? は 'auto' を偽と判定するため)。
136 137 138 139 140 141 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 136 def parse_avatar_mode(raw) value = raw.to_s.strip.downcase return :auto if value == AVATAR_AUTO Common.truthy?(value) ? :on : :off end |
.parse_flag(raw, key, fallback) ⇒ Object
真偽キーを解決する。キーが無ければ既定を引き継ぐ(明示 false と区別する)。
157 158 159 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 157 def parse_flag(raw, key, fallback) raw.key?(key) ? Common.truthy?(raw[key]) : fallback end |
.parse_style(raw) ⇒ Object
style 値を Symbol へ。未指定は既定、未知値は 🟡 で既定へフォールバック。
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 144 def parse_style(raw) value = raw.to_s.strip.downcase return DEFAULT_DISPLAY.style if value.empty? return value.to_sym if STYLES.include?(value.to_sym) Common.log_warn( "config/talk.yml: display.style '#{raw}' は不明な表示形式です。#{DEFAULT_DISPLAY.style} で続行します。", detail: "指定できるのは #{STYLES.join(' / ')} です" ) DEFAULT_DISPLAY.style end |
.read_yaml(path) ⇒ Object
壊れた YAML は 🔴+行番号で報告し、空({})として扱う(ビルドは止めない)。
224 225 226 227 228 229 230 231 232 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 224 def read_yaml(path) YAML.safe_load(File.read(path, encoding: 'utf-8'), aliases: true) rescue Psych::SyntaxError => e Common.log_error( "config/talk.yml の解析に失敗しました(#{e.line}行目付近)", detail: e.problem.to_s ) nil end |
.reset! ⇒ Object
114 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 114 def reset! = (@shared = nil) |
.shared ⇒ Object
ビルド 1 回につき 1 度だけ読む共有インスタンス(前処理は章ごとに走るため)。 無効色などの警告もここで一度きりに集約される。テストは reset! で破棄する。
112 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 112 def shared = (@shared ||= load) |
.validate_color(raw, key) ⇒ Object
色の妥当性を検証する。無効値は 🟡 で警告してテーマ色へフォールバック(nil を返す)。 未指定(空)は警告せず nil(=テーマアクセント色を使う)。
194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/vivlio_starter/cli/pre_process/talk_registry.rb', line 194 def validate_color(raw, key) value = raw.to_s.strip return nil if value.empty? return value if color_valid?(value) Common.log_warn( "config/talk.yml: キャラクター '#{key}' の色 '#{raw}' は無効です。テーマ色でビルドを続行します。", detail: "指定できる色: #{allowed_colors.join(' / ')}、" \ "または '#4f46e5' のような HEX(#rrggbb / #rrggbbaa)" ) nil end |