Lewati ke konten

Menambahkan tautan dan anotasi teks

Gunakan resep ini untuk menambahkan tiga elemen interaktif: tautan internal untuk melompat ke halaman lain, tautan eksternal yang membuka Uniform Resource Locator (URL), dan anotasi teks yang juga disebut catatan tempel. Resep ini mengikuti examples/17-links.php dan examples/29-annotations.php.

Tautan yang dapat diklik merupakan anotasi tautan ISO 32000-2: tautan hiperteks menuju tujuan atau tindakan. Catatan tempel adalah anotasi teks. Catatan ini tampil sebagai ikon saat ditutup dan sebagai popup saat dibuka.

Terminal window
composer require nextpdf/core:^3

Tidak diperlukan ekstensi opsional. Antarmuka pemrograman aplikasi (application programming interface, API) untuk tautan dan anotasi stabil sejak 1.0.0 dan berjalan pada matriks backport 8.1–8.4.

Tautan internal menggunakan pola tiga panggilan yang mendukung referensi maju:

  1. addLink() mencadangkan pengenal tautan (int).
  2. link($x, $y, $w, $h, $id) menempatkan persegi panjang yang dapat diklik dan mengikatnya ke id tersebut.
  3. setLink($id, $pageIndex, $y) mengikat id ke halaman tujuan (berbasis nol) dan posisi Y.

Saat menautkan ke halaman yang belum ada, panggil langkah 3 setelah langkah 2. Tujuan tersebut menggunakan bentuk tujuan eksplisit. ISO 32000-2 §12.3.2.2 mendefinisikan [page /XYZ left top zoom], dengan komponen null mempertahankan nilai pembaca saat ini.

Untuk tautan eksternal, berikan string URL ke link() alih-alih int. NextPDF kemudian menghasilkan tindakan Uniform Resource Identifier (URI) yang URI-nya merupakan string ASCII UTF-8 yang wajib ada. Sebagai pintasan, write($height, $text, $link) menggambar teks sebaris dengan URL yang dilampirkan, dan annotation($x, $y, $w, $h, $text) menempatkan catatan tempel dengan subtipe Text. ISO 32000-2 mewajibkan SubtypeLink untuk anotasi tautan dan mendefinisikan ikon anotasi teks serta perilaku popup.

Permukaan API dihasilkan dari PHPDoc. Resep ini memakai metode berikut:

  • addLink(): int — mencadangkan pengenal tautan internal.
  • setLink(int $linkId, int $pageIndex = -1, float $y = 0): static — mengikat id ke halaman tujuan (berbasis nol) dan posisi Y.
  • link(float $x, float $y, float $w, float $h, string|int $link): static — membuat persegi panjang yang dapat diklik; id int mengarah ke tautan internal, sedangkan string adalah URL eksternal.
  • write(float $height, string $text, string $link = ''): static — menulis teks sebaris dengan URL opsional.
  • annotation(float $x, float $y, float $w, float $h, string $text, string $subtype = 'Text'): static — menambahkan anotasi catatan tempel.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$jump = $doc->addLink(); // 1. reserve an id (forward reference)
$doc->addPage();
$doc->setFont('helvetica', 'B', 12);
$x = $doc->getX();
$y = $doc->getY();
$doc->cell(60, 10, 'Go to page 2', newLine: true);
$doc->link($x, $y, 60, 10, $jump); // 2. clickable rectangle -> id
$doc->link($doc->getX(), $doc->getY(), 80, 10, 'https://nextpdf.dev'); // external
$doc->addPage();
$doc->setLink($jump, pageIndex: 1, y: 0); // 3. bind id to page 2 (index 1)
$doc->cell(0, 10, 'Destination (page 2).', newLine: true);
$doc->annotation(x: 180, y: 20, w: 10, h: 10, text: 'A reviewer note.');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf');

