PDF information and metadata
View SourceNativeElixirPdfUtilities.Info reads document information and page geometry
from existing PDF binaries. It can also update common information fields
without rebuilding the document.
alias NativeElixirPdfUtilities.Info
{:ok, information} = Info.get(pdf)
information.title
information.author
information.subject
information.keywords
information.producer
information.creation_date
information.modification_dateEvery key is present in the returned map. A missing field has the value nil.
The text decoder accepts PDFDocEncoding and Unicode information strings. PDF
dates become NaiveDateTime values. A PDF date's timezone suffix is validated,
but the returned value retains the document's wall-clock time.
Page count and geometry
Use page_count/1 for the validated page-tree count:
{:ok, 3} = Info.page_count(pdf)page_sizes/1 returns one entry per page. It resolves inherited MediaBox and
rotation values, normalizes rotation to 0, 90, 180, or 270, and reports
dimensions in PDF points. Width and height reflect the normalized rotation.
The page's UserUnit scales width and height into physical PDF points. Direct
and indirectly referenced positive numeric values are supported; an omitted
value defaults to 1. The returned media_box coordinates remain in the
page's default user-space units before scaling. For example, a 100 x 200
MediaBox with UserUnit: 2 and rotation 90 reports width 400 and height
200, while retaining the original MediaBox coordinates. Invalid UserUnit
values return a diagnostic identifying the page.
{:ok, pages} = Info.page_sizes(pdf)
[
%{
page_number: 1,
width: 841.89,
height: 595.28,
unit: :point,
rotation: 90,
media_box: %{
left: 0.0,
bottom: 0.0,
right: 595.28,
top: 841.89
}
}
] = pagesEncryption status
encrypted?/1 validates the PDF header, cross-reference chain, and active
trailer before checking for encryption. It does not load or decrypt encrypted
objects.
case Info.encrypted?(pdf) do
{:ok, false} -> Info.get(pdf)
{:ok, true} -> {:error, :encrypted_document}
{:error, {_reason, diagnostic}} -> {:error, diagnostic}
endThe other Info operations reject encrypted documents because the library does
not decrypt PDF content.
Updating information
put/2 accepts a map or keyword list. Omitted fields remain unchanged and
nil removes a field. Keywords may be a string or a list of strings.
{:ok, updated_pdf} =
Info.put(pdf,
title: "August statement",
author: "Finance Operations",
subject: "Customer statement",
keywords: ["statement", "monthly"],
producer: "Accounts service",
modification_date: DateTime.utc_now()
)Supported date inputs are Date, NaiveDateTime, DateTime, ISO 8601 strings,
and valid PDF date strings. Text must be valid UTF-8. Unknown fields and invalid
values return the shared diagnostic tuple.
An update appends an incremental revision. The original bytes remain at the start of the result, and the writer preserves unspecified common fields, unknown information dictionary entries, the document root, and the permanent trailer identifier. An empty patch returns the original binary unchanged.
When the active trailer has an ID pair, an incremental update preserves its
first, permanent identifier and refreshes its second, revision identifier.
A malformed pair returns :invalid_pdf_input at :incremental_write. An
absent ID remains absent. Outline updates use the same identifier handling.
The API updates the PDF information dictionary only. It does not read or write XMP metadata, decrypt documents, add signatures, or guarantee that an existing signature remains valid after an update.
Supported inputs and limits
Information operations use the shared PDF reader and support its classic cross-reference tables, cross-reference streams, object streams, hybrid files, and incremental revisions. Malformed, unsupported, encrypted, or oversized inputs return:
{:error, {reason, diagnostic}}Metadata update values are bounded by max_pdf_info_value_bytes per value and
max_pdf_info_total_bytes in total. Reader input, object, page, reference, and
revision limits apply to every information operation. See Configurable resource
limits and Diagnostics.