|
THotPDF Preflight Report Methods
Składnia
type
THPDFPreflightFormat = (pfText, pfJSON, pfHTML, pfCSV);
function CreatePreflightReport(
const SourceFile: TFileName;
const Password : AnsiString = ''): AnsiString; overload;
function CreatePreflightReport(
const SourceFile: TFileName;
const Password : AnsiString;
const Format : THPDFPreflightFormat): AnsiString; overload;
procedure SavePreflightReport(
const SourceFile: TFileName;
const ReportFile: TFileName;
const Password :AnsiString = ''); overload;
procedure SavePreflightReport(
const SourceFile: TFileName;
const ReportFile: TFileName;
const Password : AnsiString;
const Format : THPDFPreflightFormat); overload;
function ValidatePDFVT(
const SourceFile: TFileName;
out Report : AnsiString): Boolean;
function ValidatePDFVT(
const SourceFile: TFileName;
const Password : AnsiString;
out Report : AnsiString): Boolean;
procedure EmbedPreflightReportInPDF(
const SourceFile: TFileName;
const TargetFile: TFileName);
procedure EmbedPreflightReportInPDF(
const SourceFile: TFileName;
const TargetFile: TFileName;
const Password : AnsiString);
function LoadAndValidatePreflightReport(
const EmbeddedFile : TFileName;
out OriginalReport: AnsiString;
out CurrentReport : AnsiString): Boolean;
function LoadAndValidatePreflightReport(
const EmbeddedFile : TFileName;
const Password : AnsiString;
out OriginalReport: AnsiString;
out CurrentReport : AnsiString): Boolean;
function ComparePreflightReports(
const ReportA: AnsiString;
const ReportB: AnsiString): AnsiString;
function RepairPDFFromPreflightReport(
const SourceFile: TFileName;
const TargetFile: TFileName;
out RepairsApplied: AnsiString): Boolean;
function RepairPDFFromPreflightReport(
const SourceFile: TFileName;
const TargetFile: TFileName;
const Password : AnsiString;
out RepairsApplied: AnsiString): Boolean;
function AggregatePreflightReports(
const Reports: array of AnsiString): AnsiString;
type
THPDFPreflightProfile = record
DisableChecks : AnsiString;
DisableWarnings: AnsiString;
DisableHints : Boolean;
end;
function LoadPreflightProfile(
const ProfileFile: TFileName): THPDFPreflightProfile;
function ApplyPreflightProfile(
const Report : AnsiString;
const Profile: THPDFPreflightProfile): AnsiString;
function ValidatePreflightProfile(
const Profile: THPDFPreflightProfile;
out UnknownNames: AnsiString): Boolean;
function GetBuiltInPreflightProfile(
const Name: AnsiString): THPDFPreflightProfile;
procedure SavePreflightProfile(
const Profile : THPDFPreflightProfile;
const ProfileFile: TFileName);
function CreatePreflightReportWithProfile(
const SourceFile : TFileName;
const Password : AnsiString;
const ProfileFile: TFileName;
const Format : THPDFPreflightFormat): AnsiString;
function MergePreflightProfiles(
const A, B: THPDFPreflightProfile): THPDFPreflightProfile;
function DiffPreflightProfiles(
const A, B : THPDFPreflightProfile;
out OnlyInA: AnsiString;
out OnlyInB: AnsiString): Boolean;
procedure EmbedPreflightReportAsXMP(
const SourceFile: TFileName;
const TargetFile: TFileName);
procedure EmbedPreflightReportAsXMP(
const SourceFile: TFileName;
const TargetFile: TFileName;
const Password : AnsiString);
function ConvertPreflightReportToVeraPDFStyle(
const Report: AnsiString): AnsiString;
Opis
CreatePreflightReport odczytuje wejściowy PDF i zwraca raport tekstowy z lekkimi kontrolami struktury. Przeciążenia z hasłem używają istniejącej ścieżki ładowania obsługującej hasła dla wspieranych szyfrowanych PDF. SavePreflightReport zapisuje ten sam raport do docelowego pliku tekstowego.
ValidatePDFVT uruchamia ukierunkowaną walidację PDF/VT i zwraca True tylko wtedy, gdy wymagane znaczniki i struktury są obecne. Zwrócony raport tekstowy sprawdza deklarację XMP pdfvtid:GTS_PDFVTVersion, przestrzeń nazw metadanych PDF/VT, zgodność daty modyfikacji PDF/VT z xmp:ModifyDate, bazowy znacznik PDF/X, brak szyfrowania, intencję wyjściową PDF/X, katalogowe DPartRoot, DPartRootNode, NodeNameList, obecność części dokumentu, ładowalną liczbę stron oraz pokrycie DPart na poziomie strony. Właściwości dat PDF/VT i XMP mogą być zapisane jako tekst elementu albo jako atrybuty RDF na elemencie rdf:Description.
Raport sprawdza nagłówek PDF, znacznik EOF, czy końcowy %%EOF leży blisko końca pliku, ostatni offset startxref, czy ten offset wskazuje tabelę xref albo strumień xref, liczbę znaczników %%EOF i startxref, równowagę znaczników rewizji i końcową kolejność znaczników, znacznik trailera albo strumienia XRef, ładowalną liczbę stron, stan szyfrowania, katalog, drzewo stron, znacznik obiektu strony, MediaBox, referencję słownika informacji, referencję root, liczbę obiektów pośrednich, liczbę definicji obiektów pośrednich, najwyższy numer obiektu, liczbę zduplikowanych numerów obiektów, unikalność numerów obiektów, liczbę obiektów katalogu, liczbę obiektów drzewa stron, liczbę obiektów stron, zadeklarowaną liczbę stron w drzewie stron, spójność liczby stron drzewa stron i ładowalnych stron, spójność obiektów stron i ładowalnych stron, równowagę stream i endstream, pokrycie wpisów /Length strumieni, liczbę tabel xref, liczbę podsekcji xref, liczby wpisów tabel xref, liczby wolnych i używanych wpisów xref, liczbę uszkodzonych wierszy xref, poprawność wierszy xref, pokrycie xref względem numerów obiektów, liczbę strumieni xref, liczbę strumieni obiektów, liczbę trailerów, trailer /Size, czy trailer /Size obejmuje najwyższy numer obiektu, pośrednie referencje trailera /Root i /Info, czy wskazane obiekty są zdefiniowane, czy trailer /Root wskazuje obiekt katalogu, liczbę wpisów tablicy trailer /ID i strukturę par, obecność trailer /Root, /Info, /ID i /Encrypt, szacowaną liczbę aktualizacji przyrostowych, status linearyzacji, załadowane pola stron, liczbę pól formularza, liczbę słowników zasobów, liczbę zasobów fontów, liczbę osadzonych programów fontów (/FontFile, /FontFile2, /FontFile3), liczbę image XObject, liczbę form XObject, liczbę zasobów ColorSpace, liczbę adnotacji oraz podliczby adnotacji widget/link, liczniki użycia łańcuchów filtrów dla FlateDecode, DCTDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode, ASCIIHexDecode, ASCII85Decode, RunLengthDecode i JPXDecode, pokrycie osadzania fontów, spójność liczby adnotacji, wskazówki zgodności PDF/A / PDF/X / PDF/UA / Tagged PDF / transparency, wybrane flagi funkcji, ostrzeżenia JavaScript albo action (obejmujące pełny zestaw PDF 1.7 sec 12.6.4 action: GoTo*, Thread, URI, Sound, Movie, Hide, Named, SubmitForm, ResetForm, ImportData, SetOCGState, Rendition, Trans i GoTo3DView, plus starsze kontrole JavaScript / Launch / OpenAction / AdditionalActions / EmbeddedFile / RichMedia oraz ostrzeżenia wzajemnego wykluczenia PDF/A), sumy ostrzeżeń oraz ogólne podsumowanie pass/fail. Te pomocniki są przeznaczone jako szybkie kontrole in-process przed przekazaniem plików do zewnętrznych walidatorów standardów; nie zastępują pełnego silnika walidacji preflight PDF/A, PDF/X, PDF/UA ani ISO 32000.
Overload Format przyjmuje pfText (domyślna ścieżka czysto tekstowa, stabilna bajtowo ze starymi overloadami),
pfJSON (dokument JSON przyjazny CI),
pfHTML (gotowy na dashboard, samowystarczalny raport HTML
z inline CSS i wierszami barwionymi wg wagi) albo pfCSV
(wiersze przyjazne arkuszom dla metadanych, checków, hintów, ostrzeżeń
i wartości podsumowania). Wyjście JSON grupuje wpisy w
polach najwyższego poziomu input, size, pdfVersion i
xrefStyle plus tablice checks,
info, hints i warnings
oraz obiekt summary niosący wartości failed,
warnings i result. Każdy check,
hint i ostrzeżenie niesie też stabilny, mający przestrzeń nazw
ruleId oraz ustrukturyzowany obiekt
location
Lokalizacja zawsze zawiera logiczny scope i
rozdzielaną ukośnikami path, może zawierać powiązany
key PDF i dodaje objectNumber,
pageIndex albo byteOffset, gdy raport
potrafi wskazać dokładną współrzędną. Wyjście CSV
używa stabilnego nagłówka category,name,status,value,spec,
z tekstami referencji ISO w spec, gdy diagnostyka ma
zmapowaną klauzulę standardu. Wbudowany enkoder JSON escapuje
", \ i bajty sterujące; sekwencje bajtów UTF-8
przechodzą bez zmian.
Każdy wpis checks, hints i warnings
niesie opcjonalne pole spec nazywające klauzulę ISO,
na którą celuje diagnostyka
(np
ISO 32000-1 sec 7.5.5 dla checków trailera,
ISO 19005-1 sec 6.6.2 dla ostrzeżenia o wzajemnej
wykluczalności PDF/A z JavaScriptem). Mapowanie obejmuje każdy check, hint i
ostrzeżenie emitowane przez raport do v2.122.0. Formalny JSON Schema
(draft 2020-12) opisujący strukturę wyjścia pfJSON
jest opublikowany w Docs/preflight-schema.json, więc
konsumenci downstream mogą walidować wyjście przed
parsowaniem
ID reguł mają stabilną formę
hotpdf.preflight.<category>.<rule-name>,
więc polityki CI mogą matchować regułę bez zależności od przetłumaczonej
prozy albo pozycji w tablicy
EmbedPreflightReportInPDF zapisuje kopię źródłowego PDF do TargetFile z raportem preflight w starszym formacie tekstowym dołączonym po ostatnim %%EOF jako linie komentarzy w stylu PDF (każda linia poprzedzona % ). Czytniki PDF ignorują dołączone bajty, ponieważ znajdują się poza grafem obiektów, ale przepływy archiwizacji, edytory tekstu i narzędzia w stylu grep mogą nadal odnaleźć osadzony raport do późniejszego audytu. Oryginalny graf obiektów, tabela cross-reference i trailer nie są modyfikowane.
LoadAndValidatePreflightReport wyodrębnia raport, który wcześniej dołączyło
EmbedPreflightReportInPDF, ponownie uruchamia bieżący algorytm preflight
na bajtach źródła poprzedzających osadzony blok komentarza i porównuje wartości
InputFingerprint. Funkcja zwraca
True, gdy oba odciski się zgadzają, co oznacza, że osadzony raport
nadal opisuje plik w takiej postaci, w jakiej istnieje na dysku
Gdy walidacja się nie powiedzie, wywołujący może sprawdzić
OriginalReport i CurrentReport, aby zobaczyć
diff zmian
ComparePreflightReports generuje treść w stylu unified diff
dla dwóch raportów. Wspólne wiersze pojawiają się z prefiksem dwóch spacji,
wiersze unikalne dla ReportA mają prefiks - ,
a wiersze unikalne dla ReportB — prefiks
+ . Algorytm jest dostrojony do poprawnie sformowanego
wyjścia klucz/wartość produkowanego przez CreatePreflightReport,
gdzie kolejność wierszy jest deterministyczna; nie jest to ogólna implementacja
LCS, ale daje zwarte, czytelne diffy w typowym przypadku raportów
w większości niezmienionych
RepairPDFFromPreflightReport stosuje zachowawczy
podzbiór napraw na poziomie bajtów uszkodzonego pliku PDF: odcina końcowe
bajty następujące po ostatnim markerze %%EOF i dopisuje
brakujący %%EOF, jeśli nie ma go nigdzie w pliku. Funkcja
zwraca True, gdy zastosowano co najmniej jedną naprawę; RepairsApplied wymienia naprawy w jednym wierszu
na zmianę. Naprawy na poziomie grafu obiektów (odbudowa tablic xref, łatanie
długości strumieni, poprawianie słowników trailera) są celowo poza
zakresem, bo takie poprawki mogą pogorszyć odzyskiwalność pliku częściowo odzyskiwalnego;
przy głębszych uszkodzeniach użyj dedykowanego narzędzia do odzyskiwania PDF
AggregatePreflightReports przyjmuje tablicę raportów per plik i tworzy jedno podsumowanie batch. Każdy wpis tablicy jest parsowany pod kątem pól Input, Size i Summary; agregat emituje jedną linię na plik oraz sumy liczby raportów passed, failed i warning, łącznych przeskanowanych bajtów oraz ogólnych liczników wyników. Przydatne dla potoków CI i pętli shell, które przetwarzają katalog PDF i chcą jednego zwięzłego podsumowania na końcu.
LoadPreflightProfile i
ApplyPreflightProfile pozwalają dostosować wyjście raportu
bez ponownego uruchamiania analizy. Plik profilu używa formatu w stylu INI
z trzema opcjonalnymi sekcjami:
[disable-checks] wymienia nazwy sprawdzeń do pominięcia;
[disable-warnings] wymienia nazwy ostrzeżeń do pominięcia;
a [options] akceptuje hints=false, aby
pominąć każdy wiersz Hint. Po filtrowaniu wiersz
Summary jest przeliczany, tak aby pominięte wpisy nie wpływały już na sumy Failed i Warnings; reszta
raportu przechodzi bez zmian
ValidatePreflightProfile przechodzi przez listy DisableChecks i DisableWarnings załadowanego profilu i zgłasza każdą nazwę nierozpoznawaną przez bieżącą implementację preflight. Pomaga wykryć pliki profili napisane dla nowszej lub starszej wersji HotPDF, które w przeciwnym razie po cichu nie wyłączyłyby niczego, ponieważ nazwy nie pasują do żadnej emitowanej kontroli ani ostrzeżenia.
GetBuiltInPreflightProfile zwraca gotowe do użycia
rekordy profili dla typowych przepływów. Rozpoznawane nazwy
(bez rozróżniania wielkości liter): default / ''
zwraca pusty profil; compact wyłącza każdy
wiersz Hint dla krótszych raportów;
silent-actions wyłącza każde ostrzeżenie o akcji z PDF 1.7 sec 12.6.4
oraz EmbeddedFile i
RichMedia, z myślą o przepływach, które
celowo osadzają multimedia lub akcje interaktywne i nie chcą,
by raport preflight je oznaczał. Nieznane nazwy również
zwracają pusty profil
SavePreflightProfile zapisuje rekord
THPDFPreflightProfile z powrotem do pliku INI w
tym samym formacie, który odczytuje LoadPreflightProfile
Obie funkcje są dokładnie odwrotne dla poprawnie sformowanych profili,
więc wywołujący mogą zbudować przepływ „wczytaj preset, popraw, zapisz”:
P := GetBuiltInPreflightProfile('compact'), edycja
P.DisableChecks, a potem
SavePreflightProfile(P, 'tuned.ini') do późniejszego
ponownego użycia
CreatePreflightReportWithProfile to wygodny wrapper jednego kroku, który składa istniejące CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile i konwertery formatów, dzięki czemu wywołujący mający już źródłowy PDF, opcjonalne hasło, plik profilu i format docelowy może wykonać jedno wywołanie zamiast łączyć cztery. Przekazanie pustego ProfileFile pomija krok profilu.
MergePreflightProfiles zwraca zdeduplikowaną sumę dwóch profili: DisableChecks i DisableWarnings zbierają nazwy z obu wejść, a DisableHints jest logicznym OR. Przydatne do nakładania presetu na poprawki specyficzne dla projektu.
DiffPreflightProfiles raportuje strukturalną
różnicę między dwoma profilami. Zwraca True, gdy
są równoważne; w przeciwnym razie False, a
OnlyInA i OnlyInB są wypełnione
wierszami rozdzielonymi znakiem nowej linii w postaci check:<name>,
warn:<name> lub option:hints=false,
opisującymi, które wpisy występują tylko po jednej stronie
EmbedPreflightReportAsXMP to wariant
EmbedPreflightReportInPDF przyjazny archiwizacji: zapisuje
kopię źródłowego PDF z raportem preflight dołączonym jako
blok komentarza w stylu PDF, którego payload to XMP / RDF
(xmlns:hotpdf="http://www.loslab.com/hotpdf/preflight/")
Każdy wiersz raportu staje się elementem hotpdf:<name>,
a poziom ważności jest przenoszony jako atrybut w wierszach sprawdzeń
Narzędzia obsługujące XMP, które skanują plik w poszukiwaniu markerów xpacket,
mogą wyświetlić osadzony raport; czytniki PDF nadal
ignorują dołączone bajty, bo leżą poza grafem obiektów. To celowo nie jest
integracja XMP zgodna ze specyfikacją: payload XMP nie jest referencjonowany z wpisu /Metadata
katalogu, więc czytniki XMP, które podążają tylko za referencją z katalogu,
go nie zobaczą
ConvertPreflightReportToVeraPDFStyle formuje
raport preflight HotPDF w dokument JSON podążający za ogólnym zarysem
wyjścia walidacji veraPDF, z poliem najwyższego poziomu
profile, tablicą jobs zawierającą
itemDetails / taskResult /
validationResult i tablicą ruleViolations
pod validationResult.details. Stylizowane na HotPDF,
a nie kompatybilne po drucie z veraPDF; celem jest pozwolić
narzędziom downstream, które już konsumują JSON veraPDF, zaadaptować się
do wyjścia HotPDF z minimalnym remapowaniem nazw pól, zamiast
uczyć się kompletnie innego układu
danych
Każde violation niesie ten sam stabilny ruleId i
ustrukturyzowaną location, których używa natywny raport JSON
Przykład
var
PDF: THotPDF;
begin
PDF := THotPDF.Create(nil);
try
PDF.SavePreflightReport('Input.pdf', 'PreflightReport.txt');
PDF.SavePreflightReport('Encrypted.pdf', 'EncryptedReport.txt', 'user-password');
PDF.SavePreflightReport('Input.pdf', 'PreflightReport.json', '', pfJSON);
PDF.SavePreflightReport('Input.pdf', 'PreflightReport.html', '', pfHTML);
PDF.SavePreflightReport('Input.pdf', 'PreflightReport.csv', '', pfCSV);
PDF.EmbedPreflightReportInPDF('Input.pdf', 'Input-with-report.pdf');
if not PDF.LoadAndValidatePreflightReport(
'Input-with-report.pdf', OriginalReport, CurrentReport)
then
WriteLn('Embedded preflight report no longer matches the source.');
finally
PDF.Free;
end;
end;
Zobacz też
|