Skip to content
getnextpdf.com

Pro edition

Table of contents — Deep Reference

This page is the contract-level reference for the NextPDF Pro Toc module, NextPDF\Pro\Toc. AutoTocCollector scans HTML for H1–H6 headings and emits TocHeading value objects. AutoTocRenderer paginates those headings and renders each TOC page as PDF content-stream operators. AutoTocConfig is the immutable rendering configuration. Page numbers are caller-supplied or sequential placeholders; the module does not resolve live document cross-references. This page states the public API, the observable behaviour contract, and the failure modes. Task-oriented setup and samples live on the Table of contents capability page.

This capability ships in NextPDF Pro (nextpdf/pro) and activates with a Pro-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

No runtime capability flag gates this module. The Toc classes are usable whenever nextpdf/pro is installed and licensed.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
AutoTocCollector::__construct()int $maxDepth = 6Clamps depth to the 1–6 rangeInstance accumulates collected headings
AutoTocCollector::extract()string $html, int $maxDepth = 6Constructs, scans, and returns headings in one calllist<TocHeading>Static fast path
AutoTocCollector::scan()string $htmlMatches H1–H6, strips markup, decodes entities, collapses whitespace, appends non-empty headingsMutates internal state
AutoTocCollector::assignSequentialPages()int $startPage = 1Advances the page at each level-0 heading after the firstlist<TocHeading>Placeholder numbering only
AutoTocCollector::assignPageNumbers()array<int,int> $pageMapApplies an index-to-page map; unmapped indices keep their current pagelist<TocHeading>Caller-supplied real pages
AutoTocCollector::getHeadings()Returns the collected headingslist<TocHeading>
AutoTocCollector::count()Number of collected headingsint
AutoTocCollector::reset()Clears collected headingsReuse the collector across scans
AutoTocRenderer::render()list<TocHeading> $headings, ?AutoTocConfig $config = nullFilters by depth, paginates, emits one content stream per pagelist<string>Returns [] when every heading is filtered out
AutoTocConfig::__construct()14 typed params (title, depth, fonts, spacing, margins, colors, page size)Immutable configuration carrierReadonly; ChartColor colors default to black
AutoTocConfig::default(), ::landscape(), ::letter()A4 portrait, A4 landscape, and US Letter presetsselfStatic factories
AutoTocConfig::withTitle(), ::withMaxDepth(), ::withFontSize(), ::withDotLeader(), ::withPageNumbers(), ::withIndentPerLevel()one value eachReturns a new instance with the field changed; withMaxDepth() clamps to 1–6selfFluent, non-mutating
AutoTocConfig::contentWidth()pageWidth - 2 * leftMarginfloatDerived
AutoTocConfig::lineSpacing()fontSize * lineHeightfloatDerived
AutoTocConfig::entriesPerPage()max(1, floor((pageHeight - 2*topMargin - 2*titleFontSize) / lineSpacing))intAlways ≥ 1
TocHeading::__construct()string $title, int $level, ?int $pageNumber = null, float $y = 0.0Immutable heading value objectReadonly; level 0 = H1
TocHeading::withPageNumber(), ::withY(), ::withPosition()page number and/or Y coordinateReturns a new instance with position fields changedselfFluent, non-mutating
TocHeading::hasPageNumber()True when a page number is assignedbool
public function __construct(int $maxDepth = 6)
public static function extract(string $html, int $maxDepth = 6): array
public function scan(string $html): void
public function assignSequentialPages(int $startPage = 1): array
public function assignPageNumbers(array $pageMap): array
public static function render(
array $headings,
?AutoTocConfig $config = null,
): array
public function __construct(
public string $title = 'Table of Contents',
public int $maxDepth = 6,
public float $fontSize = 10.0,
public float $titleFontSize = 16.0,
public float $indentPerLevel = 15.0,
public float $lineHeight = 1.6,
public bool $showPageNumbers = true,
public bool $showDotLeader = true,
public ChartColor $textColor = new ChartColor(0.0, 0.0, 0.0),
public ChartColor $titleColor = new ChartColor(0.0, 0.0, 0.0),
public float $leftMargin = 40.0,
public float $topMargin = 50.0,
public float $pageWidth = 595.28,
public float $pageHeight = 841.89,
)
public function entriesPerPage(): int
public function __construct(
public string $title,
public int $level,
public ?int $pageNumber = null,
public float $y = 0.0,
)
public function withPageNumber(int $pageNumber): self
public function hasPageNumber(): bool

