pub struct PdfDocument<R: Read + Seek> { /* private fields */ }Expand description
High-level PDF document interface for parsing and manipulation.
PdfDocument provides a clean, safe API for working with PDF files.
It handles the complexity of PDF structure, object references, and resource
management behind a simple interface.
§Type Parameter
R- The reader type (must implement Read + Seek)
§Architecture Benefits
- RefCell Usage: Allows multiple parts of the API to access the document
- Lazy Loading: Pages and resources are loaded on demand
- Automatic Caching: Frequently accessed objects are cached
- Safe API: Borrow checker issues are handled internally
§Example
use oxidize_pdf::parser::{PdfDocument, PdfReader};
use std::fs::File;
// From a file
let reader = PdfReader::open("document.pdf")?;
let document = PdfDocument::new(reader);
// From any Read + Seek source
let file = File::open("document.pdf")?;
let reader = PdfReader::new(file)?;
let document = PdfDocument::new(reader);
// Use the document
let page_count = document.page_count()?;
for i in 0..page_count {
let page = document.get_page(i)?;
// Process page...
}Implementations§
Source§impl<R: Read + Seek> PdfDocument<R>
impl<R: Read + Seek> PdfDocument<R>
Sourcepub fn version(&self) -> ParseResult<String>
pub fn version(&self) -> ParseResult<String>
Sourcepub fn options(&self) -> ParseOptions
pub fn options(&self) -> ParseOptions
Get the parse options
Sourcepub fn page_count(&self) -> ParseResult<u32>
pub fn page_count(&self) -> ParseResult<u32>
Get the total number of pages in the document.
§Returns
The page count as an unsigned 32-bit integer.
§Errors
Returns an error if the page tree is malformed or missing.
§Example
let count = document.page_count()?;
println!("Document has {} pages", count);
// Iterate through all pages
for i in 0..count {
let page = document.get_page(i)?;
// Process page...
}Sourcepub fn metadata(&self) -> ParseResult<DocumentMetadata>
pub fn metadata(&self) -> ParseResult<DocumentMetadata>
Get document metadata including title, author, creation date, etc.
Metadata is cached after first access for performance.
§Returns
A DocumentMetadata struct containing all available metadata fields.
§Example
let metadata = document.metadata()?;
if let Some(title) = &metadata.title {
println!("Title: {}", title);
}
if let Some(author) = &metadata.author {
println!("Author: {}", author);
}
if let Some(creation_date) = &metadata.creation_date {
println!("Created: {}", creation_date);
}
println!("PDF Version: {}", metadata.version);Sourcepub fn get_page(&self, index: u32) -> ParseResult<ParsedPage>
pub fn get_page(&self, index: u32) -> ParseResult<ParsedPage>
Get a page by index (0-based).
Pages are cached after first access. This method handles page tree traversal and property inheritance automatically.
§Arguments
index- Zero-based page index (0 to page_count-1)
§Returns
A complete ParsedPage with all properties and inherited resources.
§Errors
Returns an error if:
- Index is out of bounds
- Page tree is malformed
- Required page properties are missing
§Example
// Get the first page
let page = document.get_page(0)?;
// Access page properties
println!("Page size: {}x{} points", page.width(), page.height());
println!("Rotation: {}°", page.rotation);
// Get content streams
let streams = page.content_streams_with_document(&document)?;
println!("Page has {} content streams", streams.len());Sourcepub fn get_object(&self, obj_num: u32, gen_num: u16) -> ParseResult<PdfObject>
pub fn get_object(&self, obj_num: u32, gen_num: u16) -> ParseResult<PdfObject>
Get an object by its reference numbers.
This method first checks the cache, then loads from the file if needed. Objects are automatically cached after loading.
§Arguments
obj_num- Object numbergen_num- Generation number
§Returns
The resolved PDF object.
§Errors
Returns an error if:
- Object doesn’t exist
- Object is part of an encrypted object stream
- File is corrupted
§Example
// Get object 10 0 R
let obj = document.get_object(10, 0)?;
// Check object type
match obj {
PdfObject::Dictionary(dict) => {
println!("Object is a dictionary with {} entries", dict.0.len());
}
PdfObject::Stream(stream) => {
println!("Object is a stream");
}
_ => {}
}Sourcepub fn resolve(&self, obj: &PdfObject) -> ParseResult<PdfObject>
pub fn resolve(&self, obj: &PdfObject) -> ParseResult<PdfObject>
Resolve a reference to get the actual object.
If the input is a Reference, fetches the referenced object. Otherwise returns a clone of the input object.
§Arguments
obj- The object to resolve (may be a Reference or direct object)
§Returns
The resolved object (never a Reference).
§Example
// Contents might be a reference or direct object
if let Some(contents) = page.dict.get("Contents") {
let resolved = document.resolve(contents)?;
match resolved {
PdfObject::Stream(_) => println!("Single content stream"),
PdfObject::Array(_) => println!("Multiple content streams"),
_ => println!("Unexpected content type"),
}
}Sourcepub fn get_page_resources<'a>(
&self,
page: &'a ParsedPage,
) -> ParseResult<Option<&'a PdfDictionary>>
pub fn get_page_resources<'a>( &self, page: &'a ParsedPage, ) -> ParseResult<Option<&'a PdfDictionary>>
Get content streams for a specific page.
This method handles both single streams and arrays of streams, automatically decompressing them according to their filters.
§Arguments
page- The page to get content streams from
§Returns
Vector of decompressed content stream data ready for parsing.
§Example
let page = document.get_page(0)?;
let streams = document.get_page_content_streams(&page)?;
// Parse content streams
for stream_data in streams {
let operations = ContentParser::parse(&stream_data)?;
println!("Stream has {} operations", operations.len());
}Get page resources dictionary.
This method returns the resources dictionary for a page, which may include fonts, images (XObjects), patterns, color spaces, and other resources.
§Arguments
page- The page to get resources from
§Returns
Optional resources dictionary if the page has resources.
§Example
let page = document.get_page(0)?;
if let Some(resources) = document.get_page_resources(&page)? {
// Check for images (XObjects)
if let Some(PdfObject::Dictionary(xobjects)) = resources.0.get(&PdfName("XObject".to_string())) {
for (name, _) in xobjects.0.iter() {
println!("Found XObject: {}", name.0);
}
}
}pub fn get_page_content_streams( &self, page: &ParsedPage, ) -> ParseResult<Vec<Vec<u8>>>
Sourcepub fn extract_text(&self) -> ParseResult<Vec<ExtractedText>>
pub fn extract_text(&self) -> ParseResult<Vec<ExtractedText>>
Extract text from all pages in the document.
Uses the default text extraction settings. For custom settings,
use extract_text_with_options.
§Returns
A vector of ExtractedText, one for each page in the document.
§Example
let extracted_pages = document.extract_text()?;
for (page_num, page_text) in extracted_pages.iter().enumerate() {
println!("=== Page {} ===", page_num + 1);
println!("{}", page_text.text);
println!();
}Sourcepub fn extract_text_from_page(
&self,
page_index: u32,
) -> ParseResult<ExtractedText>
pub fn extract_text_from_page( &self, page_index: u32, ) -> ParseResult<ExtractedText>
Extract text from a specific page.
§Arguments
page_index- Zero-based page index
§Returns
Extracted text with optional position information.
§Example
// Extract text from first page only
let page_text = document.extract_text_from_page(0)?;
println!("First page text: {}", page_text.text);
// Access text fragments with positions (if preserved)
for fragment in &page_text.fragments {
println!("'{}' at ({}, {})", fragment.text, fragment.x, fragment.y);
}Sourcepub fn extract_text_from_page_with_options(
&self,
page_index: u32,
options: ExtractionOptions,
) -> ParseResult<ExtractedText>
pub fn extract_text_from_page_with_options( &self, page_index: u32, options: ExtractionOptions, ) -> ParseResult<ExtractedText>
Extract text from a specific page with custom options.
This method combines the functionality of [extract_text_from_page] and
[extract_text_with_options], allowing fine control over extraction
behavior for a single page.
§Arguments
page_index- Zero-based page indexoptions- Text extraction configuration
§Returns
Extracted text with optional position information.
§Example
// Use higher space threshold for PDFs with micro-adjustments
let options = ExtractionOptions {
space_threshold: 0.4,
..Default::default()
};
let page_text = document.extract_text_from_page_with_options(0, options)?;
println!("Text: {}", page_text.text);Sourcepub fn extract_text_with_options(
&self,
options: ExtractionOptions,
) -> ParseResult<Vec<ExtractedText>>
pub fn extract_text_with_options( &self, options: ExtractionOptions, ) -> ParseResult<Vec<ExtractedText>>
Extract text with custom extraction options.
Allows fine control over text extraction behavior including layout preservation, spacing thresholds, and more.
§Arguments
options- Text extraction configuration
§Returns
A vector of ExtractedText, one for each page.
§Example
// Configure extraction to preserve layout
let options = ExtractionOptions {
preserve_layout: true,
space_threshold: 0.3,
newline_threshold: 10.0,
..Default::default()
};
let extracted_pages = document.extract_text_with_options(options)?;
// Text fragments will include position information
for page_text in extracted_pages {
for fragment in &page_text.fragments {
println!("{:?}", fragment);
}
}Sourcepub fn get_page_annotations(
&self,
page_index: u32,
) -> ParseResult<Vec<PdfDictionary>>
pub fn get_page_annotations( &self, page_index: u32, ) -> ParseResult<Vec<PdfDictionary>>
Get annotations from a specific page.
Returns a vector of annotation dictionaries for the specified page. Each annotation dictionary contains properties like Type, Rect, Contents, etc.
§Arguments
page_index- Zero-based page index
§Returns
A vector of PdfDictionary objects representing annotations, or an empty vector if the page has no annotations.
§Example
let annotations = document.get_page_annotations(0)?;
for annot in &annotations {
if let Some(contents) = annot.get("Contents").and_then(|c| c.as_string()) {
println!("Annotation: {:?}", contents);
}
}Sourcepub fn get_all_annotations(&self) -> ParseResult<Vec<(u32, Vec<PdfDictionary>)>>
pub fn get_all_annotations(&self) -> ParseResult<Vec<(u32, Vec<PdfDictionary>)>>
Get all annotations from all pages in the document.
Returns a vector of tuples containing (page_index, annotations) for each page that has annotations.
§Returns
A vector of tuples where the first element is the page index and the second is a vector of annotation dictionaries for that page.
§Example
let all_annotations = document.get_all_annotations()?;
for (page_idx, annotations) in all_annotations {
println!("Page {} has {} annotations", page_idx, annotations.len());
}Sourcepub fn to_markdown(&self) -> Result<String>
pub fn to_markdown(&self) -> Result<String>
Export the document to LLM-optimized Markdown format.
Delegates to crate::ai::export_to_markdown. Includes YAML frontmatter
with document metadata followed by extracted text content.
Sourcepub fn to_element_markdown(&self) -> ParseResult<String>
pub fn to_element_markdown(&self) -> ParseResult<String>
Export the document to element-aware Markdown format.
Unlike to_markdown, this method classifies elements
by type and maps each to its canonical Markdown representation.
Sourcepub fn to_contextual(&self) -> Result<String>
pub fn to_contextual(&self) -> Result<String>
Export the document to a contextual text format for LLM consumption.
Delegates to crate::ai::export_to_contextual.
Sourcepub fn chunk(&self, target_tokens: usize) -> Result<Vec<DocumentChunk>>
pub fn chunk(&self, target_tokens: usize) -> Result<Vec<DocumentChunk>>
Split the document text into chunks of approximately target_tokens size.
Uses a default overlap of 10% of the target token count.
Sourcepub fn chunk_with(
&self,
target_tokens: usize,
overlap: usize,
) -> Result<Vec<DocumentChunk>>
pub fn chunk_with( &self, target_tokens: usize, overlap: usize, ) -> Result<Vec<DocumentChunk>>
Split the document text into chunks with explicit size and overlap control.
Sourcepub fn partition(&self) -> ParseResult<Vec<Element>>
pub fn partition(&self) -> ParseResult<Vec<Element>>
Partition the document into typed elements using default configuration.
Extracts text with layout preservation, then classifies fragments into
Element variants (Title, Paragraph, Table, etc.).
Sourcepub fn partition_with(
&self,
config: PartitionConfig,
) -> ParseResult<Vec<Element>>
pub fn partition_with( &self, config: PartitionConfig, ) -> ParseResult<Vec<Element>>
Partition the document into typed elements with custom configuration.
Sourcepub fn partition_with_profile(
&self,
profile: ExtractionProfile,
) -> ParseResult<Vec<Element>>
pub fn partition_with_profile( &self, profile: ExtractionProfile, ) -> ParseResult<Vec<Element>>
Partition the document using a pre-configured extraction profile.
Source§impl PdfDocument<File>
impl PdfDocument<File>
Sourcepub fn open<P: AsRef<Path>>(path: P) -> ParseResult<Self>
pub fn open<P: AsRef<Path>>(path: P) -> ParseResult<Self>
Open a PDF file by path — the simplest way to start working with a PDF.
This is a convenience method that combines PdfReader::open() and
PdfDocument::new() into a single call.
§Example
use oxidize_pdf::parser::PdfDocument;
let doc = PdfDocument::open("report.pdf").unwrap();
let text = doc.extract_text().unwrap();
let markdown = doc.to_markdown().unwrap();Auto Trait Implementations§
impl<R> !Freeze for PdfDocument<R>
impl<R> !RefUnwindSafe for PdfDocument<R>
impl<R> !Send for PdfDocument<R>
impl<R> !Sync for PdfDocument<R>
impl<R> Unpin for PdfDocument<R>where
R: Unpin,
impl<R> UnsafeUnpin for PdfDocument<R>where
R: UnsafeUnpin,
impl<R> !UnwindSafe for PdfDocument<R>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more