HTML: subsistem rendering HTML+CSS ke PDF
Sekilas pandang
Bagian berjudul “Sekilas pandang”Subsistem HTML mengonversi HyperText Markup Language (HTML) dan Cascading Style Sheets (CSS) menjadi aliran konten Portable Document Format (PDF) dalam satu lintasan maju. Ini adalah subsistem terbesar dan paling berisiko pada mesin ini, dengan 324 berkas di bawah src/Html/.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Tinjauan konseptual
Bagian berjudul “Tinjauan konseptual”Subsistem HTML adalah perender streaming satu lintasan dari HTML+CSS ke PDF. Antarmuka publiknya hanya satu metode: Document::writeHtml(). Secara internal, HtmlParser melakukan tokenisasi masukan, menyelesaikan gaya, menghitung tata letak, dan mengeluarkan operator PDF dalam satu lintasan maju, tanpa menyimpan pohon dokumen.
Pahami cakupannya dengan jelas. Subsistem ini bukan renderer berbasis dokumen tertahan. Subsistem ini tidak menyimpan graf elemen, tidak menata ulang konten yang telah ditulis, dan tidak mengizinkan masukan berubah setelah penguraian dimulai. Subsistem ini mengimplementasikan subset CSS terkurasi berdasarkan pin spesifikasi yang tetap. Dua Architecture Decision Record (ADR) mengaturnya. ADR-001 mendefinisikan model streaming satu lintasan beserta batas-batasnya. ADR-010 mendefinisikan kontrak empat lapisan (penguraian CSS, status gaya, tata letak, paint), serta adjung paged-media dan pengukuran.
HtmlParser dinilai berisiko kritis dalam manifes modul. Lima berkas memuat anotasi zona bahaya yang terdokumentasi: orkestrator HtmlParser (tokenizer streaming, 1000+ baris kode (LOC)), HtmlStyleState (100+ bidang properti CSS dengan model pewarisan tumpukan), HtmlBlockHandler (pengiriman blok yang terkopel dengan status gaya), FlexLayoutEngine (pengukuran dan tata letak flex penuh), dan TableParser (paginasi colspan/rowspan yang melintasi pemisah halaman). Perlakukan perubahan di area ini sebagai pekerjaan mode rencana.
Gunakan halaman ini sebagai titik masuk. Lihat pipeline untuk urutan tahap, css-resolver untuk cascade dan spesifisitas, layer-contracts-adr010 untuk batas-batas lapisan, dan streaming-constraints-adr001 untuk model tanpa pohon tertahan beserta batas-batasnya.
Teks kanan-ke-kiri dan dwiarah
Bagian berjudul “Teks kanan-ke-kiri dan dwiarah”writeHtml() merender konten kanan-ke-kiri (RTL). Atur properti CSS direction: rtl pada body, sebuah tabel, atau elemen apa pun. Mesin menyelesaikan urutan visual dengan Unicode Bidirectional Algorithm (UAX #9) melalui mesin dwiarah pada lapisan tipografi — lihat Typography untuk detail BidiEngine. Konten campuran Latin, Arab, dan numerik tersusun dengan benar, dan angka setelah Arab mempertahankan digitnya dari kiri ke kanan.
Arab juga menjalani shaping kontekstual: mesin memilih bentuk awal, tengah, akhir, atau terisolasi untuk setiap huruf dan menerapkan ligatur Lam-Alef. Shaping membutuhkan fon terdaftar yang peta karakternya mencakup blok Arabic Presentation Forms-B; wajah hanya-Latin, termasuk fon standard-14, tidak dapat menggambar Arab. Dalam tabel, setiap sel disusun ulang dan di-shape sendiri-sendiri serta diratakan ke tepi awal (kanan) di bawah direction: rtl. RTL berlaku untuk Arab, Ibrani, Persia, dan Urdu; Ibrani disusun ulang tetapi tidak di-shape.
Atur arah dengan properti CSS direction — atribut HTML dir tidak dipetakan ke properti tersebut. Perataan horizontal teks blok dan inline non-tabel, serta text-align: justify, belum diterapkan. Untuk faktur Arab yang dapat dijalankan dan daftar lengkap batasan saat ini, lihat Render right-to-left Arabic HTML.
Permukaan API
Bagian berjudul “Permukaan API”| Simbol | Lokasi | Peran |
|---|---|---|
Document::writeHtml(string $html): static | src/Core/Concerns/HasTextOutput.php | Titik masuk publik. Merender HTML pada kursor saat ini. |
Document::createStandalone(): self | src/Core/Document.php | Membangun dokumen mandiri. |
HtmlParser::parse(string $html): HtmlRenderResult | src/Html/HtmlParser.php | Orkestrator internal. |
HtmlRenderResult | src/Html/HtmlRenderResult.php | Hasil imutabel: stream, kursor akhir, dan fon yang digunakan. |
DefaultHtmlSecurityPolicy | src/Html/DefaultHtmlSecurityPolicy.php | Kebijakan tag, atribut, CSS, dan Uniform Resource Locator (URL) standar. |
HtmlSecurityPolicyInterface | src/Contracts/HtmlSecurityPolicyInterface.php | Kontrak kebijakan untuk kebijakan kustom. |
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”Sumber: examples/08-html-basic.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('HTML Basic');$doc->addPage();$doc->writeHtml('<h1 style="color:#1E3A8A;">HTML Rendering</h1><p>Direct to PDF.</p>');$doc->save(__DIR__ . '/output/08-html-basic.pdf');Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”Contoh ini menampilkan laporan tabel dengan blok gaya tertanam yang dimodelkan dari examples/09-html-table.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Exception\HtmlParsingException;
function renderInventory(string $rowsHtml, string $out): void{ $doc = Document::createStandalone(); $doc->setTitle('Inventory'); $doc->addPage();
$html = '<style>table { width: 100%; } ' . 'th { background-color: #1E3A8A; color: #FFFFFF; }</style>' . '<table border="1" cellpadding="5">' . $rowsHtml . '</table>';
try { $doc->writeHtml($html); } catch (HtmlParsingException $e) { // Input cap, element cap (50,000), or nesting cap (100). Do not retry. throw $e; }
$doc->save($out);}Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Subset CSS terkurasi. Dukungan di-pin per modul. Periksa matriks dukungan CSS sebelum Anda mengandalkan suatu properti.
- Batas keras melempar pengecualian. Batas masukan 10 MB,
50,000elemen, dan 100 tingkat penyarangan masing-masing melemparkanHtmlParsingException. Lihat batasan streaming. - Tanpa penataan ulang. Perender menulis keluaran satu kali dalam urutan dokumen; gaya yang datang belakangan tidak dapat mengubah keluaran sebelumnya.
:has()dibatasi berada di balik fitur eksperimentalcss.has.- Subsistem berisiko kritis. Lima berkas ditandai sebagai zona bahaya. Gunakan mode rencana untuk perubahan di bawah
src/Html/.
Batasan streaming satu lintasan (ADR-001)
Bagian berjudul “Batasan streaming satu lintasan (ADR-001)”Perender tidak menyimpan pohon dokumen dan hanya menjalankan satu lintasan maju. Batas elemen, penyarangan, dan masukan merupakan batas keras. Untuk detail lengkap dan kontrak keamanan worker, lihat batasan streaming (ADR-001).
Kontrak lapisan (ADR-010)
Bagian berjudul “Kontrak lapisan (ADR-010)”Penguraian CSS, status gaya, tata letak, dan paint dipisahkan ke dalam empat lapisan dengan kontrak satu arah, serta adjung paged-media dan pengukuran. Untuk detail lengkap, lihat kontrak lapisan (ADR-010).
Anggaran memori untuk dokumen besar
Bagian berjudul “Anggaran memori untuk dokumen besar”Memori untuk status gaya dan kursor bersifat O(kedalaman penyarangan), bukan O(jumlah elemen). performance_budget per halaman adalah peak_mb: 64. Batas 50,000 elemen merupakan batas atas keras; bagi masukan yang lebih besar menjadi beberapa pemanggilan writeHtml(). Untuk detail, lihat batasan streaming.
Performa
Bagian berjudul “Performa”Traversal berjalan dalam O(jumlah token). Penentuan ukuran kolom tabel menambahkan pemindaian baris per tabel yang terbatas. Pra-pemindaian :has() opsional menambahkan satu lintasan daftar token yang terbatas. Tolok ukur performa pipeline render HTML menegakkan gerbang regresi 5% (pekerjaan yang telah digabungkan, pull request (PR) #564). performance_budget per halaman (wall_ms: 1500, peak_mb: 64) merupakan batas atas operasional.
Catatan keamanan
Bagian berjudul “Catatan keamanan”DefaultHtmlSecurityPolicy menegakkan allowlist untuk tag, atribut, properti CSS, dan skema URL, ditambah batas atas masukan 10 MB dan batas atas penyarangan 100 tingkat, secara independen dari pengurai. Allowlist properti CSS merupakan batas atas keamanan. Tabel dukungan runtime merupakan batas atas kapabilitas yang terpisah. Implementasikan HtmlSecurityPolicyInterface untuk menyediakan kebijakan yang lebih ketat. DefaultExternalResourcePolicy mengatur pengambilan sumber daya eksternal secara terpisah.
Untuk nilai href dan src gambar, allowlist URL juga menolak jalur yang berakar pada backslash (\…) dan jalur Universal Naming Convention (UNC) (\\host\share), selain penolakan protocol-relative (//) yang sudah ada dan allowlist hanya-http(s)-atau-relatif. Backslash dinormalkan menjadi forward slash sebelum pemeriksaan, sehingga penyertaan berkas lokal dengan jalur absolut Windows atau pengambilan share Server Message Block (SMB) tidak dapat lolos melalui cabang “tanpa skema, jadi relatif”. Kedua jalur tersebut tidak membawa skema Uniform Resource Identifier (URI).
Kutipan matriks dukungan CSS (baris Verified saja)
Bagian berjudul “Kutipan matriks dukungan CSS (baris Verified saja)”Halaman ini tidak menyatakan ulang dukungan per properti. Matriks dukungan CSS adalah satu-satunya otoritas untuk status modul per World Wide Web Consortium (W3C) yang terverifikasi, termasuk modul mana yang berstatus Verified versus Claimed.
Kesesuaian
Bagian berjudul “Kesesuaian”Subsistem ini mengimplementasikan subset CSS terkurasi berdasarkan pin spesifikasi yang tetap. Pemetaan spesifikasi perilaku untuk cascade didokumentasikan dengan pengenal klausa dan chunk pada css-resolver. Status kesesuaian per modul muncul dalam matriks dukungan CSS.
Konteks komersial
Bagian berjudul “Konteks komersial”Kapabilitas Enterprise. Premium memperluas cakupan CSS (pencetakan tingkat lanjut dan modul tambahan) pada pipeline satu lintasan yang identik. Arsitektur, batasan, dan kontrak lapisan tetap sama di seluruh edisi. Lihat matriks dukungan CSS.