import_pages/import_pages.rs
1// PDFium-rs -- Modern Rust interface to PDFium, the PDF library from Google
2//
3// Copyright (c) 2025 Martin van der Werff <github (at) newinnovations.nl>
4//
5// This file is part of PDFium-rs.
6//
7// PDFium-rs is free software: you can redistribute it and/or modify it under the terms of
8// the GNU General Public License as published by the Free Software Foundation, either version 3
9// of the License, or (at your option) any later version.
10//
11// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
12// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
13// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
15// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
16// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20// Import all necessary items from the pdfium crate
21// This gives us access to PdfiumDocument and related functionality
22use pdfium::*;
23
24/// Demonstrates importing PDF pages using string-based page specification.
25///
26/// This function shows how to:
27/// - Create a new empty PDF document
28/// - Load an existing PDF file as a source
29/// - Import specific pages using a human-readable string format
30/// - Save the resulting document to disk
31/// - Verify the operation was successful
32///
33/// The string format supports:
34/// - Individual pages: "5" (imports page 5)
35/// - Multiple pages: "1,3,7" (imports pages 1, 3, and 7)
36/// - Page ranges: "10-15" (imports pages 10 through 15 inclusive)
37/// - Mixed format: "1,5-8,12" (imports page 1, pages 5-8, and page 12)
38///
39/// Note: Page numbers in the string are 1-based (human-readable format)
40pub fn example_import_pages() -> PdfiumResult<()> {
41 // Create a new, empty PDF document that will serve as our destination
42 // This document starts with 0 pages and we'll add pages to it
43 let document = PdfiumDocument::new()?;
44
45 // Load the source PDF document from which we'll extract pages
46 // The second parameter (None) means we're not providing a password
47 let src_doc = PdfiumDocument::new_from_path("resources/pg1342-images-3.pdf", None)?;
48
49 // Import specific pages from the source document into our destination document
50 // Parameters breakdown:
51 // - &src_doc: Reference to the source document to import from
52 // - "12,14,30-34": String specifying which pages to import
53 // * Page 12 (individual page)
54 // * Page 14 (individual page)
55 // * Pages 30-34 (range of 5 pages: 30, 31, 32, 33, 34)
56 // * Total: 7 pages will be imported
57 // - 0: Index position where imported pages should be inserted
58 // * 0 means insert at the beginning of the destination document
59 // * If the destination had existing pages, imported pages would be inserted before them
60 document.pages().import(&src_doc, "12,14,30-34", 0)?;
61
62 // Save the destination document with imported pages to a new file
63 // The second parameter (None) indicates we're not specifying a version
64 document.save_to_path("pride-1.pdf", None)?;
65
66 // Verification step: reload the saved document to confirm the operation
67 let document = PdfiumDocument::new_from_path("pride-1.pdf", None)?;
68
69 // Get the total number of pages in the saved document
70 let page_count = document.page_count();
71
72 // Assert that we have exactly 7 pages as expected
73 // This confirms that all specified pages were imported correctly:
74 // 1 page (12) + 1 page (14) + 5 pages (30-34) = 7 pages total
75 assert_eq!(page_count, 7);
76
77 Ok(())
78}
79
80/// Demonstrates importing PDF pages using index-based page specification.
81///
82/// This function shows an alternative approach to page importing using
83/// explicit page indices rather than string specifications. This method
84/// provides more programmatic control and is useful when:
85/// - You have a dynamically generated list of page numbers
86/// - You need to import non-contiguous pages with complex patterns
87/// - You're working with 0-based indexing in your application logic
88///
89/// Key differences from string-based approach:
90/// - Uses 0-based indexing (first page is index 0)
91/// - Requires explicit specification of each page index
92/// - More verbose but offers precise control
93/// - Better for programmatic generation of page lists
94pub fn example_import_pages_by_index() -> PdfiumResult<()> {
95 // Create a new, empty PDF document to serve as our destination
96 let document = PdfiumDocument::new()?;
97
98 // Load the same source PDF document as in the previous example
99 // We're extracting the same pages but using a different method
100 let src_doc = PdfiumDocument::new_from_path("resources/pg1342-images-3.pdf", None)?;
101
102 // Import pages using explicit 0-based indices
103 // Parameters breakdown:
104 // - &src_doc: Reference to the source document
105 // - Some(&[11, 13, 29, 30, 31, 32, 33]): Vector of 0-based page indices
106 // * Index 11 = Page 12 in human numbering (11 + 1 = 12)
107 // * Index 13 = Page 14 in human numbering (13 + 1 = 14)
108 // * Indices 29-33 = Pages 30-34 in human numbering
109 // * Note: This matches exactly the same pages as "12,14,30-34" from the previous example
110 // * The Some() wrapper indicates we're providing a specific list of indices
111 // * Using None instead would import all pages from the source document
112 // - 0: Insertion position (beginning of destination document)
113 document
114 .pages()
115 .import_by_index(&src_doc, Some(&[11, 13, 29, 30, 31, 32, 33]), 0)?;
116
117 // Save the document with a different filename to distinguish from the first example
118 // Even though the content should be identical, using different names helps with testing
119 document.save_to_path("pride-2.pdf", None)?;
120
121 // Verification: reload the saved document to ensure it was created correctly
122 let document = PdfiumDocument::new_from_path("pride-2.pdf", None)?;
123
124 // Count the pages in the saved document
125 let page_count = document.page_count();
126
127 // Verify that we have the same 7 pages as the string-based method
128 // This confirms both methods produce identical results:
129 // - 1 page at index 11 (page 12)
130 // - 1 page at index 13 (page 14)
131 // - 5 pages at indices 29-33 (pages 30-34)
132 // Total: 7 pages
133 assert_eq!(page_count, 7);
134
135 Ok(())
136}
137
138fn main() -> PdfiumResult<()> {
139 example_import_pages()?;
140 example_import_pages_by_index()?;
141 Ok(())
142}