Pular para o conteúdo

Adicione marcadores e um sumário

Esta receita adiciona marcadores na forma de um outline hierárquico do documento. O leitor exibe essas entradas na barra lateral de navegação, onde elas funcionam como um sumário clicável. Um valor inteiro para o nível controla o aninhamento. A receita segue examples/12-bookmarks-and-toc.php.

A ISO 32000-2 chama essa estrutura de outline do documento: uma árvore de itens de outline que serve como um sumário visual.

Terminal window
composer require nextpdf/core:^3

Nenhuma extensão opcional é necessária. A API de marcadores é estável desde a 1.0.0 e roda na matriz de backport 8.1–8.4.

bookmark($title, $level, $y) adiciona um item de outline vinculado à página atual. O vínculo usa a posição Y atual, a menos que você passe um valor Y explícito. $level define a profundidade de aninhamento: o nível 0 é um capítulo de nível superior, o nível 1 é uma seção sob o item de nível 0 mais recente, e assim por diante. O motor constrói a árvore de outline para você. Na ISO 32000-2, os itens são encadeados por meio de Prev/Next em cada nível e aninhados por meio de First/Last, com a entrada Outlines do catálogo como raiz.

Cada item contém um destino; assim, o leitor salta para a página correta quando você clica no marcador. A ISO 32000-2 §12.3.2 determina que os destinos podem ser associados a itens de outline. Essa mesma chamada também alimenta o construtor de sumário do NextPDF, então o outline e o sumário renderizado permanecem sincronizados.

A superfície da API é gerada a partir do PHPDoc. Esta receita depende de um método:

  • bookmark(string $title, int $level = 0, float $y = -1): static — adiciona um item de outline no nível $level vinculado à página atual. $y = -1 usa a posição Y atual do cursor. Passe um valor Y não negativo para fixar um destino preciso.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->bookmark('Chapter 1', level: 0);
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Chapter 1', newLine: true);
$doc->bookmark('Section 1.1', level: 1); // nested under Chapter 1
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'Section body.');
$doc->addPage();
$doc->bookmark('Chapter 2', level: 0);
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Chapter 2', newLine: true);
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/bookmarks.pdf');

Este exemplo completo, pronto para o harness, respeita NEXTPDF_COOKBOOK_OUTPUT e não introduz entropia própria.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Bookmarks and Navigation');
$doc->setPrintHeader(false);
$doc->setPrintFooter(false);
$doc->setAutoPageBreak(true, margin: 25);
// Chapter 1
$doc->addPage();
$doc->bookmark('Chapter 1: Introduction', level: 0);
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Chapter 1: Introduction', newLine: true);
$doc->ln(3);
$doc->bookmark('What is NextPDF?', level: 1);
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, 'What is NextPDF?', newLine: true);
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'NextPDF is a modern PDF 2.0 library for PHP 8.4+. '
. 'It generates standards-targeting documents with typography, '
. 'graphics, and signatures.');
$doc->ln(5);
$doc->bookmark('Key Features', level: 1);
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, 'Key Features', newLine: true);
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'HTML rendering, barcodes, PAdES signatures, '
. 'and a worker-safe architecture.');
// Chapter 2
$doc->addPage();
$doc->bookmark('Chapter 2: Getting Started', level: 0);
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Chapter 2: Getting Started', newLine: true);
$doc->ln(3);
$doc->bookmark('Installation', level: 1);
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, 'Installation', newLine: true);
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'Install via Composer: composer require nextpdf/core');
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/bookmarks.pdf';
$doc->save($out);
echo "Created bookmarks.pdf with a 2-level outline\n";
  • Saltos de nível. Um salto do nível 0 para o nível 2 sem um nível 1 entre eles pode parecer malformado em alguns leitores. Aumente o nível em, no máximo, um de cada vez.
  • Crie o marcador antes do conteúdo. Chame bookmark() no ponto em que você quer o destino. Na maioria dos casos, coloque a chamada imediatamente antes do título. Uma chamada colocada após o título define o destino um pouco abaixo do título.
  • Y explícito para destinos precisos. Com $y = -1, o destino usa a posição Y atual do cursor. Passe um valor Y explícito para um destino estável. Por exemplo, esse valor fixa o topo de uma seção independentemente de quanto conteúdo a precede.
  • O suporte a outline é universal, mas a apresentação pode variar. Os leitores podem renderizar o outline recolhido ou expandido. Esta API não pode forçar um estado aberto ou fechado por item.

Cada chamada de bookmark() acrescenta um item de outline e uma entrada de sumário, o que é uma operação O(1). A árvore de outline é finalizada uma única vez, em save(). Centenas de marcadores continuam bem dentro do orçamento de 2000 ms / 64 MB.

Os títulos dos marcadores aparecem na interface de navegação do leitor. Se um título incluir dados controlados pelo usuário, limite seu comprimento e aplique a mesma sanitização que aplicaria a qualquer string exibida. Esta receita não realiza análise de entrada nem acessa a rede.

AfirmaçãoEspecificaçãoCláusulareference_id
O outline do documento é uma árvore de itens de outline que atua como um sumário visual.ISO 32000-2§12.3.3
Os itens de outline se encadeiam por meio de Prev/Next e se aninham por meio de First/Last.ISO 32000-2§12.3.3
O dicionário de outline é a entrada Outlines do catálogo.ISO 32000-2§7.7.2
Os destinos podem ser associados a itens de outline.ISO 32000-2§12.3.2

Perfil de reprodutibilidade — estrutural. O /ID do trailer e os átomos de data variam a cada salvamento, então o harness remove esses átomos e compara a estrutura normalizada pelo qpdf. Esta receita descreve como o NextPDF produz essa estrutura. Ela não declara, de forma genérica, conformidade com a ISO 32000-2.

Não se aplica. O outline do documento e o sumário são recursos do Core, sem qualquer restrição Premium.