ข้ามไปยังเนื้อหา

HTML: ระบบย่อยสำหรับเรนเดอร์ HTML+CSS เป็น PDF

ระบบย่อย HTML แปลง HyperText Markup Language (HTML) และ Cascading Style Sheets (CSS) เป็นสตรีมเนื้อหา Portable Document Format (PDF) ด้วยการเดินหน้าเพียงครั้งเดียว ระบบย่อย HTML เป็นระบบย่อยที่ใหญ่ที่สุดและมีความเสี่ยงสูงสุดของเอนจิน โดยมีไฟล์ 324 ไฟล์อยู่ภายใต้ src/Html/

Terminal window
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

สัญลักษณ์ตำแหน่งบทบาท
Document::writeHtml(string $html): staticsrc/Core/Concerns/HasTextOutput.phpจุดเข้าใช้งานสาธารณะ เรนเดอร์ HTML ที่ตำแหน่งเคอร์เซอร์ปัจจุบัน
Document::createStandalone(): selfsrc/Core/Document.phpสร้างเอกสารแบบสแตนด์อะโลน
HtmlParser::parse(string $html): HtmlRenderResultsrc/Html/HtmlParser.phpออร์เคสเตรเตอร์ภายใน
HtmlRenderResultsrc/Html/HtmlRenderResult.phpผลลัพธ์ที่เปลี่ยนแปลงไม่ได้ ได้แก่ สตรีม เคอร์เซอร์สิ้นสุด และฟอนต์ที่ใช้
DefaultHtmlSecurityPolicysrc/Html/DefaultHtmlSecurityPolicy.phpนโยบายค่าเริ่มต้นสำหรับแท็ก แอตทริบิวต์ CSS และ Uniform Resource Locator (URL)
HtmlSecurityPolicyInterfacesrc/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 ระดับ แต่ละขีดจำกัดจะ throw HtmlParsingException ดู ข้อจำกัดของสตรีมมิง
  • ไม่มีการจัดวางใหม่ ตัวเรนเดอร์เขียนเอาต์พุตเพียงครั้งเดียวตามลำดับของเอกสาร สไตล์ที่มาภายหลังไม่สามารถเปลี่ยนแปลงเอาต์พุตก่อนหน้าได้
  • :has() ถูกควบคุมการเข้าถึง ภายใต้ฟีเจอร์ทดลอง css.has
  • ระบบย่อยที่มีความเสี่ยงระดับวิกฤติ มีไฟล์ห้าไฟล์ที่ถูกทำเครื่องหมายเป็นเขตอันตราย ใช้โหมดวางแผนสำหรับการเปลี่ยนแปลงภายใต้ src/Html/

ตัวเรนเดอร์ไม่เก็บโครงต้นไม้ของเอกสารและทำงานด้วยการเดินหน้าเพียงครั้งเดียว ขีดจำกัดขององค์ประกอบ การซ้อน และอินพุตเป็นขีดจำกัดแบบเข้ม สำหรับรายละเอียดทั้งหมดและสัญญาด้านความปลอดภัยของ worker โปรดดู ข้อจำกัดของสตรีมมิง (ADR-001)

การแยกวิเคราะห์ 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