Class: Vivlio::PDF::Printer

Inherits:
Object
  • Object
show all
Defined in:
lib/vivlio/pdf/printer.rb

Overview

Renders documents to PDF through a browser running the Vivliostyle Viewer.

A Printer owns one browser instance. Reuse it across conversions and close it when done, or use the block form which closes it for you:

Vivlio::PDF::Printer.open do |printer|
printer.print(source: 'a.html', output: 'a.pdf')
printer.print(source: 'b.html', output: 'b.pdf')
end

Defined Under Namespace

Classes: Rendering

Constant Summary collapse

DEFAULT_TIMEOUT =
300
DEFAULT_PROCESS_TIMEOUT =

How long to wait for Chrome to boot and report its websocket URL. This is Ferrum's :process_timeout, separate from :timeout above -- the latter bounds rendering, this one bounds startup. Ferrum defaults it to 10s, which a loaded CI runner occasionally overruns; 30s absorbs that.

30
BROWSER_OPTIONS =

Chromium refuses XHR against file:// without this, and the viewer fetches the source document that way. Build-tool usage only.

{ 'allow-file-access-from-files' => nil }.freeze
SETUP_OPTIONS =

The optional keywords of .new and of #print: the option surface Vivlio::PDF.print routes and validates against. Spelled out rather than derived from the signatures, because these are public API and a parameter rename should not quietly become an API change. A unit test fails if either signature drifts away from its list.

%i[viewer browser_path timeout process_timeout].freeze
%i[outline metadata book_mode style].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(viewer: nil, browser_path: nil, timeout: DEFAULT_TIMEOUT, process_timeout: DEFAULT_PROCESS_TIMEOUT) ⇒ Printer

Returns a new instance of Printer.



53
54
55
56
57
58
59
# File 'lib/vivlio/pdf/printer.rb', line 53

def initialize(viewer: nil, browser_path: nil, timeout: DEFAULT_TIMEOUT,
               process_timeout: DEFAULT_PROCESS_TIMEOUT)
  @viewer = Viewer.coerce(viewer)
  @timeout = timeout
  @process_timeout = process_timeout
  @browser_path = browser_path
end

Instance Attribute Details

#timeoutObject (readonly)

Returns the value of attribute timeout.



40
41
42
# File 'lib/vivlio/pdf/printer.rb', line 40

def timeout
  @timeout
end

#viewerObject (readonly)

Returns the value of attribute viewer.



40
41
42
# File 'lib/vivlio/pdf/printer.rb', line 40

def viewer
  @viewer
end

Class Method Details

.open(**options) ⇒ Object



42
43
44
45
46
47
48
49
50
51
# File 'lib/vivlio/pdf/printer.rb', line 42

def self.open(**options)
  printer = new(**options)
  return printer unless block_given?

  begin
    yield printer
  ensure
    printer.close
  end
end

Instance Method Details

#browserObject



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/vivlio/pdf/printer.rb', line 77

def browser
  @browser ||= PDF.translate_browser_errors do
    Ferrum::Browser.new(
      headless: true,
      timeout: @timeout,
      process_timeout: @process_timeout,
      browser_path: @browser_path,
      browser_options: BROWSER_OPTIONS
    )
  end
end

#closeObject



89
90
91
92
# File 'lib/vivlio/pdf/printer.rb', line 89

def close
  PDF.translate_browser_errors { @browser&.quit }
  @browser = nil
end

Renders source and writes a PDF to output, returning a Result.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/vivlio/pdf/printer.rb', line 62

def print(source:, output:, outline: :toc, metadata: nil, book_mode: nil, style: nil)
  source = Source.coerce(source)
  strategy = Outline.resolve(outline)
   = Metadata.coerce()
  book_mode = source.publication? if book_mode.nil?
  url = @viewer.url_for(source, book_mode: book_mode, style: style)

  StagedFile.write(output) do |staged|
    rendering = render(url, strategy, staged)
    pages, bookmarks = finalize(staged, metadata: , entries: rendering.entries)
    Result.new(path: output, pages: pages, bookmarks: bookmarks,
               outline: rendering.entries, warnings: rendering.warnings)
  end
end