Repository navigation
Conversation
readPdf takes a pages option of zero-based page-tree indices, negative indices counting from the end. Only the selected pages' content streams are fetched, decoded and interpreted, so the fonts and images only unselected pages use are never resolved: reading a cover page or the last page of a large file no longer costs the memory of laying out every page. The selected pages come back in document order, each carrying its source position as index, with the page tree's length as pageCount; a full read sets neither. Document-level page references keep naming source indices, and sourcePageIndex resolves either shape. An empty selection reads no page. An entry naming no page throws PdfPageSelectionError before any page is read. Refs #1688
The pdfTo* conversions, convertDocument with a pdf source and readNativeDocumentTree/readContentDocument take a pages option, passed to readPdf, so only the selected pages are parsed, laid out and reconstructed. Every reconstruction now stamps frames, comment anchor keys and sheet names with the page's source index (sourcePageIndex) rather than its position, so they agree with the destinations and form widgets the layout already names by source index. A page-selected conversion's DocumentTree carries no pages envelope, since that array is indexed by frame page index and a selection cannot fill it. Markdown output of a page-selected conversion opens each page with its original one-based page number, written as <!-- page N --> beside the existing page-break marker. buildMarkdownText and renderContentDocumentToMarkdown take the same labels as pageNumbers for callers composing the stages themselves, and reading markdown back drops them. Refs #1688
Member
Author
|
Superseded by #1690, which rebuilds this change with one commit per package and folds in the review fixes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
readPdf(bytes, { pages: [0, 1, 2, -1] })now reads only the listed pages. Indices are zero-based into the page tree, a negative index counts from the end, duplicates collapse, and the result comes back in document order whatever order the selection was written in. Each returned page carries its source position asindex, and the document carries the page tree's length aspageCount. A full read sets neither, so its output is unchanged. An index that names no page (out of range, or not an integer) throwsPdfPageSelectionError, aPdfParseErrorwith codepdf/page-out-of-rangeorpdf/page-index-not-integerthat carriespageIndexandpageCount, before any page is read. An empty selection is valid and reads no page, which makes it the cheapest way to get the page count and metadata.Unselected pages are skipped before
readPage, which is the only path that fetches/Contents, decodes and interprets it, and resolves the fonts and images a page uses. Objects are resolved lazily, so none of that work happens for pages that were not asked for. The page tree is still walked in full, and the document-level readers still cover the whole file. That is cheap: they read the catalog plus page and annotation dictionaries, never content streams (attachments look at every page's/Annotsfor/FileAttachment, and the structure tree maps every page's/StructParents). Document-level references (destinations, outline, form widgets, structure, page-boxes residue) keep naming source indices.sourcePageIndex(page, position)resolves either shape.In documents.js the
pagesoption is threaded throughPdfToDocumentOptions,UnifiedConversionOptions(used only by the fromPdf hop) andReadNativeDocumentTreeOptions. Reconstructions previously used each page's position inlayout.pagesas its page index. They now use the source index for frames, comment anchor keys (pdf-annot-{page}-{n}) and sheet names, which keeps them in agreement with the form widgets and destinations that already used source indices. Without this, a form widget on a selected page would have been matched against the wrong page. A page-selected conversion'sDocumentTreeleaves out thepagesenvelope, because that array is indexed by frame page index and a selection can't fill it.Page-selected Markdown opens each page with
<!-- page N -->, where N is the original one-based page number. The existing<!-- page break -->between pages is unchanged, so a consumer that already splits on it keeps working. A caller can read the label to see which pages it got. That matters because the conversion writes no break between pages that start different sections (different page sizes).buildMarkdownTextandrenderContentDocumentToMarkdowntake the same labels aspageNumbersfor callers that composereadPdf,reconstructWordprocessingand the writer themselves. A count mismatch throwsMarkdownPageNumberCountError, and reading the Markdown back drops the labels.For the memory claim,
read-page-selection.test.tswrapsinterpretContentStreamwith a pass-through spy. A selection of two pages out of four interprets exactly two content streams, and an empty selection interprets none. The fixture's unselected trap page has a content stream with an unknown filter: a full read reportspdf/unsupported-filter, while a selection that leaves that page out reports no diagnostics. An image drawn only by an unselected page never reachesimages. Selected pages are compared page for page against the same pages of a full read, withindexadded. Further tests cover negative indices, duplicates, the empty selection, out-of-range and non-integer indices, a zero-page file, and destinations keeping their source page. On the documents.js side, tests check the Markdown labels (including a page that starts its own section), source-index frames from all four reconstructors, comment keys that still pair with their definitions, the omitted tree envelope, and that the labels are dropped on read-back. I hand-mutated each piece of new logic (reading every page anyway, ignoring negative indices, droppingindex, skipping the range check, using position instead of source index in each reconstructor and in the comment keys, skipping section-start labels, ignoringcontinuous, keeping labels on read, zero-based labels, keeping the envelope), and in every case at least one test failed.Known limit:
writePdfplaces pages by position, so writing a page-selectedLayoutDocumentback out doesn't remap the source-index references. I've documented this. It's a reading of part of a file, not a document to re-emit.Refs #1688