A handle to one page of a PdfElixide.Document.
A %Page{} is just its document and a zero-based :index — it holds no
native resource of its own, which is why there is no Page.close/1 and why
building one costs nothing. It stays valid exactly as long as its document
does: closing the document makes every page handle taken from it report
{:error, %PdfElixide.Error{reason: :closed}}.
Get one from PdfElixide.Document.page/2, all of them from
PdfElixide.Document.pages/1, or iterate the document directly — it
implements Enumerable over its pages:
for page <- doc, do: PdfElixide.Document.Page.text!(page)Every extractor PdfElixide.Document offers is available here for a single
page, taking the same options, except PdfElixide.Document.running_regions/2,
which compares pages and so needs the whole document. The comprehension above
collects every page's result. To bound memory used by results, consume pages
without accumulating
their results — see the streaming example and handle-release guidance in the
"Whole-document extraction and memory" section of PdfElixide.Document.
A page whose :index is not a page of the document — only reachable from a
hand-built %Page{} — yields
%PdfElixide.Error{reason: :out_of_range} from every function here.
Summary
Page properties
Returns the page's /CropBox — the region a viewer displays and prints — as
a normalized PdfElixide.Geometry.Rect in unrotated user space. It is
inherited and reported unclipped, on the same terms as media_box/1.
Same as crop_box/1 but raises an error if it fails.
Returns whether the page carries a text layer, as opposed to being image-only or blank.
Same as has_text_layer/1 but returns the bare boolean, raising on failure.
Returns the page's height in points.
Same as height/1 but raises an error if it fails.
Lists the Separation and DeviceN ink names the page declares.
Same as inks/2 but raises an error if it fails.
Returns the page's logical page label (e.g. "i", "1", "A-1").
Same as label/1 but raises an error if it fails.
Returns the page's /MediaBox — the sheet it is imposed on — as a
PdfElixide.Geometry.Rect in unrotated user space.
Same as media_box/1 but raises an error if it fails.
Returns the page's /Rotate — the clockwise rotation a viewer applies when
displaying it — as 0, 90, 180 or 270.
Same as rotation/1 but raises an error if it fails.
Returns the page's visible region — its /CropBox intersected with its
/MediaBox — as a normalized PdfElixide.Geometry.Rect in unrotated user
space.
Same as visible_box/1 but raises an error if it fails.
Returns the page's width in points.
Same as width/1 but raises an error if it fails.
Text extraction
Extracts the characters of the page, each with its bounding box, font metadata, and typographic placement.
Same as chars/2 but raises an error if it fails.
Extracts the spans of the page, each a run of text sharing one text state.
Same as spans/2 but raises an error if it fails.
Reads the page as a PdfElixide.Document.StructuredPage containing typed
regions.
Same as structured/2 but raises an error if it fails.
Detects the tables of the page.
Same as tables/2 but raises an error if it fails.
Extracts the text content of the page.
Same as text/2 but raises an error if it fails.
Extracts the text lines of the page, each with its bounding box and words.
Same as text_lines/2 but raises an error if it fails.
Converts the page to plain text.
Same as to_plain_text/2 but raises an error if it fails.
Extracts the words of the page, each with its bounding box and font metadata.
Same as words/2 but raises an error if it fails.
Conversion
Converts the page to an HTML fragment.
Same as to_html/2 but raises an error if it fails.
Converts the page to Markdown.
Same as to_markdown/2 but raises an error if it fails.
Graphics, images and annotations
Reads the annotations on the page.
Same as annotations/1 but raises an error if it fails.
Extracts the fonts referenced by the page.
Same as fonts/1 but raises an error if it fails.
Extracts the raster images of the page — photos, logos, and scanned pictures.
Same as images/1 but raises an error if it fails.
Extracts the straight lines of the page.
Same as lines/1 but raises an error if it fails.
Extracts the vector paths of the page — lines, curves, rectangles, and shapes.
Same as paths/1 but raises an error if it fails.
Extracts the rectangles of the page.
Same as rects/1 but raises an error if it fails.
Search
Finds every occurrence of pattern on the page.
Same as search/3 but raises an error if it fails.
Rendering
Renders the page to a raster image.
Same as render/2 but raises an error if it fails.
Renders a single named ink's plate for the page.
Same as separation/3 but raises an error if it fails.
Renders one grayscale plate per ink on the page: the process inks and the page's spot inks, painted or not.
Same as separations/2 but raises an error if it fails.
Page properties
@spec crop_box(t()) :: {:ok, PdfElixide.Geometry.Rect.t() | nil} | {:error, PdfElixide.Error.t()}
Returns the page's /CropBox — the region a viewer displays and prints — as
a normalized PdfElixide.Geometry.Rect in unrotated user space. It is
inherited and reported unclipped, on the same terms as media_box/1.
Returns nil when the box is absent or null. A box whose entry is not an
array, or is an array of fewer than four elements, yields
%PdfElixide.Error{reason: :invalid_pdf}; as with media_box/1, an element
that is not a number is not reported and reads as 0.0.
The box is reported as declared, so it may extend past the sheet. Extraction
stops at the two intersected — visible_box/1 — not at this box. See What
the crop box hides from
extraction
for what that frame omits.
@spec crop_box!(t()) :: PdfElixide.Geometry.Rect.t() | nil
Same as crop_box/1 but raises an error if it fails.
@spec has_text_layer(t()) :: {:ok, boolean()} | {:error, PdfElixide.Error.t()}
Returns whether the page carries a text layer, as opposed to being image-only or blank.
This is the signal text/1 cannot give: an empty string means "no text was
extracted", which a scanned page and a genuinely blank page produce alike.
A false here says the page has nothing to extract, so a caller can route it
to OCR instead of treating the empty result as content.
It is a static probe, not an extraction — no text is assembled and no
fonts are loaded — and it approximates towards true, so the two answers are
not equally strong:
falseis reliable. The page declares no fonts and no form XObjects, or its content stream shows no text and invokes no XObject.trueis not a promise thattext/1returns anything. A page whose only XObject holds no text still answerstrue, and so does a page whose content stream cannot be decoded.
One asymmetry is worth knowing: a page with no fonts whose sole XObject is
an image answers false. Text drawn in invisible render mode (Tr 3) is
not considered either way.
Same as has_text_layer/1 but returns the bare boolean, raising on failure.
Unlike PdfElixide.Document.has_structure_tree?/1 and
PdfElixide.Document.has_xfa?/1, this degrades nothing: every error raises,
not just a failure of the handle — see the "Errors versus exceptions" section
of PdfElixide.Error.
Sweep a document with it:
Enum.reject(doc, &PdfElixide.Document.Page.has_text_layer?/1)
@spec height(t()) :: {:ok, float()} | {:error, PdfElixide.Error.t()}
Returns the page's height in points.
This is media_box/1's :height, in unrotated user space, and like width/1
it is never negative and is not swapped for a rotated page. See rotation/1.
Same as height/1 but raises an error if it fails.
@spec inks(t(), PdfElixide.Document.inks_opts()) :: {:ok, [String.t()]} | {:error, PdfElixide.Error.t()}
Lists the Separation and DeviceN ink names the page declares.
These are the values :exclude_inks accepts. By default only the page's own
/Resources is read; PdfElixide.Document.inks/3 explains what that misses,
what :deep costs, and which colorants never appear.
@spec inks!(t(), PdfElixide.Document.inks_opts()) :: [String.t()]
Same as inks/2 but raises an error if it fails.
@spec label(t()) :: {:ok, String.t()} | {:error, PdfElixide.Error.t()}
Returns the page's logical page label (e.g. "i", "1", "A-1").
This is the human-facing page number the PDF may define, independent of the zero-based physical index. Pages outside any declared label range fall back to their decimal page number.
Every call re-reads the document's label ranges, so use
PdfElixide.Document.page_labels/1 to label a whole document.
Same as label/1 but raises an error if it fails.
@spec media_box(t()) :: {:ok, PdfElixide.Geometry.Rect.t()} | {:error, PdfElixide.Error.t()}
Returns the page's /MediaBox — the sheet it is imposed on — as a
PdfElixide.Geometry.Rect in unrotated user space.
The rect is normalized: :x and :y are the bottom-left corner and :width
and :height are non-negative, even for a file that writes the two corners in
the reverse order. It is not turned to match rotation/1. See Page boxes and
the coordinate
origin for
inherited boxes, non-zero origins and the coordinate frame.
A page with no /MediaBox anywhere above it, or whose entry is not an array,
or is an array of fewer than four elements, is malformed and yields
%PdfElixide.Error{reason: :invalid_pdf} — no default page size is
substituted. One malformation is not reported: an element that is not a
number reads as 0.0, so such a page reports a smaller box rather than
failing. See crop_box/1 for the part of the sheet a viewer shows.
@spec media_box!(t()) :: PdfElixide.Geometry.Rect.t()
Same as media_box/1 but raises an error if it fails.
@spec rotation(t()) :: {:ok, rotation()} | {:error, PdfElixide.Error.t()}
Returns the page's /Rotate — the clockwise rotation a viewer applies when
displaying it — as 0, 90, 180 or 270.
A page without /Rotate inherits it from the nearest ancestor that declares
one and otherwise reads as 0. See Which ancestor an inherited box comes
from for
the full inheritance behavior.
Two normalizations are worth knowing:
- a value outside
0..359wraps, so-90reads as270; - a value that is not a multiple of 90 is invalid per §7.7.3.3 and reads
as
0— it is not rounded down, so45is0, not90.
media_box/1, width/1 and height/1 are not swapped to match. Rotation
also affects the frame of some extracted bounding boxes; see Rotated pages
and extracted
geometry.
Same as rotation/1 but raises an error if it fails.
@spec visible_box(t()) :: {:ok, PdfElixide.Geometry.Rect.t()} | {:error, PdfElixide.Error.t()}
Returns the page's visible region — its /CropBox intersected with its
/MediaBox — as a normalized PdfElixide.Geometry.Rect in unrotated user
space.
Unlike crop_box/1 this always answers a box: the media box stands in
whenever the crop box is absent, null, written with fewer than four
elements, written with an element that is not a number, or leaves nothing
once intersected. Only an unreadable /MediaBox fails, with
%PdfElixide.Error{reason: :invalid_pdf}.
This is the frame text extraction stops at — see What the crop box hides from
extraction
for which extractors it bounds. It is not what render/1,2 draws: on a page
with a malformed /CropBox the two part. Measure a raster from the :width
and :height of the returned PdfElixide.Document.RenderedPage, and see
"What the raster covers" in the Rendering guide.
@spec visible_box!(t()) :: PdfElixide.Geometry.Rect.t()
Same as visible_box/1 but raises an error if it fails.
@spec width(t()) :: {:ok, float()} | {:error, PdfElixide.Error.t()}
Returns the page's width in points.
This is media_box/1's :width, in unrotated user space. Like it, the value
is never negative and is not swapped for a rotated page: a page with
rotation/1 of 90 or 270 displays as height × width. See rotation/1.
Same as width/1 but raises an error if it fails.
Text extraction
@spec chars(t(), PdfElixide.Document.chars_opts()) :: {:ok, [PdfElixide.Document.Char.t()]} | {:error, PdfElixide.Error.t()}
Extracts the characters of the page, each with its bounding box, font metadata, and typographic placement.
See PdfElixide.Document.chars_opts/0 for the available options.
@spec chars!(t(), PdfElixide.Document.chars_opts()) :: [PdfElixide.Document.Char.t()]
Same as chars/2 but raises an error if it fails.
@spec spans(t(), PdfElixide.Document.spans_opts()) :: {:ok, [PdfElixide.Document.Span.t()]} | {:error, PdfElixide.Error.t()}
Extracts the spans of the page, each a run of text sharing one text state.
See PdfElixide.Document.spans_opts/0 for the available options.
@spec spans!(t(), PdfElixide.Document.spans_opts()) :: [PdfElixide.Document.Span.t()]
Same as spans/2 but raises an error if it fails.
@spec structured(t(), PdfElixide.Document.structured_opts()) :: {:ok, PdfElixide.Document.StructuredPage.t()} | {:error, PdfElixide.Error.t()}
Reads the page as a PdfElixide.Document.StructuredPage containing typed
regions.
See PdfElixide.Document.structured_opts/0 for the available options.
@spec structured!(t(), PdfElixide.Document.structured_opts()) :: PdfElixide.Document.StructuredPage.t()
Same as structured/2 but raises an error if it fails.
@spec tables(t(), PdfElixide.Document.tables_opts()) :: {:ok, [PdfElixide.Document.Table.t()]} | {:error, PdfElixide.Error.t()}
Detects the tables of the page.
Returns {:ok, []} when the page has no detectable table. See
PdfElixide.Document.tables_opts/0 for the available options.
@spec tables!(t(), PdfElixide.Document.tables_opts()) :: [ PdfElixide.Document.Table.t() ]
Same as tables/2 but raises an error if it fails.
@spec text(t(), PdfElixide.Document.page_text_opts()) :: {:ok, String.t()} | {:error, PdfElixide.Error.t()}
Extracts the text content of the page.
:on_page_error is a whole-document option of PdfElixide.Document.text/1;
passing it here raises ArgumentError.
See PdfElixide.Document.page_text_opts/0 for the available options, and
to_plain_text/2 for the other way to read a page as text.
@spec text!(t(), PdfElixide.Document.page_text_opts()) :: String.t()
Same as text/2 but raises an error if it fails.
@spec text_lines(t(), PdfElixide.Document.text_lines_opts()) :: {:ok, [PdfElixide.Document.TextLine.t()]} | {:error, PdfElixide.Error.t()}
Extracts the text lines of the page, each with its bounding box and words.
See PdfElixide.Document.text_lines_opts/0 for the available options.
@spec text_lines!(t(), PdfElixide.Document.text_lines_opts()) :: [ PdfElixide.Document.TextLine.t() ]
Same as text_lines/2 but raises an error if it fails.
@spec to_plain_text(t(), PdfElixide.Document.plain_text_opts()) :: {:ok, String.t()} | {:error, PdfElixide.Error.t()}
Converts the page to plain text.
A different assembler from text/2; see PdfElixide.Document.to_plain_text/2
for how the two differ. See PdfElixide.Document.plain_text_opts/0 for the
available options.
@spec to_plain_text!(t(), PdfElixide.Document.plain_text_opts()) :: String.t()
Same as to_plain_text/2 but raises an error if it fails.
@spec words(t(), PdfElixide.Document.words_opts()) :: {:ok, [PdfElixide.Document.Word.t()]} | {:error, PdfElixide.Error.t()}
Extracts the words of the page, each with its bounding box and font metadata.
See PdfElixide.Document.words_opts/0 for the available options.
@spec words!(t(), PdfElixide.Document.words_opts()) :: [PdfElixide.Document.Word.t()]
Same as words/2 but raises an error if it fails.
Conversion
@spec to_html(t(), PdfElixide.Document.html_opts()) :: {:ok, String.t()} | {:error, PdfElixide.Error.t()}
Converts the page to an HTML fragment.
See PdfElixide.Document.html_opts/0 for the available options.
@spec to_html!(t(), PdfElixide.Document.html_opts()) :: String.t()
Same as to_html/2 but raises an error if it fails.
@spec to_markdown(t(), PdfElixide.Document.markdown_opts()) :: {:ok, String.t()} | {:error, PdfElixide.Error.t()}
Converts the page to Markdown.
See PdfElixide.Document.markdown_opts/0 for the available options.
@spec to_markdown!(t(), PdfElixide.Document.markdown_opts()) :: String.t()
Same as to_markdown/2 but raises an error if it fails.
Graphics, images and annotations
@spec annotations(t()) :: {:ok, [PdfElixide.Document.Annotation.t()]} | {:error, PdfElixide.Error.t()}
Reads the annotations on the page.
Returns {:ok, []} when the page has no annotations.
@spec annotations!(t()) :: [PdfElixide.Document.Annotation.t()]
Same as annotations/1 but raises an error if it fails.
@spec fonts(t()) :: {:ok, [PdfElixide.Document.Font.t()]} | {:error, PdfElixide.Error.t()}
Extracts the fonts referenced by the page.
Returns {:ok, []} when the page references no fonts — and also when the page
or its /Resources could not be read, which PdfElixide.Document.fonts/2
explains.
@spec fonts!(t()) :: [PdfElixide.Document.Font.t()]
Same as fonts/1 but raises an error if it fails.
@spec images(t()) :: {:ok, [PdfElixide.Document.Image.t()]} | {:error, PdfElixide.Error.t()}
Extracts the raster images of the page — photos, logos, and scanned pictures.
Returns {:ok, []} when the page has no images — and also in the cases
PdfElixide.Document.images/2 explains, where an image is left out rather
than reported.
@spec images!(t()) :: [PdfElixide.Document.Image.t()]
Same as images/1 but raises an error if it fails.
@spec lines(t()) :: {:ok, [PdfElixide.Document.Path.t()]} | {:error, PdfElixide.Error.t()}
Extracts the straight lines of the page.
The paths of paths/1 narrowed to those classified as single straight
segments. Returns {:ok, []} when the page draws none. See the "Rectangles
and straight lines" section of PdfElixide.Document.Path for which shapes
qualify.
@spec lines!(t()) :: [PdfElixide.Document.Path.t()]
Same as lines/1 but raises an error if it fails.
@spec paths(t()) :: {:ok, [PdfElixide.Document.Path.t()]} | {:error, PdfElixide.Error.t()}
Extracts the vector paths of the page — lines, curves, rectangles, and shapes.
Returns {:ok, []} when the page has no vector graphics.
@spec paths!(t()) :: [PdfElixide.Document.Path.t()]
Same as paths/1 but raises an error if it fails.
@spec rects(t()) :: {:ok, [PdfElixide.Document.Path.t()]} | {:error, PdfElixide.Error.t()}
Extracts the rectangles of the page.
The paths of paths/1 narrowed to those classified as rectangles. Returns
{:ok, []} when the page draws none. See the "Rectangles and straight lines"
section of PdfElixide.Document.Path for which shapes qualify.
@spec rects!(t()) :: [PdfElixide.Document.Path.t()]
Same as rects/1 but raises an error if it fails.
Search
@spec search(t(), String.t(), PdfElixide.Document.search_opts()) :: {:ok, [PdfElixide.Document.SearchMatch.t()]} | {:error, PdfElixide.Error.t()}
Finds every occurrence of pattern on the page.
The pattern is plain text unless literal: false is given. See
PdfElixide.Document.search_opts/0 for the available options.
@spec search!(t(), String.t(), PdfElixide.Document.search_opts()) :: [ PdfElixide.Document.SearchMatch.t() ]
Same as search/3 but raises an error if it fails.
Rendering
@spec render(t(), PdfElixide.Document.render_opts()) :: {:ok, PdfElixide.Document.RenderedPage.t()} | {:error, PdfElixide.Error.t()}
Renders the page to a raster image.
See PdfElixide.Document.render/3 for what the raster covers and
PdfElixide.Document.render_opts/0 for resolution, format, background,
annotations and layer filtering.
rendered = PdfElixide.Document.Page.render!(page, fit: {240, 320})
File.write!("thumb.png", rendered.data)See the Rendering guide for rendering each page of a document.
@spec render!(t(), PdfElixide.Document.render_opts()) :: PdfElixide.Document.RenderedPage.t()
Same as render/2 but raises an error if it fails.
@spec separation(t(), String.t(), PdfElixide.Document.dpi_opts()) :: {:ok, PdfElixide.Document.SeparationPlate.t()} | {:error, PdfElixide.Error.t()}
Renders a single named ink's plate for the page.
See PdfElixide.Document.separation/4. An ink the page never paints yields
an all-zero plate.
@spec separation!(t(), String.t(), PdfElixide.Document.dpi_opts()) :: PdfElixide.Document.SeparationPlate.t()
Same as separation/3 but raises an error if it fails.
@spec separations(t(), PdfElixide.Document.dpi_opts()) :: {:ok, [PdfElixide.Document.SeparationPlate.t()]} | {:error, PdfElixide.Error.t()}
Renders one grayscale plate per ink on the page: the process inks and the page's spot inks, painted or not.
See PdfElixide.Document.separations/3 for which inks a page yields and
PdfElixide.Document.SeparationPlate for how to read a plate.
@spec separations!(t(), PdfElixide.Document.dpi_opts()) :: [ PdfElixide.Document.SeparationPlate.t() ]
Same as separations/2 but raises an error if it fails.
Types
@type rotation() :: 0 | 90 | 180 | 270
A page's clockwise display rotation in degrees — always one of these four.
@type t() :: %PdfElixide.Document.Page{ doc: PdfElixide.Document.t(), index: non_neg_integer() }