Class: VivlioStarter::CLI::BuildCommands::DirectBuild

Inherits:
Object
  • Object
show all
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

Constructor Details

#initialize(source, theme: nil) ⇒ DirectBuild

Returns a new instance of DirectBuild.

Parameters:

  • source (String)

    入力 Markdown のパス(呼び出し元 cwd 基準)

  • theme (String, nil) (defaults to: nil)

    --theme の値(省略時 yellow)



77
78
79
80
81
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 77

def initialize(source, theme: nil)
  # ワークスペースへ chdir した後も同じファイルを指せるよう絶対パスで保持する
  @source = File.expand_path(source.to_s)
  @theme = theme
end

Instance Method Details

#basenameObject

ワークスペース内の章 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

#callInteger

Returns 終了コード.

Returns:

  • (Integer)

    終了コード



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_nameObject

出力 PDF 名・タイトルの既定に使う元ファイル名(拡張子なし)



140
# File 'lib/vivlio_starter/cli/build/direct_build.rb', line 140

def source_name = File.basename(source, '.md')

#titleObject

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