Module: VivlioStarter::CLI::PreProcessCommands::BookSettingsCss
- Defined in:
- lib/vivlio_starter/cli/pre_process/book_settings_css.rb
Overview
book-settings.css 生成モジュール
Constant Summary collapse
- CACHE_TO_STYLESHEETS =
.cache/vs/からstylesheets/への相対プレフィックス。 生成ファイルは 2 階層深いため、stylesheets/ 基準の相対 URL をこの接頭辞で組み替える。 '../../stylesheets/'- DEFAULT_HEADING_CHARS =
theme.css が持つ既定の文字数(未指定時の値と一致させる)。 EpubBuilder も同じ既定でリード幅比を導くため公開している(§5-1)。
8- DEFAULT_LEAD_CHARS =
20- DEFAULT_ORNAMENT_HEADING_CHARS =
14- SECTION_TITLE_FONT_Q_RANGE =
節題の基準フォントサイズ(Q)。節絵の帯は版面幅から左右の飾り避け(padding-inline)を 引いた幅が使える。字数を増やすほど小さく、減らすほど大きくなる。 極端な指定で本文と階層が崩れないよう 20〜48Q に収める。
(20.0..48.0)
- SECTION_TITLE_PADDING_LEFT_MM =
節絵の飾り避け(image-header.css の padding-inline)。左右それぞれ
clamp(下限, --paper-scale × 基準, 基準)で用紙比に応じて縮む。 { min: 11.0, base: 16.0 }.freeze
- SECTION_TITLE_PADDING_RIGHT_MM =
{ min: 12.0, base: 18.0 }.freeze
- SECTION_TITLE_HEADROOM =
行あふれの余裕。節番号(
6-3)の幅・英数字の字幅の揺れ・禁則処理で わずかにはみ出しても、指定した字数で折り返せるようにする。 0.96- SECTION_PAGEBREAK_SELECTORS =
================================================================
節(h2)の改ページ(page-break-control-spec.md §2.2)
節でページを改める既存ルールの元セレクタ。打ち消しは「元セレクタをそのまま 複製」する必要がある——book-settings.css は後段読込なので同特異度なら後勝ち できるが、セレクタがずれると特異度負けして効かない。
[ 'body.vs-header-image .section-topic h2', # image-header.css(PDF / EPUB) 'body.vs-header-simple h2', # simple-header.css(PDF / EPUB) 'body.vs-header-simple.vs-kindle h2', # simple-header.css の Kindle 用(legacy 併記) 'article.vs-section-topic-epub' # components.css(EPUB の節絵 article) ].freeze
- CHAPTER_PAGEBREAK_SELECTORS =
================================================================
章の改丁(chapter-pagebreak-spec.md §2.2)
章・目次・部扉・付録・用語集・後書き・索引を右ページ始まりにする既存ルールの 元セレクタ。7 ファイルに散っているが、chapter-common / glossary / index / postface の 4 つはいずれも素の body なので、相異なるセレクタは 4 つで足りる。 打ち消しは「元セレクタをそのまま複製」する必要がある——book-settings.css は 後段読込なので同特異度なら後勝ちできるが、ずれると特異度負けして効かない。
[ 'body', # chapter-common.css / glossary.css / index.css / postface.css 'body.toc', # toc.css 'body.vs-header-simple h1', # simple-header.css '.part-title' # part-title.css ].freeze
- CHAPTER_PAGEBREAK_VALUES =
page.chapter_pagebreak が取りうる値。@pagebreak 記法(裸 / :recto / :verso)と ちょうど 1 対 1 に対応させてある(裸の @pagebreak = any)。
%w[recto verso any].freeze
- DEFAULT_CHAPTER_PAGEBREAK =
'recto'
Class Method Summary collapse
-
.adm_label_rule(prefix, color) ⇒ Object
実体ラベル【TIP】等(Kindle は ::before を content:none で抑止し vs-adm-label を注入・既定 #444)。 .terminal は白ラベル override が特異度で勝つため、.output は PDF にラベル無しのため、含めない。.
-
.appendix_accent_hex6(theme_cfg, theme_hex) ⇒ Object
付録アクセントのリテラル hex。appendix_color 未指定時は appendix.css の静的既定 (--appendix-accent-color: var(--accent-yellow))に合わせて yellow を返す——PDF/クリーン EPUB の実カスケードと一致させるため(theme.color にはフォールバックしない)。.
-
.appendix_kindle_accent_rules(apx) ⇒ Object
付録は appendix.css が --heading-accent / --color-mark を appendix-accent へ差し替えるため、 見出し・h3 マーカー・ラベルを APX で上書きする(strong/枠は theme-accent のままで base が担う)。 .appendix が 1 つ多く特異度で勝つ。.
-
.base_kindle_accent_rules(acc, colbg) ⇒ Object
本文・見出しのアクセント規則(テーマ色 ACC / コラム地色 COLBG)。theme.style によらず共通。.
-
.build_page_cfg(cfg) ⇒ Object
book.yml の page / typography から、CSS 変数マッピングに渡せる page_cfg を組み立てる。 紙サイズ正規化・用紙スケール・行長・ノンブル配置・綴じオフセットを算出して詰める。.
-
.chapter_frontispiece_guard_rule ⇒ Object
章扉(h1 のページ)だけは節の改ページを止めても独立させる。.
-
.chapter_lead_advance_mm(page_cfg) ⇒ Object
章リード 1 字の送り(mm)。.chapter-lead は font-size: larger(= 親の 1.2 倍)で letter-spacing は本文既定(0)。基準は page プリセットの base_font_size。.
- .chapter_pagebreak_css(value, legacy: nil, note: '') ⇒ Object
-
.chapter_pagebreak_rule(page_cfg) ⇒ Object
既定(recto)では何も出さず、テーマ CSS の break-before: recto をそのまま生かす (P3 の「書かない条件では宣言しない」セマンティクス)。.
-
.chapter_pagebreak_value(page_cfg) ⇒ Object
設定値の正規化。不正値・未設定は既定(recto)へ倒す。警告は出さない ——PdfMerger も同じ判定を借りるため、ここで鳴らすと 1 ビルドで二度警告が出る。.
-
.chapter_title_advance_mm(scale) ⇒ Object
章題 1 字の送り(mm)。image-header.css の .chapter-title の
font-size: clamp(34Q, calc(var(--paper-scale) * 48Q), 50Q)とletter-spacing: 0.08emを再現する。CSS 側を変えたらここも直すこと (回帰テストで両者の一致を固定してある)。. -
.css_image_value(raw, image_prefix:) ⇒ Object
テーマ画像の CSS 値を url("...") 形式で返す。 stylesheets/ 基準の相対パスを生成ファイル位置基準へ組み替える(調査報告 §7.3-1)。 既に url(...) 形式ならその内側パスを、素のパスならそのものを対象にする。 data:/http(s):/絶対パスは組み替えない。.
-
.emphasis_fallback_rules ⇒ Object
本文書体に太字が無いときの強調(ゴシック代用)。.
-
.ensure_fonts_available(cfg) ⇒ Object
book.yml の typography が要求するフォントを準備する(CSS 書換とは独立に必要)。.
-
.escape_marker(mark) ⇒ Object
CSS の "..." 文字列内で安全なマーカー文字にする(" と \ をエスケープ)。.
-
.font_synthesis_rules(cfg) ⇒ Object
疑似太字(faux-bold)の抑止 — Type 3 フォント対策 ================================================================ Bold 字面を持たない書体に太字を要求すると、Chromium は字を太らせて 合成し、それを Type 3 フォントとして PDF へ埋め込む。Type 3 は 技術書典等の入稿で不可(実測 2026-08-07: Noto Sans JP 指定の 1 章 ビルドで Type 3 が 195 件)。.
- .format_mm(value) ⇒ Object
-
.format_number(value) ⇒ Object
末尾の 0 を落とす(103.68 → 103.68 / 36.0 → 36).
-
.frontispiece_position_rule(settings, page_cfg) ⇒ Object
扉背景の background-position もリテラル必須——Vivliostyle は background-position の calc() 内 var() を解さず宣言ごと落とし、背景が左上(0 0)へ偏る(pdf_chapter5 実測。 background-size の calc()+var() は解すので size 側は image-header.css のままでよい)。 綴じオフセットを生成時に焼き込み、image-header.css の既定(center center)を上書きする。.
-
.generate!(cfg = nil) ⇒ String?
book-settings.css を生成し、フォント準備と config.js 同期も行う。 プレフライト/フル/単章の全モードで 'prepare theme images' ステップから呼ばれる。.
-
.header_comment ⇒ Object
生成ファイル先頭の注意書き。.
-
.heading_metric_declarations(settings, page_cfg) ⇒ Object
見出しの寸法(heading-metrics-spec §1-2) ================================================================ 著者は book.yml に「1 行の文字数」で書く。判型に追従する CSS の clamp() を calc() の中で掛け合わせると Vivliostyle が宣言ごと落とすため、 換算は生成時に行いリテラルで焼き込む(@page size・綴じオフセットと同型)。.
-
.index_glossary_kindle_accent_rules(acc, colbg) ⇒ Object
索引・用語集は章と別の HTML(UnifiedPageBuilder 生成)で body クラスも異なるため、 上の body.vs-kindle 規則では届かない罫線・見出し色を個別に literalize する。.
-
.kindle_accent_rules(cfg) ⇒ Object
Kindle 用テーマ色リテラル(kindle-theme-color-literalize-spec.md) ================================================================ KFX は var()/color-mix()/calc() を解さないため、テーマ色で塗った本文アクセント (strong・下線・見出しマーカー・コラム/注記枠・付録見出し)が Kindle では黒/グレー/ くすんだ金へ劣化する。book-settings.css は最後に読まれるので、ここへテーマ色を リテラル hex で焼いた body.vs-kindle 規則を出せば、静的な #888/#b8860b フォールバックを 後勝ちで上書きできる。body.vs-kindle 前置のためクリーン EPUB では不発(無害)。.
-
.marker_declarations(cfg) ⇒ Object
見出しマーカー(旧 update_chapter_common_css 相当)。未指定時は ♣ / ♦。.
-
.output_path ⇒ Object
生成ファイルのパス(.cache/vs/book-settings.css)。.
-
.page_declarations(page_cfg) ⇒ Object
page-settings 系 22 変数(旧 update_page_settings_css 相当)。 nil/空値は宣言しない(page-settings.css の既定がカスケードで生きる)。.
-
.page_size_rule(page_cfg) ⇒ Object
width/height が空なら @page 規則自体を出さない。.
-
.paper_scale_of(page_cfg) ⇒ Object
build_page_cfg が算出済みの値を使う(同じ計算を 2 度しない).
-
.preface_accent_hex6(theme_cfg, theme_hex) ⇒ Object
前書き/後書きアクセントのリテラル hex。preface_color 未指定時はテーマ色へフォールバック (supplemental_color_declarations が --color-preface-accent を常に fallback: accent で宣言する のと一致=PDF/クリーン EPUB のカスケードと揃える。appendix の yellow 既定とは異なる)。.
-
.preface_kindle_accent_rules(pref) ⇒ Object
前書き(body.preface)/ 後書き(body.postface。postface.css が preface.css を import)の accent 規則。preface.css は h1 下線・h2/引用の左罫・リンク色を var(--color-preface-accent) で 塗るが KFX で全滅する(h1 下線だけ静的 #4f46e5 フォールバックがあるがテーマ非追従)。 book-settings.css は全ページ共通のため body.preface / body.postface で必ずスコープする (裸の h1/h2 規則を出すと本文章へ波及する)。論理プロパティは避け物理で書く。.
-
.rebase_relative(path, image_prefix:) ⇒ Object
stylesheets/ 基準の相対パスを image_prefix で組み替える。 外部 URL・data URI・絶対パスは対象外。二重組替を避ける冪等ガード付き。 theme-images/… は生成バリアントのキャッシュ参照で、既に生成ファイル位置 (.cache/vs/)基準のため組み替えない(generated-assets 移設仕様 §3.1)。.
-
.render(cfg = Common::CONFIG, image_prefix: CACHE_TO_STYLESHEETS) ⇒ String
生成する CSS 全文を組み立てる(副作用なし・テスト対象)。.
-
.section_pagebreak_disabled?(page_cfg) ⇒ Boolean
明示的に false と書かれたときだけ「節で改ページしない」と解釈する。 未設定・空欄は既定の true(現行挙動)を保つため、truthy? の裏返しではない。.
-
.section_pagebreak_rule(page_cfg) ⇒ Object
page.section_pagebreak: false のときだけ打ち消し規則を出す。 true・未設定では何も出さず、テーマ CSS の改ページがそのまま生きる (P3 の「書かない条件では宣言しない」セマンティクス)。 打ち消しだけでは章扉に最初の節が流れ込むため、章扉の保護を続けて出す。.
- .section_title_font_q(chars, text_mm, scale) ⇒ Object
-
.section_title_ornament_padding_mm(scale) ⇒ Object
飾り避けの合計(mm)。CSS と同じ式で求める。.
-
.selector_group(scopes, element) ⇒ Object
複数スコープ × 要素をカンマ区切りのセレクタ群にする("a b, c b")。.
-
.supplemental_color_declarations(settings, cfg) ⇒ Object
appendix / preface のアクセント色(旧 update_appendix_css / update_preface_css 相当)。 - appendix_color 未指定なら宣言しない(appendix.css の既定がカスケードで生きる) - preface は常に宣言(未指定時は theme accent へフォールバック).
-
.talk_class_rules(registry) ⇒ Object
.talk-c-
の --talk-accent 差し替えと、Kindle 用リテラル色。 PDF/クリーン EPUB は var() 経由で色を当て、Kindle は KFX が var() を解さないため 具体色(hex)で焼く(テーマ色名→hex は ThemeColor.to_hex6 で解決)。. -
.talk_variable_declarations(registry) ⇒ Object
:root に置く --talk-c-
の宣言行。色を明示した話者のみ(未指定はテーマ色を使う)。. -
.text_area_width_mm(page_cfg) ⇒ Object
版面幅(mm)= 紙幅 − ノド − 小口。導けないときは A4 標準相当へ。.
-
.theme_declarations(settings, image_prefix:, page_cfg: {}) ⇒ Object
theme 系変数(旧 update_theme_css 相当) ================================================================ 条件付き宣言のセマンティクスを in-place 版と一致させる(調査報告 §7.3-2): - simple スタイル: 画像 2 変数は none、frontispiece-edge-inset は宣言しない - image スタイル : 画像 2 変数+edge_inset を宣言 - 見出しの寸法は文字数指定がある時だけ宣言(theme.css の既定が生きる).
-
.url_inner(value) ⇒ Object
url("...") / url('...') / url(...) の内側を取り出す。url() でなければそのまま返す。.
-
.warn_if_wider_than_text_area(label, chars, advance_mm, text_mm) ⇒ Object
版面に収まらない文字数指定は 🟡 で具体的な上限を示す(warning-messages の方針)。.
-
.warn_unknown_chapter_pagebreak!(page_cfg) ⇒ Object
綴り間違いが黙って既定へ戻ると著者は気づけないので知らせる。鳴らすのは CSS 生成の 1 回だけ(generate! はビルド Step 2 で必ず通る唯一の接続先)。.
Class Method Details
.adm_label_rule(prefix, color) ⇒ Object
実体ラベル【TIP】等(Kindle は ::before を content:none で抑止し vs-adm-label を注入・既定 #444)。 .terminal は白ラベル override が特異度で勝つため、.output は PDF にラベル無しのため、含めない。
606 607 608 609 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 606 def adm_label_rule(prefix, color) %w[tip memo column notice note] .map { "#{prefix} .#{it} .vs-adm-label" }.join(', ') + " { color: #{color}; }" end |
.appendix_accent_hex6(theme_cfg, theme_hex) ⇒ Object
付録アクセントのリテラル hex。appendix_color 未指定時は appendix.css の静的既定 (--appendix-accent-color: var(--accent-yellow))に合わせて yellow を返す——PDF/クリーン EPUB の実カスケードと一致させるため(theme.color にはフォールバックしない)。
541 542 543 544 545 546 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 541 def appendix_accent_hex6(theme_cfg, theme_hex) raw = theme_cfg.appendix_color return ThemeColor::DEFAULT if raw.to_s.strip.empty? ThemeColor.to_hex6(raw, fallback: theme_hex) end |
.appendix_kindle_accent_rules(apx) ⇒ Object
付録は appendix.css が --heading-accent / --color-mark を appendix-accent へ差し替えるため、 見出し・h3 マーカー・ラベルを APX で上書きする(strong/枠は theme-accent のままで base が担う)。 .appendix が 1 つ多く特異度で勝つ。
593 594 595 596 597 598 599 600 601 602 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 593 def appendix_kindle_accent_rules(apx) [ "body.appendix.vs-header-simple.vs-kindle h1 { border-color: #{apx}; }", "body.appendix.vs-header-simple.vs-kindle h1 .chapter-number { color: #{apx}; }", "body.appendix.vs-header-simple.vs-kindle h2 { border-color: #{apx}; border-left-color: #{apx}; }", "body.appendix.vs-header-simple.vs-kindle h2 .section-number { background: #{apx}; }", "body.appendix.vs-kindle .subsection-marker { color: #{apx}; }", adm_label_rule('body.appendix.vs-kindle', apx) ] end |
.base_kindle_accent_rules(acc, colbg) ⇒ Object
本文・見出しのアクセント規則(テーマ色 ACC / コラム地色 COLBG)。theme.style によらず共通。
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 559 def base_kindle_accent_rules(acc, colbg) [ "body.vs-kindle strong { color: #{acc}; }", "body.vs-kindle em { text-decoration-color: #{acc}; }", "body.vs-kindle .subsection-marker { color: #{acc}; }", "body.vs-kindle .column { border-color: #{acc}; background: #{colbg}; }", "body.vs-kindle .tip { border-color: #{acc}; }", "body.vs-kindle .memo { border-color: #{acc}; }", "body.vs-kindle .note { border-color: #{acc}; }", "body.vs-kindle .notice { border-color: #{acc}; }", adm_label_rule('body.vs-kindle', acc), "body.vs-header-simple.vs-kindle h1 { border-color: #{acc}; }", "body.vs-header-simple.vs-kindle h1 .chapter-number { color: #{acc}; }", "body.vs-header-simple.vs-kindle h2 { border-color: #{acc}; border-left-color: #{acc}; }", "body.vs-header-simple.vs-kindle h2 .section-number { background: #{acc}; }" ] + index_glossary_kindle_accent_rules(acc, colbg) end |
.build_page_cfg(cfg) ⇒ Object
book.yml の page / typography から、CSS 変数マッピングに渡せる page_cfg を組み立てる。 紙サイズ正規化・用紙スケール・行長・ノンブル配置・綴じオフセットを算出して詰める。
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 677 def build_page_cfg(cfg) page_cfg = FrontmatterGenerator.safe_config_hash(cfg.page) typo_cfg = FrontmatterGenerator.safe_config_hash(cfg.typography) # typography からフォント設定を取り込む page_cfg[:main_text_font] = typo_cfg&.dig(:body, :font) page_cfg[:header_font] = typo_cfg&.dig(:heading, :font) page_cfg[:column_font] = typo_cfg&.dig(:column, :font) page_cfg[:code_font] = typo_cfg&.dig(:code, :font) page_cfg[:folio_font] = typo_cfg&.dig(:folio, :font) page_cfg[:column_font_size] = Units.font_size_to_pt(typo_cfg&.dig(:column, :font_size)) page_cfg[:folio_placement] = typo_cfg&.dig(:folio, :placement) Common.normalize_page_size!(page_cfg) page_cfg[:paper_scale] = CssUpdater.calculate_paper_scale(page_cfg[:width], page_cfg[:height]) page_cfg[:align_max_width] = CssUpdater.calculate_align_max_width(page_cfg[:width]) CssUpdater.apply_folio_placement!(page_cfg) page_cfg[:frontispiece_binding_offset] = CssUpdater.calculate_frontispiece_binding_offset( page_cfg[:margin_inner], page_cfg[:margin_outer] ) page_cfg end |
.chapter_frontispiece_guard_rule ⇒ Object
章扉(h1 のページ)だけは節の改ページを止めても独立させる。
image スタイルの章扉は @page :nth(1) の全面背景(扉絵)で成立しているので、 最初の節が同ページへ流れ込むと扉絵の上に本文と節絵が重なる(pdf_h1.png 実測)。 EPUB/Kindle の扉絵は通常フローの合成 SVG 画像で全面背景ではないため保護不要 ——body.vs-epub(クリーン・Kindle 共通マーカー)を除外して PDF に限定する。 section.level2:first-of-type は section.level1 直下の最初の節。h1 と .chapter-lead は section 要素でないので :first-of-type の数に入らない。
415 416 417 418 419 420 421 422 423 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 415 def chapter_frontispiece_guard_rule <<~CSS.chomp /* 章扉は全面の扉絵で成立するページなので、最初の節だけは次ページから始める。 */ body.vs-header-image:not(.vs-epub) section.level2:first-of-type > .section-topic h2 { break-before: page; page-break-before: always; } CSS end |
.chapter_lead_advance_mm(page_cfg) ⇒ Object
章リード 1 字の送り(mm)。.chapter-lead は font-size: larger(= 親の 1.2 倍)で letter-spacing は本文既定(0)。基準は page プリセットの base_font_size。
231 232 233 234 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 231 def chapter_lead_advance_mm(page_cfg) base_mm = Units.length_to_mm(page_cfg[:base_font_size]) || (10.5 * 25.4 / 72.0) base_mm * 1.2 end |
.chapter_pagebreak_css(value, legacy: nil, note: '') ⇒ Object
476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 476 def chapter_pagebreak_css(value, legacy: nil, note: '') declarations = ["break-before: #{value};"] declarations << "page-break-before: #{legacy};" if legacy <<~CSS.chomp /* page.chapter_pagebreak — 章・目次・部扉・付録・用語集・後書き・索引を#{note}。 原稿中の @pagebreak:recto / :verso(.vs-break-*)はここでは触らないため、 局所の明示指定が本設定より優先される。 */ #{CHAPTER_PAGEBREAK_SELECTORS.join(",\n")} { #{declarations.join("\n ")} } CSS end |
.chapter_pagebreak_rule(page_cfg) ⇒ Object
既定(recto)では何も出さず、テーマ CSS の break-before: recto をそのまま生かす (P3 の「書かない条件では宣言しない」セマンティクス)。
any の置換先を auto ではなく page にするのは、.part-title と body.vs-header-simple h1 が文書内の要素であり、auto にすると直前の内容へ 流れ込んでしまうため。body への page は分割フローの先頭なので実害が無い。 verso には legacy page-break-before の対応値が無いので併記しない (KFX はいずれにせよ recto/verso を解さない)。
462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 462 def chapter_pagebreak_rule(page_cfg) warn_unknown_chapter_pagebreak!(page_cfg) case chapter_pagebreak_value(page_cfg) when 'any' chapter_pagebreak_css('page', legacy: 'always', note: 'どちら側の面からでも始める(白紙を挿入しない)') when 'verso' chapter_pagebreak_css('verso', note: '左ページ(偶数)始まりにする') else '' end end |
.chapter_pagebreak_value(page_cfg) ⇒ Object
設定値の正規化。不正値・未設定は既定(recto)へ倒す。警告は出さない ——PdfMerger も同じ判定を借りるため、ここで鳴らすと 1 ビルドで二度警告が出る。
492 493 494 495 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 492 def chapter_pagebreak_value(page_cfg) raw = page_cfg[:chapter_pagebreak].to_s.strip.downcase CHAPTER_PAGEBREAK_VALUES.include?(raw) ? raw : DEFAULT_CHAPTER_PAGEBREAK end |
.chapter_title_advance_mm(scale) ⇒ Object
章題 1 字の送り(mm)。image-header.css の .chapter-title の
font-size: clamp(34Q, calc(var(--paper-scale) * 48Q), 50Q) と
letter-spacing: 0.08em を再現する。CSS 側を変えたらここも直すこと
(回帰テストで両者の一致を固定してある)。
224 225 226 227 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 224 def chapter_title_advance_mm(scale) font_q = (scale * 48).clamp(34, 50) font_q * 0.25 * 1.08 end |
.css_image_value(raw, image_prefix:) ⇒ Object
テーマ画像の CSS 値を url("...") 形式で返す。 stylesheets/ 基準の相対パスを生成ファイル位置基準へ組み替える(調査報告 §7.3-1)。 既に url(...) 形式ならその内側パスを、素のパスならそのものを対象にする。 data:/http(s):/絶対パスは組み替えない。
708 709 710 711 712 713 714 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 708 def css_image_value(raw, image_prefix:) value = raw.to_s.strip return 'none' if value.empty? || value.casecmp?('none') inner = url_inner(value) %(url("#{rebase_relative(inner, image_prefix:)}")) end |
.emphasis_fallback_rules ⇒ Object
本文書体に太字が無いときの強調(ゴシック代用)。
136 137 138 139 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 136 def emphasis_fallback_rules ['/* 本文書体に太字が無いため、強調は見出し書体(ゴシック)で表す */', 'strong, b { font-family: var(--font-header); }'] end |
.ensure_fonts_available(cfg) ⇒ Object
book.yml の typography が要求するフォントを準備する(CSS 書換とは独立に必要)。
748 749 750 751 752 753 754 755 756 757 758 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 748 def ensure_fonts_available(cfg) typo_cfg = FrontmatterGenerator.safe_config_hash(cfg.typography) font_names = [ typo_cfg&.dig(:body, :font), typo_cfg&.dig(:heading, :font), typo_cfg&.dig(:column, :font), typo_cfg&.dig(:code, :font), typo_cfg&.dig(:folio, :font) ] FontManager.ensure_fonts_available(font_names) end |
.escape_marker(mark) ⇒ Object
CSS の "..." 文字列内で安全なマーカー文字にする(" と \ をエスケープ)。
739 740 741 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 739 def escape_marker(mark) mark.gsub('\\', '\\\\\\\\').gsub('"', '\\"') end |
.font_synthesis_rules(cfg) ⇒ Object
================================================================
疑似太字(faux-bold)の抑止 — Type 3 フォント対策
Bold 字面を持たない書体に太字を要求すると、Chromium は字を太らせて 合成し、それを Type 3 フォントとして PDF へ埋め込む。Type 3 は 技術書典等の入稿で不可(実測 2026-08-07: Noto Sans JP 指定の 1 章 ビルドで Type 3 が 195 件)。
対策は 2 段:
1. `font-synthesis-weight: none` で合成そのものを止める。実 Bold が
ある書体には影響しない——実体があるとき合成は起きないため。
2. それだけだと本文の **強調** が標準の太さになって埋もれるので、
本文書体に太字が無いときに限り `strong`/`b` を見出し書体(ゴシック)へ
振る。明朝の強調にゴシックを当てるのは和文組版の作法でもある。
同梱書体は Regular/Bold 両字面を持つため 2 は発動せず、見た目は変わらない。
詳細は type3-font-embedding-notes.md。
127 128 129 130 131 132 133 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 127 def font_synthesis_rules(cfg) typo = FrontmatterGenerator.safe_config_hash(cfg&.typography) || {} rules = ['/* faux-bold を禁止して Type 3 フォントの混入を断つ */', 'body, body *, body *::before, body *::after { font-synthesis-weight: none; }'] rules.concat(emphasis_fallback_rules) unless FontManager.bold_available?(typo.dig(:body, :font)) rules.join("\n") end |
.format_mm(value) ⇒ Object
299 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 299 def format_mm(value) = "#{format_number(value)}mm" |
.format_number(value) ⇒ Object
末尾の 0 を落とす(103.68 → 103.68 / 36.0 → 36)
302 303 304 305 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 302 def format_number(value) rounded = value.round(2) rounded == rounded.to_i ? rounded.to_i.to_s : rounded.to_s end |
.frontispiece_position_rule(settings, page_cfg) ⇒ Object
扉背景の background-position もリテラル必須——Vivliostyle は background-position の calc() 内 var() を解さず宣言ごと落とし、背景が左上(0 0)へ偏る(pdf_chapter5 実測。 background-size の calc()+var() は解すので size 側は image-header.css のままでよい)。 綴じオフセットを生成時に焼き込み、image-header.css の既定(center center)を上書きする。
363 364 365 366 367 368 369 370 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 363 def frontispiece_position_rule(settings, page_cfg) return '' if settings[:theme_style] == 'simple' offset = page_cfg[:frontispiece_binding_offset].to_s.strip return '' if offset.empty? || offset == '0mm' "@page :nth(1) { background-position: calc(50% + #{offset}) center; }" end |
.generate!(cfg = nil) ⇒ String?
book-settings.css を生成し、フォント準備と config.js 同期も行う。 プレフライト/フル/単章の全モードで 'prepare theme images' ステップから呼ばれる。
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 60 def generate!(cfg = nil) cfg ||= Common::CONFIG # --- Phase: CSS 全文を組み立てて書き出す --- css = render(cfg) path = output_path FileUtils.mkdir_p(File.dirname(path)) File.write(path, css, encoding: 'utf-8') # --- Phase: CSS 書換とは独立に必要な副作用(旧 update_all_css_files から引越し)--- ensure_fonts_available(cfg) Common.log_success('[Step 2] book-settings.css を生成しました') path rescue StandardError => e Common.log_warn("[Step 2] book-settings.css の生成に失敗: #{e.}") nil end |
.header_comment ⇒ Object
生成ファイル先頭の注意書き。
142 143 144 145 146 147 148 149 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 142 def header_comment <<~COMMENT.chomp /* 自動生成: config/book.yml のビルド設定(手編集しない) 生成器: VivlioStarter::CLI::PreProcessCommands::BookSettingsCss ソース CSS(stylesheets/*.css)は読み取り専用のテーマ資産。 設定変更は config/book.yml を編集すること。 */ COMMENT end |
.heading_metric_declarations(settings, page_cfg) ⇒ Object
================================================================
見出しの寸法(heading-metrics-spec §1-2)
著者は book.yml に「1 行の文字数」で書く。判型に追従する CSS の clamp() を calc() の中で掛け合わせると Vivliostyle が宣言ごと落とすため、 換算は生成時に行いリテラルで焼き込む(@page size・綴じオフセットと同型)。
章題・章リードは「箱幅」を、節題は「フォントサイズ」を決める——節絵の帯は 版面幅いっぱいで固定なので、箱を広げる余地が無く字送りで調整するしかない。
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 190 def heading_metric_declarations(settings, page_cfg) text_mm = text_area_width_mm(page_cfg) scale = paper_scale_of(page_cfg) lines = [] if (chars = settings[:heading_chars_value]) lines << "--frontispiece-heading-width: #{format_mm(chars * chapter_title_advance_mm(scale))};" warn_if_wider_than_text_area('theme.frontispiece.heading_chars', chars, chapter_title_advance_mm(scale), text_mm) end if (chars = settings[:lead_chars_value]) lines << "--frontispiece-lead-width: #{format_mm(chars * chapter_lead_advance_mm(page_cfg))};" warn_if_wider_than_text_area('theme.frontispiece.lead_chars', chars, chapter_lead_advance_mm(page_cfg), text_mm) end if (chars = settings[:ornament_heading_chars_value]) lines << "--section-title-font-size: #{section_title_font_q(chars, text_mm, scale)}Q;" end lines end |
.index_glossary_kindle_accent_rules(acc, colbg) ⇒ Object
索引・用語集は章と別の HTML(UnifiedPageBuilder 生成)で body クラスも異なるため、 上の body.vs-kindle 規則では届かない罫線・見出し色を個別に literalize する。
579 580 581 582 583 584 585 586 587 588 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 579 def index_glossary_kindle_accent_rules(acc, colbg) [ "body.vs-kindle .index h1 { border-bottom-color: #{acc}; }", "body.vs-kindle .index-section h2 { color: #{acc}; border-bottom-color: #{acc}; }", "body.vs-kindle .glossary-title { border-bottom-color: #{acc}; }", "body.vs-kindle .glossary-group-header { color: #{acc}; border-left-color: #{acc}; " \ "background: linear-gradient(90deg, #{colbg} 0%, transparent 100%); }", "body.vs-kindle .glossary-h4 { color: #{acc}; }" ] end |
.kindle_accent_rules(cfg) ⇒ Object
================================================================
Kindle 用テーマ色リテラル(kindle-theme-color-literalize-spec.md)
KFX は var()/color-mix()/calc() を解さないため、テーマ色で塗った本文アクセント (strong・下線・見出しマーカー・コラム/注記枠・付録見出し)が Kindle では黒/グレー/ くすんだ金へ劣化する。book-settings.css は最後に読まれるので、ここへテーマ色を リテラル hex で焼いた body.vs-kindle 規則を出せば、静的な #888/#b8860b フォールバックを 後勝ちで上書きできる。body.vs-kindle 前置のためクリーン EPUB では不発(無害)。
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 520 def kindle_accent_rules(cfg) theme_cfg = cfg.theme acc = ThemeColor.to_hex6(theme_cfg.color) colbg = ThemeColor.mix_with_white(acc, 0.15) apx = appendix_accent_hex6(theme_cfg, acc) # 付録色がテーマ色と同一なら付録専用の上書きは不要(既定構成は両方 yellow)。 lines = base_kindle_accent_rules(acc, colbg) lines += appendix_kindle_accent_rules(apx) unless apx == acc # 前書き/後書き(preface.css)の accent は preface_color 由来。preface 固有要素のため常に出す。 lines += preface_kindle_accent_rules(preface_accent_hex6(theme_cfg, acc)) <<~CSS.chomp /* Kindle 用テーマ色リテラル(KFX は var()/color-mix 非対応・最後に読まれ静的フォールバックを上書き) */ #{lines.join("\n")} CSS end |
.marker_declarations(cfg) ⇒ Object
見出しマーカー(旧 update_chapter_common_css 相当)。未指定時は ♣ / ♦。
327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 327 def marker_declarations(cfg) markers = FrontmatterGenerator.safe_config_hash(cfg.theme.markers) h3 = (markers[:h3] || markers['h3']).to_s h4 = (markers[:h4] || markers['h4']).to_s h3 = '♣' if h3.strip.empty? h4 = '♦' if h4.strip.empty? [ %(--h3-marker: "#{escape_marker(h3)}";), %(--h4-marker: "#{escape_marker(h4)}";) ] end |
.output_path ⇒ Object
生成ファイルのパス(.cache/vs/book-settings.css)。
50 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 50 def output_path = File.join(Common::CACHE_DIR, 'book-settings.css') |
.page_declarations(page_cfg) ⇒ Object
page-settings 系 22 変数(旧 update_page_settings_css 相当)。 nil/空値は宣言しない(page-settings.css の既定がカスケードで生きる)。
341 342 343 344 345 346 347 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 341 def page_declarations(page_cfg) CssUpdater.build_css_variable_mappings(page_cfg).filter_map do |name, val, kind| next if val.nil? || val.to_s.strip.empty? "#{name}: #{CssUpdater.format_font_value(name, val.to_s.strip, kind)};" end end |
.page_size_rule(page_cfg) ⇒ Object
width/height が空なら @page 規則自体を出さない。
351 352 353 354 355 356 357 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 351 def page_size_rule(page_cfg) w = page_cfg[:width].to_s.strip h = page_cfg[:height].to_s.strip return '' if w.empty? || h.empty? "@page { size: #{w} #{h}; }" end |
.paper_scale_of(page_cfg) ⇒ Object
build_page_cfg が算出済みの値を使う(同じ計算を 2 度しない)
284 285 286 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 284 def paper_scale_of(page_cfg) (page_cfg[:paper_scale] || 1.0).to_f end |
.preface_accent_hex6(theme_cfg, theme_hex) ⇒ Object
前書き/後書きアクセントのリテラル hex。preface_color 未指定時はテーマ色へフォールバック (supplemental_color_declarations が --color-preface-accent を常に fallback: accent で宣言する のと一致=PDF/クリーン EPUB のカスケードと揃える。appendix の yellow 既定とは異なる)。
551 552 553 554 555 556 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 551 def preface_accent_hex6(theme_cfg, theme_hex) raw = theme_cfg.preface_color return theme_hex if raw.to_s.strip.empty? ThemeColor.to_hex6(raw, fallback: theme_hex) end |
.preface_kindle_accent_rules(pref) ⇒ Object
前書き(body.preface)/ 後書き(body.postface。postface.css が preface.css を import)の accent 規則。preface.css は h1 下線・h2/引用の左罫・リンク色を var(--color-preface-accent) で 塗るが KFX で全滅する(h1 下線だけ静的 #4f46e5 フォールバックがあるがテーマ非追従)。 book-settings.css は全ページ共通のため body.preface / body.postface で必ずスコープする (裸の h1/h2 規則を出すと本文章へ波及する)。論理プロパティは避け物理で書く。
616 617 618 619 620 621 622 623 624 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 616 def preface_kindle_accent_rules(pref) scopes = %w[body.preface.vs-kindle body.postface.vs-kindle] [ selector_group(scopes, 'h1') + " { border-bottom-color: #{pref}; }", selector_group(scopes, 'h2') + " { border-left: 3px solid #{pref}; }", selector_group(scopes, 'blockquote') + " { border-left: 3px solid #{pref}; }", selector_group(scopes, 'a') + " { color: #{pref}; border-bottom: 1px dotted #{pref}; }" ] end |
.rebase_relative(path, image_prefix:) ⇒ Object
stylesheets/ 基準の相対パスを image_prefix で組み替える。 外部 URL・data URI・絶対パスは対象外。二重組替を避ける冪等ガード付き。 theme-images/… は生成バリアントのキャッシュ参照で、既に生成ファイル位置 (.cache/vs/)基準のため組み替えない(generated-assets 移設仕様 §3.1)。
729 730 731 732 733 734 735 736 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 729 def rebase_relative(path, image_prefix:) p = path.to_s.strip return p if p.empty? return p if p.start_with?('data:', 'http://', 'https://', '/') return p if p.start_with?(image_prefix, 'theme-images/') "#{image_prefix}#{p}" end |
.render(cfg = Common::CONFIG, image_prefix: CACHE_TO_STYLESHEETS) ⇒ String
生成する CSS 全文を組み立てる(副作用なし・テスト対象)。
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 83 def render(cfg = Common::CONFIG, image_prefix: CACHE_TO_STYLESHEETS) settings = FrontmatterGenerator.parse_theme_settings(cfg) page_cfg = build_page_cfg(cfg) registry = TalkRegistry.load root_lines = [] root_lines.concat(theme_declarations(settings, image_prefix:, page_cfg:)) root_lines.concat(supplemental_color_declarations(settings, cfg)) root_lines.concat(marker_declarations(cfg)) root_lines.concat(page_declarations(page_cfg)) root_lines.concat(talk_variable_declarations(registry)) <<~CSS #{header_comment} #{page_size_rule(page_cfg)} #{frontispiece_position_rule(settings, page_cfg)} :root { #{root_lines.map { " #{it}" }.join("\n")} } #{section_pagebreak_rule(page_cfg)} #{chapter_pagebreak_rule(page_cfg)} #{font_synthesis_rules(cfg)} #{kindle_accent_rules(cfg)} #{talk_class_rules(registry)} CSS end |
.section_pagebreak_disabled?(page_cfg) ⇒ Boolean
明示的に false と書かれたときだけ「節で改ページしない」と解釈する。 未設定・空欄は既定の true(現行挙動)を保つため、truthy? の裏返しではない。
427 428 429 430 431 432 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 427 def section_pagebreak_disabled?(page_cfg) case page_cfg[:section_pagebreak]&.to_s&.strip&.downcase in 'false' | 'no' | 'off' | '0' then true else false end end |
.section_pagebreak_rule(page_cfg) ⇒ Object
page.section_pagebreak: false のときだけ打ち消し規則を出す。 true・未設定では何も出さず、テーマ CSS の改ページがそのまま生きる (P3 の「書かない条件では宣言しない」セマンティクス)。 打ち消しだけでは章扉に最初の節が流れ込むため、章扉の保護を続けて出す。
かつては「節絵の箱が固定 150px 行からはみ出して直前の本文に重なる」是正も ここで出していたが、heading-metrics-spec §3・§4 で image-header.css 側の 行を実寸(auto)にしたため不要になった(はみ出し自体が消えた)。
393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 393 def section_pagebreak_rule(page_cfg) return '' unless section_pagebreak_disabled?(page_cfg) <<~CSS.chomp /* page.section_pagebreak: false — 節(h2)でページを改めない。 Kindle KFX 向けの legacy page-break-before も併せて打ち消す。 */ #{SECTION_PAGEBREAK_SELECTORS.join(",\n")} { break-before: auto; page-break-before: auto; } #{chapter_frontispiece_guard_rule} CSS end |
.section_title_font_q(chars, text_mm, scale) ⇒ Object
265 266 267 268 269 270 271 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 265 def section_title_font_q(chars, text_mm, scale) avail = text_mm - section_title_ornament_padding_mm(scale) return 36 unless avail.positive? q = (avail * SECTION_TITLE_HEADROOM / chars) / 0.25 format_number(q.clamp(SECTION_TITLE_FONT_Q_RANGE.begin, SECTION_TITLE_FONT_Q_RANGE.end)) end |
.section_title_ornament_padding_mm(scale) ⇒ Object
飾り避けの合計(mm)。CSS と同じ式で求める。
かつては 34.0mm の固定値だった——padding-inline の基準値 16 + 18 で、
これは A4(--paper-scale が 1.0)のときの値。CSS 側は用紙比で縮むため、
B5 では実際 29.4mm しか使われず、Ruby が 4.6mm 広く見積もることで
字送りが小さくなり、1 行に 14.6 字入る余裕が偶然生まれていた。
A4 では見積もりが一致して余裕ゼロになり、25 字の節題が 2 行に収まらず
3 行へ落ちた(実測 2026-08-10)。「判型が大きいほど溢れやすい」という
直感に反する挙動の正体がこれ。
259 260 261 262 263 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 259 def section_title_ornament_padding_mm(scale) [SECTION_TITLE_PADDING_LEFT_MM, SECTION_TITLE_PADDING_RIGHT_MM].sum do (scale * it[:base]).clamp(it[:min], it[:base]) end end |
.selector_group(scopes, element) ⇒ Object
複数スコープ × 要素をカンマ区切りのセレクタ群にする("a b, c b")。
627 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 627 def selector_group(scopes, element) = scopes.map { "#{it} #{element}" }.join(', ') |
.supplemental_color_declarations(settings, cfg) ⇒ Object
appendix / preface のアクセント色(旧 update_appendix_css / update_preface_css 相当)。
- appendix_color 未指定なら宣言しない(appendix.css の既定がカスケードで生きる)
- preface は常に宣言(未指定時は theme accent へフォールバック)
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 310 def supplemental_color_declarations(settings, cfg) theme_cfg = cfg.theme accent = settings[:theme_accent_value] lines = [] appendix_color = theme_cfg.appendix_color unless appendix_color.to_s.strip.empty? value = CssUpdater.normalize_color_value(appendix_color, fallback: accent) lines << "--appendix-accent-color: #{value};" end preface_value = CssUpdater.normalize_color_value(theme_cfg.preface_color, fallback: accent) lines << "--color-preface-accent: #{preface_value};" lines end |
.talk_class_rules(registry) ⇒ Object
.talk-c-
Kindle は会話文を inline 形式(名前+区切り+発話の 1 段落)へ組み替えるため
(talk-display-options-spec.md §2.5)、焼くのは話者名・区切り・発話内 strong の 3 つ。
吹き出しの枠線は Kindle には存在しないのでリテラル化しない。
strong は base_kindle_accent_rules の body.vs-kindle strong(テーマ色・特異度 0,1,2)
に落ちてしまうため話者色で塗り直す。セレクタは (0,2,2) でその既定に勝つ。
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 652 def talk_class_rules(registry) chars = registry.with_color return '' if chars.empty? lines = chars.flat_map do |char| hex = ThemeColor.to_hex6(char.color) [ ".talk-c-#{char.key} { --talk-accent: var(--talk-c-#{char.key}); }", "body.vs-kindle .talk-c-#{char.key} .talk-name { color: #{hex}; }", "body.vs-kindle .talk-c-#{char.key} .talk-sep { color: #{hex}; }", "body.vs-kindle .talk-c-#{char.key} strong { color: #{hex}; }" ] end <<~CSS.chomp /* 会話文キャラクター色(KFX は var() 不可のため Kindle 用は hex リテラル) */ #{lines.join("\n")} CSS end |
.talk_variable_declarations(registry) ⇒ Object
:root に置く --talk-c-
637 638 639 640 641 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 637 def talk_variable_declarations(registry) registry.with_color.map do |char| "--talk-c-#{char.key}: #{CssUpdater.normalize_color_value(char.color)};" end end |
.text_area_width_mm(page_cfg) ⇒ Object
版面幅(mm)= 紙幅 − ノド − 小口。導けないときは A4 標準相当へ。
274 275 276 277 278 279 280 281 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 274 def text_area_width_mm(page_cfg) width = Units.length_to_mm(page_cfg[:width]) inner = Units.length_to_mm(page_cfg[:margin_inner]) outer = Units.length_to_mm(page_cfg[:margin_outer]) return 162.0 unless width&.positive? && inner && outer [width - inner - outer, 1.0].max end |
.theme_declarations(settings, image_prefix:, page_cfg: {}) ⇒ Object
================================================================
theme 系変数(旧 update_theme_css 相当)
条件付き宣言のセマンティクスを in-place 版と一致させる(調査報告 §7.3-2):
- simple スタイル: 画像 2 変数は none、frontispiece-edge-inset は宣言しない
- image スタイル : 画像 2 変数+edge_inset を宣言
- 見出しの寸法は文字数指定がある時だけ宣言(theme.css の既定が生きる)
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 158 def theme_declarations(settings, image_prefix:, page_cfg: {}) lines = [ "--theme-accent: #{settings[:theme_accent_value]};", '--color-strong: var(--theme-accent);', '--color-em-underline: var(--theme-accent);' ] if settings[:theme_style] == 'simple' lines << '--section-bg-image: none;' lines << '--frontispiece-image: none;' else lines << "--section-bg-image: #{css_image_value(settings[:ornament_path], image_prefix:)};" lines << "--frontispiece-image: #{css_image_value(settings[:frontispiece_path], image_prefix:)};" lines << "--frontispiece-edge-inset: #{settings[:edge_inset_value]};" end if settings[:heading_offset_value] lines << "--frontispiece-heading-offset: #{settings[:heading_offset_value]};" end lines.concat(heading_metric_declarations(settings, page_cfg)) end |
.url_inner(value) ⇒ Object
url("...") / url('...') / url(...) の内側を取り出す。url() でなければそのまま返す。
717 718 719 720 721 722 723 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 717 def url_inner(value) if (m = value.match(/\Aurl\(\s*["']?(.*?)["']?\s*\)\z/i)) m[1] else value end end |
.warn_if_wider_than_text_area(label, chars, advance_mm, text_mm) ⇒ Object
版面に収まらない文字数指定は 🟡 で具体的な上限を示す(warning-messages の方針)。
289 290 291 292 293 294 295 296 297 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 289 def warn_if_wider_than_text_area(label, chars, advance_mm, text_mm) return if advance_mm <= 0 || chars * advance_mm <= text_mm fits = (text_mm / advance_mm).floor Common.log_warn( "#{label}: #{chars} は版面幅 #{format_mm(text_mm)} に収まりません(最大 #{fits} 文字)", detail: "#{label.split('.').last}: #{fits} をお試しください" ) end |
.warn_unknown_chapter_pagebreak!(page_cfg) ⇒ Object
綴り間違いが黙って既定へ戻ると著者は気づけないので知らせる。鳴らすのは CSS 生成の 1 回だけ(generate! はビルド Step 2 で必ず通る唯一の接続先)。
499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/vivlio_starter/cli/pre_process/book_settings_css.rb', line 499 def warn_unknown_chapter_pagebreak!(page_cfg) raw = page_cfg[:chapter_pagebreak].to_s.strip return if raw.empty? || CHAPTER_PAGEBREAK_VALUES.include?(raw.downcase) Common.log_warn( "config/book.yml の page.chapter_pagebreak の値が不正です(#{raw})\n" \ " 使える値: #{CHAPTER_PAGEBREAK_VALUES.join(' / ')}\n" \ " before: chapter_pagebreak: #{raw}\n" \ " after : chapter_pagebreak: #{DEFAULT_CHAPTER_PAGEBREAK}\n" \ " 今回は既定の #{DEFAULT_CHAPTER_PAGEBREAK} で処理しました。" ) end |