AutoTocCollector::scan() matches <h1><h6> with a bounded pattern (case-insensitive, dot-matches-newline) that requires a balanced open and close tag of the same level. Each match’s inner content is tag-stripped, entity-decoded (ENT_QUOTES | ENT_HTML5, UTF-8), and whitespace-collapsed. Empty results are dropped. level is the tag number minus one, so H1 is level 0. A tag deeper than maxDepth is skipped. extract() is the one-call factory over construct, scan, and read-back.

Two explicit strategies exist, both caller-driven.

  • assignSequentialPages($startPage) advances the page counter when a level-0 heading is reached after the first entry, then stamps every heading.
  • assignPageNumbers($pageMap) applies an index-to-page map; an unmapped index keeps its existing page number.

Neither strategy inspects a laid-out document.

AutoTocRenderer::render() keeps headings whose level is below maxDepth, returns [] when nothing survives, then splits the remainder into chunks of AutoTocConfig::entriesPerPage(). Each chunk becomes one content-stream string. Per entry, indentation is leftMargin + level * indentPerLevel; the font size decreases 0.5 pt per level and is floored at 6.0 pt; level 0 uses the bold font key, deeper levels the regular key. When page numbers are enabled and present, an optional dot leader fills the gap and the number is right-aligned. The title and every entry string are shown with the Tj operator per ISO 32000-2:2020 §9.4, and each string is escaped for PDF literal-string syntax per §7.3.4.2. Identical HTML and configuration yield stable headings and operators.

  • Malformed heading markup is not collected. An unclosed <h2> with no matching </h2> fails the balanced-pair pattern and is skipped.
  • Heading text that is empty after tag stripping and trimming is dropped.
  • maxDepth is clamped to 1–6 at both the collector constructor and AutoTocConfig::withMaxDepth(); out-of-range values are corrected, not rejected.
  • Page numbers are caller-controlled. No internal layout pass discovers the real page a heading lands on, so the module cannot resolve live cross-references.
  • The module raises no exceptions. render() returns an empty array when every heading is filtered out by depth; it never throws on empty input.
  • Sizing collapses to the max(1, …) floor, so entriesPerPage() is always at least 1 and pagination always makes progress.
  • The renderer produces drawable operators only. The caller places the returned streams onto real pages and supplies the /TocFont, /TocBoldFont, and /TocTitleFont resources.

No cryptographic operation occurs in this module, so no FIPS-mode-specific behaviour exists. Nothing here consumes randomness, hashing, or signing.

ClaimStandardClause
TOC title and entry text shown with the Tj text-showing operatorISO 32000-2:2020§9.4
Emitted strings escaped as PDF literal strings, with backslash doubled and parentheses escapedISO 32000-2:2020§7.3.4.2
PDF /Outlines tree or named-destination linksNot built (content-stream operators only)
Live document cross-reference resolutionNot supported (caller-supplied page numbers)

All clauses are paraphrased; NextPDF does not reproduce normative text. The statements above are capability statements about the structures NextPDF emits.

  • Availability within the Pro package: AutoTocCollector, AutoTocRenderer, AutoTocConfig, and TocHeading since 1.9.0. All are current in nextpdf/pro 3.1.0.
  • AutoTocConfig colors are NextPDF\Pro\Chart\ChartColor values. The default text and title colors are black (0.0, 0.0, 0.0).
  • Start from AutoTocConfig::default(), ::landscape(), or ::letter(), then chain withers. The object is readonly, so each wither returns a new instance.
  • Assign real page numbers with assignPageNumbers() from your own layout pass; assignSequentialPages() yields placeholders only.
  • entriesPerPage(), lineSpacing(), and contentWidth() are pure derivations of the config; call them to pre-size layout before rendering.
  • getHeadings(), count(), and reset() read and clear the collector’s accumulated state between scans.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.