HTML: podsystem renderowania HTML+CSS do PDF
W skrócie
Dział zatytułowany „W skrócie”Podsystem HTML konwertuje język HyperText Markup Language (HTML) i arkusze Cascading Style Sheets (CSS) na strumienie zawartości formatu Portable Document Format (PDF) w jednym przebiegu do przodu. To największy i obarczony najwyższym ryzykiem podsystem silnika, obejmujący 324 pliki w katalogu src/Html/.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Podsystem HTML to jednoprzebiegowy, strumieniowy renderer HTML+CSS do PDF. Jego publiczną powierzchnię stanowi jedna metoda: Document::writeHtml(). Wewnętrznie HtmlParser tokenizuje dane wejściowe, rozwiązuje style, oblicza układ i emituje operatory PDF w jednym przebiegu do przodu, bez przechowywania drzewa dokumentu.
Zakres należy określić jednoznacznie. Ten podsystem nie jest rendererem przechowującym dokument. Nie utrzymuje grafu elementów, nie wykonuje ponownie układu zapisanej już treści ani nie pozwala zmieniać danych wejściowych po rozpoczęciu parsowania. Implementuje wyselekcjonowany podzbiór CSS przy ustalonych wersjach specyfikacji. Jego działanie regulują dwa dokumenty Architecture Decision Record (ADR). ADR-001 definiuje jednoprzebiegowy model strumieniowy i jego limity. ADR-010 definiuje czterowarstwowy kontrakt (parsowanie CSS, stan stylów, układ, malowanie) oraz dodatki dotyczące mediów stronicowanych i pomiarów.
W manifeście modułu HtmlParser ma przypisane ryzyko krytyczne. Pięć plików ma udokumentowane adnotacje stref zagrożenia: orkiestrator HtmlParser (strumieniowy tokenizer, ponad 1000 wierszy kodu (LOC)), HtmlStyleState (ponad 100 pól właściwości CSS ze stosowym modelem dziedziczenia), HtmlBlockHandler (dyspozytor bloków sprzężony ze stanem stylów), FlexLayoutEngine (pełny pomiar i układ flex) oraz TableParser (stronicowanie colspan/rowspan przez podziały stron). Zmiany w tym obszarze należy traktować jako pracę w trybie planowania.
Ta strona służy jako punkt wejścia. Zobacz pipeline, aby poznać sekwencję etapów, css-resolver w sprawie kaskady i swoistości, layer-contracts-adr010 w sprawie granic warstw oraz streaming-constraints-adr001 w sprawie modelu bez przechowywania drzewa i jego limitów.
Tekst od prawej do lewej i dwukierunkowy
Dział zatytułowany „Tekst od prawej do lewej i dwukierunkowy”writeHtml() renderuje treść od prawej do lewej (RTL). Ustaw właściwość CSS direction: rtl na elemencie body, tabeli lub dowolnym elemencie. Silnik rozwiązuje kolejność wizualną za pomocą algorytmu dwukierunkowego Unicode (UAX #9) poprzez silnik dwukierunkowy warstwy typografii — szczegóły BidiEngine znajdziesz w sekcji Typografia. Mieszana treść łacińska, arabska i liczbowa porządkuje się poprawnie, a liczba po tekście arabskim zachowuje cyfry w kolejności od lewej do prawej.
Tekst arabski podlega także kontekstowemu kształtowaniu: silnik wybiera formę początkową, środkową, końcową lub izolowaną każdej litery i stosuje ligaturę Lam-Alef. Kształtowanie wymaga zarejestrowanej czcionki, której mapa znaków pokrywa blok Arabic Presentation Forms-B; krój wyłącznie łaciński, w tym standard-14, nie potrafi rysować pisma arabskiego. W tabelach każda komórka jest porządkowana i kształtowana osobno oraz wyrównuje się do początkowej (prawej) krawędzi przy direction: rtl. RTL dotyczy arabskiego, hebrajskiego, perskiego i urdu; hebrajski jest porządkowany, ale nie kształtowany.
Kierunek ustawiaj właściwością CSS direction — atrybut HTML dir nie jest na nią mapowany. Wyrównanie poziome bloków i tekstu wbudowanego spoza tabel oraz text-align: justify nie są jeszcze stosowane. Uruchamialną fakturę arabską oraz pełną listę bieżących ograniczeń znajdziesz w Renderowanie arabskiego HTML od prawej do lewej.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Symbol | Lokalizacja | Rola |
|---|---|---|
Document::writeHtml(string $html): static | src/Core/Concerns/HasTextOutput.php | Publiczny punkt wejścia. Renderuje HTML w bieżącym położeniu kursora. |
Document::createStandalone(): self | src/Core/Document.php | Tworzy samodzielny dokument. |
HtmlParser::parse(string $html): HtmlRenderResult | src/Html/HtmlParser.php | Wewnętrzny orkiestrator. |
HtmlRenderResult | src/Html/HtmlRenderResult.php | Niezmienny wynik: strumień, kursor końcowy oraz użyte czcionki. |
DefaultHtmlSecurityPolicy | src/Html/DefaultHtmlSecurityPolicy.php | Domyślna polityka znaczników, atrybutów, CSS oraz adresów Uniform Resource Locator (URL). |
HtmlSecurityPolicyInterface | src/Contracts/HtmlSecurityPolicyInterface.php | Kontrakt polityki dla niestandardowych polityk. |
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”Źródło: 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');Przykład kodu — środowisko produkcyjne
Dział zatytułowany „Przykład kodu — środowisko produkcyjne”Ten przykład przedstawia raport w formie tabeli z osadzonym blokiem stylów, wzorowany na 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);}Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Wyselekcjonowany podzbiór CSS. Obsługa jest ustalana osobno dla każdego modułu. Sprawdź macierz obsługi CSS, zanim zaczniesz polegać na danej właściwości.
- Twarde limity powodują zgłoszenie wyjątku. Limity 10 MB danych wejściowych,
50,000elementów oraz 100 poziomów zagnieżdżenia — każdy z nich powoduje zgłoszenieHtmlParsingException. Zobacz ograniczenia strumieniowania. - Brak ponownego układu. Renderer zapisuje dane wyjściowe jednokrotnie, w kolejności dokumentu; późniejsze style nie mogą zmienić wcześniejszych danych wyjściowych.
:has()jest zablokowany za eksperymentalną funkcjącss.has.- Podsystem o ryzyku krytycznym. Pięć plików oznaczono jako strefy zagrożenia. Do zmian w katalogu
src/Html/używaj trybu planowania.
Ograniczenia jednoprzebiegowego strumieniowania (ADR-001)
Dział zatytułowany „Ograniczenia jednoprzebiegowego strumieniowania (ADR-001)”Renderer nie przechowuje drzewa dokumentu i wykonuje jeden przebieg do przodu. Limity elementów, zagnieżdżenia i danych wejściowych są twardymi ograniczeniami. Pełne szczegóły oraz kontrakt bezpieczeństwa workerów zawiera ograniczenia strumieniowania (ADR-001).
Kontrakty warstw (ADR-010)
Dział zatytułowany „Kontrakty warstw (ADR-010)”Parsowanie CSS, stan stylów, układ i malowanie są rozdzielone na cztery warstwy z jednokierunkowymi kontraktami oraz dodatkami dotyczącymi mediów stronicowanych i pomiarów. Pełne szczegóły zawiera kontrakty warstw (ADR-010).
Budżet pamięci dla dużych dokumentów
Dział zatytułowany „Budżet pamięci dla dużych dokumentów”Zużycie pamięci przez stan stylów i kursor ma złożoność O(głębokość zagnieżdżenia), a nie O(liczba elementów). Przypadający na stronę performance_budget wynosi peak_mb: 64. Limit 50,000 elementów to twardy pułap; większe dane wejściowe dziel na wiele wywołań writeHtml(). Szczegóły zawiera ograniczenia strumieniowania.
Wydajność
Dział zatytułowany „Wydajność”Przetwarzanie ma złożoność O(liczba tokenów). Wyznaczanie szerokości kolumn tabeli dodaje ograniczone skanowanie wierszy w obrębie każdej tabeli. Opcjonalny wstępny skan :has() dodaje jeden ograniczony przebieg listy tokenów. Test wydajności potoku renderowania HTML egzekwuje 5% bramkę regresji w ramach scalonego pull request (PR) #564. Przypadający na stronę performance_budget (wall_ms: 1500, peak_mb: 64) stanowi pułap operacyjny.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”DefaultHtmlSecurityPolicy egzekwuje listę dozwolonych znaczników, atrybutów, właściwości CSS i schematów URL, a także pułap 10 MB danych wejściowych i pułap 100 poziomów zagnieżdżenia, niezależnie od parsera. Lista dozwolonych właściwości CSS stanowi pułap bezpieczeństwa. Tabela obsługi w czasie wykonywania stanowi odrębny pułap możliwości. Aby zapewnić surowszą politykę, zaimplementuj HtmlSecurityPolicyInterface. DefaultExternalResourcePolicy osobno reguluje pobieranie zasobów zewnętrznych.
W wartościach href oraz src obrazów lista dozwolonych adresów URL odrzuca także ścieżki zaczynające się od ukośnika wstecznego (\…) oraz ścieżki Universal Naming Convention (UNC) (\\host\share), oprócz już odrzucanych ścieżek względnych wobec protokołu (//) i przy liście dopuszczającej wyłącznie http(s) lub adresy względne. Ukośniki wsteczne są przed sprawdzeniem normalizowane do ukośników zwykłych, dzięki czemu ani dołączenie lokalnego pliku za pomocą bezwzględnej ścieżki systemu Windows, ani pobranie udziału Server Message Block (SMB) nie może przejść przez gałąź „brak schematu, zatem adres względny”. Żadna z tych ścieżek nie zawiera schematu Uniform Resource Identifier (URI).
Fragment macierzy obsługi CSS (tylko zweryfikowane wiersze)
Dział zatytułowany „Fragment macierzy obsługi CSS (tylko zweryfikowane wiersze)”Ta strona nie powtarza informacji o obsłudze poszczególnych właściwości. Macierz obsługi CSS jest jedynym źródłem prawdy o zweryfikowanym statusie poszczególnych modułów World Wide Web Consortium (W3C), a także o tym, które moduły są zweryfikowane, a które tylko deklarowane.
Zgodność
Dział zatytułowany „Zgodność”Podsystem implementuje wyselekcjonowany podzbiór CSS przy ustalonych wersjach specyfikacji. Behawioralne odwzorowania specyfikacji dla kaskady udokumentowano wraz z identyfikatorami klauzul i fragmentów na stronie css-resolver. Status zgodności poszczególnych modułów znajduje się w macierzy obsługi CSS.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Funkcja dla przedsiębiorstw. Premium poszerza zakres obsługi CSS (zaawansowany druk i dodatkowe moduły) w identycznym, jednoprzebiegowym potoku. Architektura, limity i kontrakty warstw pozostają takie same we wszystkich edycjach. Zobacz macierz obsługi CSS.