Facturx.Embed (Facturx v0.7.0)

Copy Markdown View Source

Embed CII XML into an existing PDF/A to produce a Factur-X PDF (pure Elixir).

Uses an incremental update: the original bytes are preserved verbatim (fonts, OutputIntent, content streams stay untouched) and only a small set of objects is appended — the embedded-file stream, its /Filespec, an overridden catalog (adds /AF + the EmbeddedFiles name tree) and an overridden /Metadata (the promoted XMP).

Input contract

The base PDF must already be PDF/A-2 or PDF/A-3 (see ADR 0001):

  • PDF/A-3 → embed as-is;
  • PDF/A-2 → embed and promote pdfaid:part 2 → 3 (levels A-2 and A-3 share identical conformance requirements bar the embedded-file allowance);
  • PDF/A-1 or a non-PDF/A file → refused. No external normaliser (Ghostscript) is ever invoked.

Writes the cross-reference back in the form the base uses — a classic table and trailer, or a PDF 1.5+ cross-reference stream — and never mixes the two: a table appended to a stream-based document is what a strict reader is entitled to reject. A catalog compressed inside an object stream is read from there and rewritten at top level, which is what an incremental update means.

Summary

Functions

embed(pdf, xml, opts \\ [])

@spec embed(binary(), binary(), keyword()) :: {:ok, binary()} | {:error, term()}

Embed xml into pdf.

Options:

  • :filename — embedded file name (default "factur-x.xml")
  • :profile — Factur-X profile for the XMP ConformanceLevel (default :en16931)