Introduction

Every capability in Aspose.PDF FOSS for TypeScript is reached through two classes: Document and Page. Document owns the page collection and everything document-scoped — metadata, bookmarks, page labels, and save/load — while each Page in doc.Pages owns everything scoped to that one page: content, annotations, and form fields. Once those two classes are familiar, the rest of the library’s surface — conversion, annotations, forms, security — is really just more methods on the same two objects.

This post is a closer look at the parts of that core surface the introductory post only mentions in passing: assembling documents out of other documents, building pages from nothing, adding a bookmark tree for navigation, and tagging content for accessibility. All four are plain method calls — no separate module to import, no extra dependency beyond the @asposefoss/pdf package itself.

These are the operations that come up once a PDF pipeline moves past “open one file, change it, save it”: combining reports from several sources into one document, generating pages programmatically instead of starting from a template, and making the output navigable and accessible rather than just visually correct.


What’s Included

Assembling and Reorganizing Documents

Document.Split() breaks a document into one new single-page Document per page, in page order. Document.ExtractPages() copies a given set of 1-based page numbers into a new self-contained Document, in the order given — the same page can be repeated. Pages from one document can also be copied into another: Document.Append() copies every page of a source document onto the end of the target, and Document.InsertPage() copies a single page across documents at a specific 1-based position.

import { Document } from '@asposefoss/pdf';

const report = Document.OpenFile('report.pdf');

const parts = report.Split();                      // one Document per page
const chapter = report.ExtractPages([3, 4, 5]);     // subset (1-based, repeats allowed) as a new Document

const cover = Document.OpenFile('cover.pdf');
report.InsertPage(1, cover.Pages[0]);               // copy a single page across documents
report.Append(chapter);                             // copy chapter's pages onto report

report.WriteTo('assembled.pdf');

Several documents can also be combined into one in a single call with Document.Merge(), which builds a new Document from copies of every page of every document passed to it, in order.

Building Pages From Scratch

Document.New() creates a document from nothing: zero pages when a format is omitted, or one blank page of the given PageFormat when one is passed. Additional blank pages come from Document.AddPage(), which also accepts a PageFormat (or an existing Page to copy the size of). Text is drawn onto a page with Page.AddText(), positioned at an (x, y) point in PDF user space.

import { Document, PageFormat } from '@asposefoss/pdf';

const doc = Document.New(PageFormat.A4);          // one blank A4 page
doc.Pages[0].AddText('Hello', 72, 720, { fontSize: 14 });
doc.AddPage(PageFormat.A4.landscape());           // append more as you go
doc.WriteTo('scratch.pdf');

Bookmarks and Document Navigation

The document outline (the bookmark panel most PDF readers show alongside the page) is read with Document.GetOutlines() and replaced wholesale with Document.SetOutlines(), each working with a tree of OutlineItem values. Each OutlineItem carries a Title, a Dest destination, and optionally Children for nested entries, plus display hints like Open (expanded by default) and Bold.

import { Document, OutlineItem } from '@asposefoss/pdf';

const items: OutlineItem[] = [
  { Title: 'Introduction', Dest: { name: 'intro' } },
  {
    Title: 'Chapters',
    Open: true,
    Children: [
      { Title: 'Chapter 1', Dest: { name: 'ch1' } },
      { Title: 'Chapter 2', Dest: { name: 'ch2' } },
    ],
  },
];
doc.SetOutlines(items);

Destinations named this way ({ name: 'intro' }) resolve through the document’s named-destination table, which Document.GetNamedDestinations() and Document.SetNamedDestination() manage directly when a bookmark needs to point at a destination that isn’t tied to page content.

Structured Text and Accessibility Tagging

Document.GetStructTree() returns the document’s logical structure tree (or null when the document isn’t tagged), and Document.CreateStructTree() builds one, marking the document Tagged. Once a structure tree exists, Page.GetStructuredText() returns the page’s text as TextBlock values — positioned fragments already grouped into lines and paragraph-like blocks — which is the input a hand-tagging pass works from: walking the blocks, deciding which ones are headings versus body text, and appending the corresponding elements to the tree.

function handTagPage(doc: Document, page: Page, heading: string): void {
  const root = doc.GetStructTree();
  if (!root) throw new Error('handTagPage: the document is not tagged yet');
  for (const block of page.GetStructuredText()) {
    const text = block.text.trim();
    if (text.length === 0) continue;
    const el = root.Append(text.startsWith(heading) ? 'H2' : 'P');
    el.MarkContent(page, block.quad);
  }
}

A tagged structure tree is what downstream features build on: semantic HTML export reflows from it instead of falling back to a plain heuristic layout, and Document.ValidatePdfUa() checks the document against a subset of the PDF/UA accessibility standard that depends on tagging being present.


Quick Start

Install the package, then open a document, pull out and recombine a subset of its pages, and save the result:

asposefoss/pdf is not yet published — build from source until it ships. See the project README for build instructions.
import { Document } from '@asposefoss/pdf';

const doc = Document.OpenFile('report.pdf');

const chapter = doc.ExtractPages([3, 4, 5]);   // subset (1-based, repeats allowed) as a new Document
const cover = Document.OpenFile('cover.pdf');

doc.InsertPage(1, cover.Pages[0]);             // copy a single page across documents
doc.Append(chapter);                           // copy chapter's pages onto doc

doc.WriteTo('assembled.pdf');

Supported Formats

FormatExtensionReadWrite
PDFpdf
Markdownmd
SVGsvg
TIFFtiff
DOCXdocx
HTMLhtml
PNGpng
EPUBepub

Open Source & Licensing

Aspose.PDF FOSS for TypeScript is released under the MIT license, with source published on GitHub. There is no evaluation watermark, usage limit, or separate license file to manage, and the library may be used in commercial products without royalties.

The package is currently at version 0.1.0, reflecting active early-stage development. Node.js (>=22) is the only runtime requirement, and the package has no other third-party dependencies.


Getting Started