HTML: ระบบย่อยสำหรับเรนเดอร์ HTML+CSS เป็น PDF
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”ระบบย่อย HTML แปลง HyperText Markup Language (HTML) และ Cascading Style Sheets (CSS) เป็นสตรีมเนื้อหา Portable Document Format (PDF) ด้วยการเดินหน้าเพียงครั้งเดียว ระบบย่อย HTML เป็นระบบย่อยที่ใหญ่ที่สุดและมีความเสี่ยงสูงสุดของเอนจิน โดยมีไฟล์ 324 ไฟล์อยู่ภายใต้ src/Html/
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”ระบบย่อย HTML เป็นตัวเรนเดอร์ HTML+CSS เป็น PDF แบบสตรีมมิงผ่านครั้งเดียว พื้นผิวสาธารณะมีเพียงเมธอดเดียวคือ Document::writeHtml() ภายใน HtmlParser จะแยกอินพุตเป็นโทเคน รีโซลฟ์สไตล์ คำนวณเค้าโครง และปล่อยตัวดำเนินการ PDF ด้วยการเดินหน้าเพียงครั้งเดียว โดยไม่เก็บโครงต้นไม้ของเอกสารไว้
โปรดทำความเข้าใจขอบเขตให้ชัดเจน ระบบย่อยนี้ไม่ใช่ตัวเรนเดอร์แบบเก็บเอกสารไว้ (retained-document) ระบบย่อยนี้ไม่เก็บกราฟขององค์ประกอบ ไม่จัดวางเนื้อหาที่เขียนไปแล้วใหม่ และไม่อนุญาตให้อินพุตเปลี่ยนแปลงหลังจากเริ่มการแยกวิเคราะห์ ระบบย่อยนี้นำชุดย่อยของ CSS ที่คัดสรรไว้มาใช้งานตามรุ่นของข้อกำหนดที่ตรึงไว้ มี Architecture Decision Records (ADRs) สองฉบับที่กำกับดูแลระบบย่อยนี้ ADR-001 กำหนดโมเดลสตรีมมิงผ่านครั้งเดียวและขีดจำกัดของโมเดลดังกล่าว ADR-010 กำหนดสัญญาสี่เลเยอร์ (การแยกวิเคราะห์ CSS สถานะของสไตล์ เค้าโครง การวาด) พร้อมส่วนเสริมด้านสื่อแบบแบ่งหน้าและการวัด
HtmlParser ถูกจัดระดับเป็นความเสี่ยงระดับวิกฤติในแถลงการณ์ของโมดูล ไฟล์ห้าไฟล์มีคำอธิบายประกอบเขตอันตราย (danger-zone) ที่บันทึกไว้ ได้แก่ ออร์เคสเตรเตอร์ HtmlParser (ตัวแยกโทเคนแบบสตรีมมิง โค้ดมากกว่า 1000 บรรทัด (LOC)), HtmlStyleState (ฟิลด์คุณสมบัติ CSS มากกว่า 100 รายการพร้อมโมเดลการสืบทอดแบบสแตก), HtmlBlockHandler (การจัดส่งบล็อกที่ผูกกับสถานะของสไตล์), FlexLayoutEngine (การวัดและการจัดวางแบบ flex เต็มรูปแบบ) และ TableParser (การแบ่งหน้า colspan/rowspan ข้ามจุดแบ่งหน้า) ให้ถือว่าการเปลี่ยนแปลงในส่วนนี้เป็นงานที่ต้องทำในโหมดวางแผน (plan mode)
ใช้หน้านี้เป็นจุดเริ่มต้น ดู pipeline สำหรับลำดับขั้นตอน, css-resolver สำหรับการเรียงซ้อนและความจำเพาะ, layer-contracts-adr010 สำหรับขอบเขตของเลเยอร์ และ streaming-constraints-adr001 สำหรับโมเดลแบบไม่เก็บโครงต้นไม้และขีดจำกัดของโมเดลดังกล่าว
ข้อความแบบขวาไปซ้ายและสองทิศทาง
หัวข้อที่มีชื่อว่า “ข้อความแบบขวาไปซ้ายและสองทิศทาง”writeHtml() เรนเดอร์เนื้อหาแบบขวาไปซ้าย (RTL) ได้ ตั้งค่าคุณสมบัติ CSS direction: rtl บน body ตาราง หรือองค์ประกอบใดก็ได้ เอนจินแก้ไขลำดับเชิงภาพด้วย Unicode Bidirectional Algorithm (UAX #9) ผ่านเอนจินสองทิศทางของเลเยอร์การจัดวางตัวอักษร — ดู Typography สำหรับรายละเอียดของ BidiEngine เนื้อหาที่ผสมละติน อาหรับ และตัวเลขจะถูกจัดลำดับอย่างถูกต้อง และตัวเลขที่อยู่หลังข้อความอาหรับจะยังคงเรียงหลักจากซ้ายไปขวา
อักขระอาหรับยังได้รับการ shape ตามบริบทด้วย เอนจินเลือกรูปแบบเริ่มต้น กลาง ท้าย หรือเดี่ยวของแต่ละตัวอักษร และใช้ลิเกเจอร์ Lam-Alef การ shape ต้องใช้ฟอนต์ที่ลงทะเบียนแล้วซึ่งแมปอักขระครอบคลุมบล็อก Arabic Presentation Forms-B หน้าตัวอักษรที่มีเฉพาะละติน รวมถึงฟอนต์ standard-14 ไม่สามารถวาดอาหรับได้ ในตาราง แต่ละเซลล์จะถูกจัดลำดับใหม่และ shape แยกกัน แล้วจัดแนวชิดขอบ start (ขวา) ภายใต้ direction: rtl RTL ใช้กับอาหรับ ฮีบรู เปอร์เซีย และอูรดู ฮีบรูถูกจัดลำดับใหม่แต่ไม่ถูก shape
ตั้งค่าทิศทางด้วยคุณสมบัติ CSS direction — แอตทริบิวต์ dir ของ HTML ไม่ถูกแมปกับคุณสมบัตินี้ ยังไม่ได้ใช้งานการจัดแนวแนวนอนของบล็อกที่ไม่ใช่ตารางและข้อความแบบอินไลน์ รวมถึง text-align: justify สำหรับใบแจ้งหนี้ภาษาอาหรับที่รันได้และรายการข้อจำกัดปัจจุบันทั้งหมด โปรดดู Render right-to-left Arabic HTML
พื้นผิวของ API
หัวข้อที่มีชื่อว่า “พื้นผิวของ API”| สัญลักษณ์ | ตำแหน่ง | บทบาท |
|---|---|---|
Document::writeHtml(string $html): static | src/Core/Concerns/HasTextOutput.php | จุดเข้าใช้งานสาธารณะ เรนเดอร์ HTML ที่ตำแหน่งเคอร์เซอร์ปัจจุบัน |
Document::createStandalone(): self | src/Core/Document.php | สร้างเอกสารแบบสแตนด์อะโลน |
HtmlParser::parse(string $html): HtmlRenderResult | src/Html/HtmlParser.php | ออร์เคสเตรเตอร์ภายใน |
HtmlRenderResult | src/Html/HtmlRenderResult.php | ผลลัพธ์ที่เปลี่ยนแปลงไม่ได้ ได้แก่ สตรีม เคอร์เซอร์สิ้นสุด และฟอนต์ที่ใช้ |
DefaultHtmlSecurityPolicy | src/Html/DefaultHtmlSecurityPolicy.php | นโยบายค่าเริ่มต้นสำหรับแท็ก แอตทริบิวต์ CSS และ Uniform Resource Locator (URL) |
HtmlSecurityPolicyInterface | src/Contracts/HtmlSecurityPolicyInterface.php | สัญญานโยบายสำหรับนโยบายที่กำหนดเอง |
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”ที่มา: 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');ตัวอย่างโค้ด — สำหรับการใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับการใช้งานจริง”ตัวอย่างนี้แสดงรายงานแบบตารางพร้อมบล็อกสไตล์ที่ฝังอยู่ภายใน โดยอ้างอิงจาก 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);}กรณีขอบเขตและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบเขตและข้อควรระวัง”- ชุดย่อยของ CSS ที่คัดสรร การรองรับถูกตรึงไว้ตามแต่ละโมดูล ตรวจสอบ เมทริกซ์การรองรับ CSS ก่อนที่คุณจะพึ่งพาคุณสมบัติใด ๆ
- ขีดจำกัดแบบเข้มจะ throw ข้อยกเว้น ขีดจำกัดอินพุต 10 MB, องค์ประกอบ
50,000รายการ และระดับการซ้อน 100 ระดับ แต่ละขีดจำกัดจะ throwHtmlParsingExceptionดู ข้อจำกัดของสตรีมมิง - ไม่มีการจัดวางใหม่ ตัวเรนเดอร์เขียนเอาต์พุตเพียงครั้งเดียวตามลำดับของเอกสาร สไตล์ที่มาภายหลังไม่สามารถเปลี่ยนแปลงเอาต์พุตก่อนหน้าได้
:has()ถูกควบคุมการเข้าถึง ภายใต้ฟีเจอร์ทดลองcss.has- ระบบย่อยที่มีความเสี่ยงระดับวิกฤติ มีไฟล์ห้าไฟล์ที่ถูกทำเครื่องหมายเป็นเขตอันตราย ใช้โหมดวางแผนสำหรับการเปลี่ยนแปลงภายใต้
src/Html/
ข้อจำกัดของสตรีมมิงแบบผ่านครั้งเดียว (ADR-001)
หัวข้อที่มีชื่อว่า “ข้อจำกัดของสตรีมมิงแบบผ่านครั้งเดียว (ADR-001)”ตัวเรนเดอร์ไม่เก็บโครงต้นไม้ของเอกสารและทำงานด้วยการเดินหน้าเพียงครั้งเดียว ขีดจำกัดขององค์ประกอบ การซ้อน และอินพุตเป็นขีดจำกัดแบบเข้ม สำหรับรายละเอียดทั้งหมดและสัญญาด้านความปลอดภัยของ worker โปรดดู ข้อจำกัดของสตรีมมิง (ADR-001)
สัญญาของเลเยอร์ (ADR-010)
หัวข้อที่มีชื่อว่า “สัญญาของเลเยอร์ (ADR-010)”การแยกวิเคราะห์ CSS สถานะของสไตล์ เค้าโครง และการวาด ถูกแยกออกเป็นสี่เลเยอร์ด้วยสัญญาแบบทิศทางเดียว พร้อมส่วนเสริมด้านสื่อแบบแบ่งหน้าและการวัด สำหรับรายละเอียดทั้งหมด โปรดดู สัญญาของเลเยอร์ (ADR-010)
งบประมาณหน่วยความจำสำหรับเอกสารขนาดใหญ่
หัวข้อที่มีชื่อว่า “งบประมาณหน่วยความจำสำหรับเอกสารขนาดใหญ่”หน่วยความจำของสถานะสไตล์และเคอร์เซอร์เป็น O(ความลึกของการซ้อน) ไม่ใช่ O(จำนวนองค์ประกอบ) performance_budget ต่อหน้าคือ peak_mb: 64 ขีดจำกัด 50,000 องค์ประกอบเป็นเพดานแบบเข้ม ให้แบ่งอินพุตที่ใหญ่กว่าออกเป็นการเรียก writeHtml() หลายครั้ง สำหรับรายละเอียด โปรดดู ข้อจำกัดของสตรีมมิง
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”การท่องผ่านเป็น O(จำนวนโทเคน) การกำหนดขนาดคอลัมน์ของตารางจะเพิ่มการสแกนแถวต่อตารางแบบมีขอบเขตจำกัด การสแกนล่วงหน้า :has() ที่เป็นทางเลือกจะเพิ่มการผ่านรายการโทเคนแบบมีขอบเขตจำกัดอีกหนึ่งครั้ง เกณฑ์มาตรฐานประสิทธิภาพของไปป์ไลน์การเรนเดอร์ HTML บังคับใช้เกตการถดถอย 5% (งานที่ผสานแล้ว, pull request (PR) #564) performance_budget ต่อหน้า (wall_ms: 1500, peak_mb: 64) คือเพดานการทำงาน
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”DefaultHtmlSecurityPolicy บังคับใช้รายการที่อนุญาต (allowlist) ของแท็ก แอตทริบิวต์ คุณสมบัติ CSS และสคีม URL พร้อมเพดานอินพุต 10 MB และเพดานการซ้อน 100 ระดับ โดยเป็นอิสระจากตัวแยกวิเคราะห์ รายการที่อนุญาตของคุณสมบัติ CSS คือเพดานด้านความปลอดภัย ตารางการรองรับขณะรันไทม์เป็นเพดานความสามารถที่แยกต่างหาก นำ HtmlSecurityPolicyInterface ไปใช้งานเพื่อจัดหานโยบายที่เข้มงวดขึ้น DefaultExternalResourcePolicy กำกับดูแลการดึงทรัพยากรภายนอกแยกต่างหาก
ในค่า href และ src ของรูปภาพ รายการที่อนุญาตของ URL ยังปฏิเสธพาธที่ขึ้นต้นด้วยแบ็กสแลช (\…) และพาธแบบ Universal Naming Convention (UNC) (\\host\share) ควบคู่กับการปฏิเสธแบบ protocol-relative (//) ที่มีอยู่เดิม และอนุญาตเฉพาะ http(s) หรือพาธสัมพัทธ์เท่านั้น แบ็กสแลชจะถูกทำให้เป็นรูปแบบมาตรฐานเป็นสแลชไปข้างหน้าก่อนการตรวจสอบ ดังนั้นการรวมไฟล์ภายในด้วยพาธสัมบูรณ์ของ Windows หรือการดึงจากแชร์ Server Message Block (SMB) จึงไม่สามารถหลุดผ่านสาขา “no scheme, therefore relative” ได้ พาธทั้งสองแบบไม่มีสคีม Uniform Resource Identifier (URI)
ข้อความตัดตอนจากเมทริกซ์การรองรับ CSS (เฉพาะแถวที่ Verified)
หัวข้อที่มีชื่อว่า “ข้อความตัดตอนจากเมทริกซ์การรองรับ CSS (เฉพาะแถวที่ Verified)”หน้านี้ไม่ระบุการรองรับเป็นรายคุณสมบัติซ้ำอีก เมทริกซ์การรองรับ CSS เป็นแหล่งอ้างอิงเดียวสำหรับสถานะที่ผ่านการตรวจสอบของแต่ละโมดูลตาม World Wide Web Consortium (W3C) รวมถึงสถานะว่าโมดูลใดเป็น Verified หรือ Claimed
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”ระบบย่อยนำชุดย่อยของ CSS ที่คัดสรรไว้มาใช้งานตามรุ่นของข้อกำหนดที่ตรึงไว้ การแมปข้อกำหนดเชิงพฤติกรรมสำหรับการเรียงซ้อนมีการบันทึกไว้พร้อมตัวระบุ clause และ chunk ที่ css-resolver สถานะความสอดคล้องตามมาตรฐานของแต่ละโมดูลปรากฏอยู่ใน เมทริกซ์การรองรับ CSS
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”ความสามารถระดับองค์กร Premium ขยายขอบเขตการรองรับ CSS (การพิมพ์ขั้นสูงและโมดูลเพิ่มเติม) บนไปป์ไลน์แบบผ่านครั้งเดียวที่เหมือนกัน สถาปัตยกรรม ขีดจำกัด และสัญญาของเลเยอร์ยังคงเหมือนเดิมในทุกรุ่น ดู เมทริกซ์การรองรับ CSS