Module: Typstify::Adapter

Defined in:
lib/typstify/adapter.rb

Overview

The only file in this gem that knows the typst binding exists.

Everything upstream might rename — the constructor shape, the option names, how compiled bytes come back — is contained here, so a binding release breaks one file instead of five. Verified against typst 0.15.1.5.

Constant Summary collapse

BINDING_ERROR =

The binding surfaces compile failures as ArgumentError, carrying the same codespan-formatted diagnostic the CLI prints.

ArgumentError

Class Method Summary collapse

Class Method Details

.compile_pdf(main_path:, root:, template:, config: Typstify.config) ⇒ String

Returns PDF bytes, ASCII-8BIT.

Parameters:

  • main_path (Pathname)

    the workspace's main.typ

  • root (Pathname)

    the workspace; Typst's sandbox boundary

  • template (String)

    the name to show in errors

  • config (Typstify::Config) (defaults to: Typstify.config)

    supplies the fonts and the PDF standard

Returns:

  • (String)

    PDF bytes, ASCII-8BIT



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/typstify/adapter.rb', line 23

def compile_pdf(main_path:, root:, template:, config: Typstify.config)
  document = Typst(
    main_path.to_s,
    root: root.to_s,
    font_paths: config.font_paths.map(&:to_s),
    ignore_system_fonts: config.ignore_system_fonts,
    pdf_standards: config.pdf_standards
  ).compile(:pdf)

  # PdfDocument#bytes is a per-page array of integer arrays; #pages packs
  # each one. A PDF is always a single "page" here — the whole document.
  document.pages.first.to_s.b
rescue BINDING_ERROR => e
  raise translate(e, root: root, template: template, config: config)
end

.translate(error, root:, template:, config:) ⇒ Object

Turn the binding's flat diagnostic blob into a CompileError that names the developer's template rather than a tmpdir, and surface any warnings that came along with it through the on_warning hook.



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/typstify/adapter.rb', line 42

def translate(error, root:, template:, config:)
  readable = Warnings.rewrite_paths(error.message, root, template)
  diagnostics = Warnings.parse(readable)
  Warnings.dispatch(diagnostics, template, config)

  first = diagnostics.find { |d| d.severity == :error }
  CompileError.new(
    template: template,
    typst_message: readable.strip,
    line: first&.line,
    column: first&.column
  )
end