Print-quality PDF from Markdown + Elixir, powered by Typst.
use Folio
content = ~MD""
# Report
Some **bold** content with $x^2$ math.
""
{:ok, pdf} = Folio.to_pdf(content)Styles
{:ok, pdf} = Folio.to_pdf("Hello", styles: [
Folio.Styles.page_size(width: 595, height: 842),
Folio.Styles.font_family(["Helvetica"]),
])Document pipeline
doc =
Folio.Document.new()
|> Folio.Document.attach_file("logo.png", File.read!("logo.png"))
|> Folio.Document.add_style(Folio.Styles.page_numbering("1"))
|> Folio.Document.add_content("# Hello\n\nWorld")
{:ok, pdf} = Folio.to_pdf(doc)File management
For one-off files, use register_file/2. For session-scoped isolation,
use Folio.Document.attach_file/3 — files live only within that document.
Summary
Functions
Imports Folio.DSL and Folio.Sigil.
Parse markdown into content nodes.
Parse markdown into content nodes, raising on error.
Register a file globally for use in documents (images, bibliography, etc).
Compile to PDF bytes.
Compile to PNG images (one per page).
Compile to SVG strings (one per page).
Unregister a previously registered global file, freeing its memory.
Types
@type compile_result(result) :: {:ok, result} | {:error, Folio.CompileError.t()}
@type source() :: String.t() | [Folio.Content.t()] | Folio.Document.t()
Functions
Imports Folio.DSL and Folio.Sigil.
@spec parse_markdown(String.t()) :: {:ok, [Folio.Content.t()]} | {:error, Folio.ParseError.t()}
Parse markdown into content nodes.
{:ok, nodes} = Folio.parse_markdown("# Hello\n\nWorld")Returns {:error, Folio.ParseError.t()} on failure.
@spec parse_markdown!(String.t()) :: [Folio.Content.t()]
Parse markdown into content nodes, raising on error.
nodes = Folio.parse_markdown!("# Hello\n\nWorld")Raises Folio.ParseError on failure.
Register a file globally for use in documents (images, bibliography, etc).
Files registered here are shared across all compile calls for the
lifetime of the BEAM VM. For session-scoped isolation, prefer
Folio.Document.attach_file/3 instead.
@spec to_pdf( source(), keyword() ) :: compile_result(binary())
Compile to PDF bytes.
Accepts markdown strings, content node lists, or Folio.Document structs.
{:ok, pdf} = Folio.to_pdf("# Hello")
{:ok, pdf} = Folio.to_pdf(doc)
@spec to_png( source(), keyword() ) :: compile_result([binary()])
Compile to PNG images (one per page).
Each page is rendered and encoded independently so peak memory is proportional to the largest page, not the total page count.
{:ok, [page1_png, page2_png]} = Folio.to_png("# Hello")
{:ok, pngs} = Folio.to_png("# Hello", dpi: 3.0)Options:
:dpi— render scale factor (default:2.0).1.0= 72 DPI,2.0= 144 DPI,3.0= 216 DPI.
@spec to_svg( source(), keyword() ) :: compile_result([String.t()])
Compile to SVG strings (one per page).
{:ok, [page1_svg, page2_svg]} = Folio.to_svg("# Hello")
@spec unregister_file(String.t()) :: :ok
Unregister a previously registered global file, freeing its memory.
Folio.unregister_file("chart.png")