Module: VivlioStarter::CLI::ThemeColor
- Defined in:
- lib/vivlio_starter/cli/theme_color.rb
Overview
================================================================
テーマ・アクセント色の解決(色名/hex → リテラル hex)と混色。
パレットの正典は stylesheets/theme.css の --accent-*。本モジュールはその Ruby 側の写しで、 2 つの用途で共用する:
- Kindle 用リテラル焼き込み(KFX は var()/color-mix 非対応のため、book-settings.css に
テーマ色を具体色で焼く。kindle-theme-color-literalize-spec.md)。
- techbook の画像化アセットの色決定(Techbook::Processor#theme_color_hex)。
================================================================
Constant Summary collapse
- DEFAULT =
パレット不明・空・不正値のフォールバック(theme.css の既定テーマ yellow)。
'#f0a000'- PALETTE =
theme.css の --accent-* と一致させること(12 色)。
{ 'yellow' => '#f0a000', 'orange' => '#ea580c', 'red' => '#dc2626', 'magenta' => '#e11d74', 'purple' => '#7c3aed', 'indigo' => '#4f46e5', 'navy' => '#1d4ed8', 'blue' => '#0ea5e9', 'cyan' => '#06b6d4', 'teal' => '#0d9488', 'green' => '#15803d', 'lime' => '#65a30d' }.freeze
Class Method Summary collapse
-
.luminance(hex6) ⇒ Object
WCAG の相対輝度(0.0〜1.0)。地色の明るさに応じて載せる文字色を白/黒へ 切り替えるために使う(簡易アバターの自動生成・talk-auto-avatar-spec.md §2.2)。.
-
.mix_with_white(hex6, ratio) ⇒ Object
accent を白と混色して #rrggbb を返す(ratio = accent の割合・0.0〜1.0)。 KFX は color-mix() 非対応のため、CSS の color-mix(in srgb, accent R%, white) を事前計算する。.
-
.normalize_hex6(hex) ⇒ Object
#rgb → #rrggbb 展開・#rrggbbaa → #rrggbb 切詰(alpha 破棄)。それ以外は nil。.
-
.resolve(color) ⇒ Object
色名 / hex(3・6・8 桁)/ 0x → hex 文字列。3 桁・8 桁はそのまま返す(techbook 互換)。 解決不能(空・未知色名・注入文字列)は nil を返す——呼び出し側が既定色や fallback を 明示的に当てられるようにするため(to_hex6 の fallback を機能させる鍵)。.
-
.to_hex6(color, fallback: DEFAULT) ⇒ String
Kindle リテラル用: 必ず #rrggbb(6 桁)へ正規化する。resolve 結果を 6 桁化し、 解釈不能なら fallback(既定は DEFAULT)を 6 桁化して返す。book.yml 由来の不正値による CSS 注入・構文破壊を構造的に防ぐ(戻り値は必ず /\A#\h6\z/)。.
Class Method Details
.luminance(hex6) ⇒ Object
WCAG の相対輝度(0.0〜1.0)。地色の明るさに応じて載せる文字色を白/黒へ 切り替えるために使う(簡易アバターの自動生成・talk-auto-avatar-spec.md §2.2)。
64 65 66 67 68 |
# File 'lib/vivlio_starter/cli/theme_color.rb', line 64 def luminance(hex6) channels = hex6.delete_prefix('#').scan(/../).map { it.to_i(16) / 255.0 } linear = channels.map { it <= 0.03928 ? it / 12.92 : (((it + 0.055) / 1.055)**2.4) } (0.2126 * linear[0]) + (0.7152 * linear[1]) + (0.0722 * linear[2]) end |
.mix_with_white(hex6, ratio) ⇒ Object
accent を白と混色して #rrggbb を返す(ratio = accent の割合・0.0〜1.0)。 KFX は color-mix() 非対応のため、CSS の color-mix(in srgb, accent R%, white) を事前計算する。
73 74 75 76 77 |
# File 'lib/vivlio_starter/cli/theme_color.rb', line 73 def mix_with_white(hex6, ratio) rgb = hex6.delete_prefix('#').scan(/../).map { it.to_i(16) } mixed = rgb.map { ((it * ratio) + (255 * (1.0 - ratio))).round.clamp(0, 255) } format('#%02x%02x%02x', *mixed) end |
.normalize_hex6(hex) ⇒ Object
#rgb → #rrggbb 展開・#rrggbbaa → #rrggbb 切詰(alpha 破棄)。それ以外は nil。
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/vivlio_starter/cli/theme_color.rb', line 50 def normalize_hex6(hex) body = hex.to_s.strip.delete_prefix('#') return nil unless body.match?(/\A(?:\h{3}|\h{6}|\h{8})\z/) case body.length when 3 then "##{body.chars.map { it * 2 }.join}" when 6 then "##{body}" when 8 then "##{body[0, 6]}" end end |
.resolve(color) ⇒ Object
色名 / hex(3・6・8 桁)/ 0x → hex 文字列。3 桁・8 桁はそのまま返す(techbook 互換)。 解決不能(空・未知色名・注入文字列)は nil を返す——呼び出し側が既定色や fallback を 明示的に当てられるようにするため(to_hex6 の fallback を機能させる鍵)。
31 32 33 34 35 36 37 38 39 |
# File 'lib/vivlio_starter/cli/theme_color.rb', line 31 def resolve(color) raw = color.to_s.strip.downcase return nil if raw.empty? return raw if raw.match?(/\A#(?:\h{3}|\h{6}|\h{8})\z/) return "##{raw}" if raw.match?(/\A(?:\h{3}|\h{6}|\h{8})\z/) return "##{raw.delete_prefix('0x')}" if raw.match?(/\A0x(?:\h{6}|\h{8})\z/) PALETTE[raw] end |
.to_hex6(color, fallback: DEFAULT) ⇒ String
Kindle リテラル用: 必ず #rrggbb(6 桁)へ正規化する。resolve 結果を 6 桁化し、 解釈不能なら fallback(既定は DEFAULT)を 6 桁化して返す。book.yml 由来の不正値による CSS 注入・構文破壊を構造的に防ぐ(戻り値は必ず /\A#\h6\z/)。
45 46 47 |
# File 'lib/vivlio_starter/cli/theme_color.rb', line 45 def to_hex6(color, fallback: DEFAULT) normalize_hex6(resolve(color)) || normalize_hex6(resolve(fallback)) || DEFAULT end |