Class: VivlioStarter::CLI::BuildCommands::DirectBuild
- Inherits:
-
Object
- Object
- VivlioStarter::CLI::BuildCommands::DirectBuild
- Defined in:
- lib/vivlio_starter/cli/build/direct_build.rb
Overview
設定ファイルを経由しない単一 Markdown の PDF 化
Defined Under Namespace
Classes: PipelineCommand
Constant Summary collapse
- WORKSPACE_PREFIX =
'vs-direct-'- FIXED_THEME_STYLE =
扉絵・節絵を使わない simple 固定(spec §1.2)。既定色は yellow。
'simple'- DEFAULT_THEME_COLOR =
'yellow'- FALLBACK_NUMBER =
章番号を持たない(または本章の範囲外の)原稿へ割り当てる番号と slug。 01–89 は本章の範囲であり、10 はその中庸。
'10'- FALLBACK_SLUG =
'document'- FONTS_DIR =
stylesheets 配下で唯一ビルドが書き込む生成物(FontManager が更新し page-settings.css が @import する)。ワークスペース側の実体コピーへ逃がす対象。
'fonts'- GOOGLE_FONTS_DIR =
'google'- GOOGLE_FONTS_BUNDLE =
'google-fonts.css'- PACKAGE_JSON =
生成 config が ESM(import 文)のため、ワークスペースにも type: module が要る。
%({\n "name": "vs-direct",\n "private": true,\n "type": "module"\n}\n)- LOCAL_IMAGE_PATTERN =
画像記法のローカル参照(URL・data: は除外)
%r{!\[[^\]]*\]\((?!https?://|data:)([^)\s]+)\)}
Instance Method Summary collapse
-
#basename ⇒ Object
ワークスペース内の章 basename(NN-slug)。 01–89 の番号付きファイルだけ番号を保ち、それ以外(番号なし・00・90–99)は 10 に付け替える=常に本章扱い(spec §1.1)。.
-
#call ⇒ Integer
終了コード.
-
#initialize(source, theme: nil) ⇒ DirectBuild
constructor
A new instance of DirectBuild.
-
#source_name ⇒ Object
出力 PDF 名・タイトルの既定に使う元ファイル名(拡張子なし).
-
#title ⇒ Object
PDF のタイトル。先頭の
# 見出しを拾い、無ければファイル名。 フロントマターを除いたうえで Masking に地の文だけを走査させる (コードフェンス中の# コメントを拾わないため)。.
Constructor Details
#initialize(source, theme: nil) ⇒ DirectBuild
Returns a new instance of DirectBuild.
77 78 79 80 81 |
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 77 def initialize(source, theme: nil) # ワークスペースへ chdir した後も同じファイルを指せるよう絶対パスで保持する @source = File.(source.to_s) @theme = theme end |
Instance Method Details
#basename ⇒ Object
ワークスペース内の章 basename(NN-slug)。 01–89 の番号付きファイルだけ番号を保ち、それ以外(番号なし・00・90–99)は 10 に付け替える=常に本章扱い(spec §1.1)。
113 114 115 116 117 118 119 120 |
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 113 def basename @basename ||= begin number, slug = source_name.match(/\A(\d+)[-_](.+)\z/)&.captures number = format('%02d', number.to_i) if number number = FALLBACK_NUMBER unless number && (1..89).cover?(number.to_i) "#{number}-#{sanitize_slug(slug || source_name)}" end end |
#call ⇒ Integer
Returns 終了コード.
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/build/direct_build.rb', line 84 def call # ensure で必ず復帰させるため、いかなる早期 return よりも先に退避する saved_config = Common::CONFIG workspace = nil return 1 unless valid_theme? started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) workspace = Dir.mktmpdir(WORKSPACE_PREFIX) # --- Phase: 最小プロジェクトを組み立て、その中で :single パイプラインを回す --- prepare_workspace!(workspace) Dir.chdir(workspace) do Common.install_configuration!(direct_configuration) run_pipeline end # --- Phase: 成果物を呼び出し元へ回収する(CONFIG は PdfOpener のため未復帰)--- # 所要時間はワークスペース組み立てを含む実時間。フル/単章ビルドが集計する # 「パイプライン各ステップの合計」に対し、直接ビルドは組み立て・画像同伴・回収も # 著者の待ち時間なので、それらを含めて 1 つの数字で示す。 deliver(Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at) ensure Common.install_configuration!(saved_config) discard(workspace) end |
#source_name ⇒ Object
出力 PDF 名・タイトルの既定に使う元ファイル名(拡張子なし)
140 |
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 140 def source_name = File.basename(source, '.md') |
#title ⇒ Object
PDF のタイトル。先頭の # 見出し を拾い、無ければファイル名。
フロントマターを除いたうえで Masking に地の文だけを走査させる
(コードフェンス中の # コメント を拾わないため)。
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 125 def title @title ||= begin body = File.read(source, encoding: 'utf-8').sub(/\A---\r?\n.*?^---\r?\n/m, '') found = nil Masking.each_prose_line(body) do |line, _lineno| next unless (m = line.match(/\A\#[ \t]+(.+)/)) found = m[1].strip break end found.to_s.empty? ? source_name : found end end |