Module: VivlioStarter::CLI::Build::QpdfOverlay
- Defined in:
- lib/vivlio_starter/cli/build/qpdf_overlay.rb
Constant Summary collapse
- SCALING_BOXES =
等倍重畳の妨げになるページボックス(MediaBox 以外)
%w[/TrimBox /BleedBox /CropBox /ArtBox].freeze
Class Method Summary collapse
-
.apply!(target_pdf, overlay_pdf, repeat: false) ⇒ Boolean
overlay_pdf の内容を target_pdf へ等倍で重畳する。.
-
.attach_boxes!(pdf_path, saved_boxes) ⇒ Object
控えたページボックスを書き戻す.
-
.detach_scaling_boxes!(pdf_path) ⇒ Array<Hash>?
MediaBox 以外のページボックスを取り除き、ページ順に控えを返す。 退避すべきボックスが無ければ PDF に触れず空配列を返す(高速パス)。.
-
.overlay!(target_pdf, overlay_pdf, repeat:) ⇒ Object
qpdf --overlay 本体.
Class Method Details
.apply!(target_pdf, overlay_pdf, repeat: false) ⇒ Boolean
overlay_pdf の内容を target_pdf へ等倍で重畳する。
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/vivlio_starter/cli/build/qpdf_overlay.rb', line 40 def apply!(target_pdf, , repeat: false) return false unless File.exist?(target_pdf) && File.exist?() # --- Phase: 等倍で重なるようページボックスを退避 --- saved_boxes = detach_scaling_boxes!(target_pdf) return false if saved_boxes.nil? # --- Phase: 重畳 --- success = (target_pdf, , repeat:) # --- Phase: ページボックスの復帰(重畳でオブジェクト ID が動くため再走査する) --- success && attach_boxes!(target_pdf, saved_boxes) end |
.attach_boxes!(pdf_path, saved_boxes) ⇒ Object
控えたページボックスを書き戻す
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/vivlio_starter/cli/build/qpdf_overlay.rb', line 77 def attach_boxes!(pdf_path, saved_boxes) return true if saved_boxes.all?(&:empty?) header, objects, pages = QpdfJson.read(pdf_path) return false unless pages updates = pages.each_with_index.to_h do |page, index| value = objects["obj:#{page['object']}"]['value'].merge(saved_boxes[index] || {}) ["obj:#{page['object']}", { 'value' => value }] end QpdfJson.apply!(pdf_path, header, updates) end |
.detach_scaling_boxes!(pdf_path) ⇒ Array<Hash>?
MediaBox 以外のページボックスを取り除き、ページ順に控えを返す。 退避すべきボックスが無ければ PDF に触れず空配列を返す(高速パス)。
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/vivlio_starter/cli/build/qpdf_overlay.rb', line 58 def detach_scaling_boxes!(pdf_path) header, objects, pages = QpdfJson.read(pdf_path) return nil unless pages saved = pages.map do |page| value = objects["obj:#{page['object']}"]['value'] value.slice(*SCALING_BOXES) end return saved if saved.all?(&:empty?) updates = pages.each_with_index.to_h do |page, index| value = objects["obj:#{page['object']}"]['value'].reject { |key, _| saved[index].key?(key) } ["obj:#{page['object']}", { 'value' => value }] end QpdfJson.apply!(pdf_path, header, updates) ? saved : nil end |
.overlay!(target_pdf, overlay_pdf, repeat:) ⇒ Object
qpdf --overlay 本体
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/vivlio_starter/cli/build/qpdf_overlay.rb', line 92 def (target_pdf, , repeat:) overlaid = "#{target_pdf}.overlay.tmp.pdf" page_args = repeat ? ['--from=', '--repeat=1'] : ['--to=1-z', '--from=1-z'] success = system('qpdf', target_pdf, overlaid, '--overlay', , *page_args, '--', out: File::NULL, err: File::NULL) if success && File.exist?(overlaid) FileUtils.mv(overlaid, target_pdf) true else FileUtils.rm_f(overlaid) Common.log_warn('[qpdf] --overlay による重畳に失敗しました') false end end |