Ini contoh lengkap yang siap dijalankan dalam harness. Contoh ini menghormati NEXTPDF_COOKBOOK_OUTPUT dan tidak menambahkan entropi sendiri.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Links and Annotations');
// Reserve the internal-link id before its destination page exists.
$linkToPage3 = $doc->addLink();
// Page 1 — source of the internal and external links.
$doc->addPage();
$doc->setFont('helvetica', 'B', 20);
$doc->cell(0, 14, 'Links and Annotations', newLine: true);
$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);
$doc->setTextColor(0, 51, 153);
$linkX = $doc->getX();
$linkY = $doc->getY();
$doc->cell(60, 10, 'Go to Page 3', newLine: true);
$doc->link($linkX, $linkY, 60, 10, $linkToPage3); // internal: int id
$doc->setTextColor(0);
$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);
$doc->setTextColor(0, 102, 204);
$doc->write(10, 'Visit https://nextpdf.dev', link: 'https://nextpdf.dev');
$doc->setTextColor(0);
$doc->ln(6);
$urlX = $doc->getX();
$urlY = $doc->getY();
$doc->cell(80, 10, 'NextPDF on GitHub', newLine: true);
$doc->link($urlX, $urlY, 80, 10, 'https://github.com/nextpdf-labs/nextpdf');
// Page 2 — intermediate.
$doc->addPage();
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'Internal links can jump across pages; this page is '
. 'skipped by the link on page 1.');
// Page 3 — destination + a sticky note.
$doc->addPage();
$doc->setLink($linkToPage3, pageIndex: 2, y: 0); // bind id to page 3 (index 2)
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 14, 'Page 3 — Link Target', newLine: true);
$doc->ln(4);
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'You arrived via the internal link on page 1.');
$doc->annotation(
x: 185, y: 40, w: 10, h: 10,
text: 'Sticky note: appears as an icon; click to read this text.',
);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf';
$doc->save($out);
echo "Created links.pdf\n";
  • pageIndex berbasis nol. setLink($id, pageIndex: 2, …) menargetkan halaman ketiga. Kesalahan selisih satu di sini adalah yang paling umum.
  • String vs. int pada link(). Nilai int adalah id tujuan internal dari addLink(). String adalah URL eksternal. Jika Anda memberikan tipe yang salah, Anda akan mendapatkan jenis tautan yang salah tanpa memicu kesalahan.
  • Ikat setiap id yang dicadangkan. Id addLink() yang tidak pernah Anda ikat dengan setLink() tidak memiliki tujuan. Persegi panjang tersebut dapat diklik tetapi tidak berfungsi. Ikat id tersebut sebelum save().
  • Area yang dapat diklik adalah persegi panjang, bukan teksnya. link() menerima x, y, w, h secara eksplisit. Atur ukurannya agar mencakup teks yang terlihat. Mesin tidak mengukur glif untuk Anda.
  • Tautan eksternal tidak divalidasi. NextPDF menyimpan URI secara harfiah. NextPDF tidak memverifikasi bahwa target terselesaikan atau aman. Pembaca PDF-lah yang menyelesaikannya.

Setiap tautan atau anotasi menambahkan satu kamus anotasi ke halaman. Biayanya adalah O(1) per elemen. Ratusan elemen per halaman tetap jauh di bawah anggaran 2000 ms / 64 MB.

Target tautan eksternal disimpan secara harfiah dan diselesaikan oleh pembaca, bukan oleh pustaka. Perlakukan URL yang diberikan pengguna sebagai tidak tepercaya. Batasi skema dengan daftar izin; biasanya hanya https. Tolak javascript: dan file: sebelum meneruskannya ke link(). Teks anotasi muncul di antarmuka pengguna (user interface, UI) pembaca, jadi batasi panjangnya dan bersihkan konten catatan yang dikendalikan pengguna. Tidak ada penguraian masukan maupun akses jaringan yang terjadi dalam resep ini.

PernyataanSpesifikasiKlausareference_id
Anotasi tautan adalah tautan hiperteks menuju tujuan atau tindakan.ISO 32000-2§12.5.6.5
Subtype adalah Link untuk anotasi tautan.ISO 32000-2§12.5.6.5
Pada tindakan URI, URI merupakan string ASCII UTF-8 yang wajib ada.ISO 32000-2§12.6.4.8
Anotasi teks adalah catatan tempel (tertutup = ikon, terbuka = popup).ISO 32000-2§12.5.6.4
Tujuan eksplisit [page /XYZ left top zoom]; null mempertahankan nilai saat ini.ISO 32000-2§12.3.2.2

Profil reproduktibilitas — struktural. Atom trailer /ID dan atom tanggal berubah setiap kali disimpan. Harness menghapus atom-atom tersebut, lalu membandingkan struktur yang dinormalisasi oleh qpdf. Resep ini menjelaskan cara NextPDF menghasilkan struktur tersebut. Resep ini tidak menyatakan konformansi ISO 32000-2 sebagai klaim menyeluruh.

Tidak berlaku. Tautan dan anotasi teks merupakan kemampuan Core tanpa pembatasan Premium.