THotPDF Preflight Report Methods

الصياغة

type
  THPDFPreflightFormat = (pfText, pfJSON, pfHTML, pfCSV);

function CreatePreflightReport(const SourceFile: TFileName): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat): AnsiString;
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat);
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;

الوصف

يقرأ CreatePreflightReport ملف PDF إدخالًا ويعيد تقريرًا نصيًا يتضمن فحوصًا بنيوية خفيفة. تستخدم overloads التي تقبل كلمة مرور مسار التحميل الحالي المدرك لكلمات المرور لملفات PDF المشفرة المدعومة، ويكتب SavePreflightReport التقرير نفسه إلى ملف نصي هدف

ينفذ ValidatePDFVT مسار تحقق مركزًا لـ PDF/VT ويعيد True فقط عندما تكون العلامات والبنى المطلوبة موجودة. يفحص التقرير مطالبة pdfvtid:GTS_PDFVTVersion في XMP، وnamespace metadata الخاص بـ PDF/VT، وتطابق تاريخ تعديل PDF/VT مع xmp:ModifyDate، وعلامة PDF/X الأساسية، وغياب التشفير، وPDF/X output intent، وDPartRoot في Catalog، ووجود أجزاء المستند، وعدد الصفحات القابل للتحميل، وتغطية DPart على مستوى الصفحة

يفحص التقرير رأس PDF، وعلامات EOF وstartxref، وتوازن revision markers، وtrailer أو XRef stream، وعدد الصفحات القابل للتحميل، وحالة التشفير، وCatalog، وشجرة الصفحات، وMediaBox، ومراجع Root وInfo، وأعداد الكائنات غير المباشرة، وتغطية xref، وتوازن stream/endstream، وحقول /Length، ومعلومات trailer /Size و/Root و/Info و/ID و/Encrypt، وتقدير التحديثات التزايدية، وحالة linearization، وpage boxes، وحقول النماذج، والموارد والخطوط والصور والتعليقات، وسلاسل filters، وتغطية تضمين الخطوط، ولمحات توافق PDF/A وPDF/X وPDF/UA وTagged PDF والشفافية، وتحذيرات JavaScript/actions، وإجمالي التحذيرات وملخص النجاح أو الفشل. هذه الفحوص سريعة داخل العملية وليست بديلًا لمحرك preflight كامل للمعايير

The Format overload accepts pfText (default plain-text path, byte-stable with the legacy overloads), pfJSON (CI-friendly JSON document), or pfHTML (dashboard-ready, self-contained HTML report with inline CSS and severity-coloured rows). The JSON output groups entries into input, size, pdfVersion, and xrefStyle top-level fields plus checks, info, hints, and warnings arrays and a summary object carrying failed, warnings, and result values. The built-in JSON encoder escapes ", \, and control bytes; UTF-8 byte sequences pass through unchanged.

يحمل كل إدخال في checks وhints وwarnings حقل spec اختياريًا يسمي بند ISO الذي يستهدفه التشخيص، مثل ISO 32000-1 sec 7.5.5 لفحوص trailer أو ISO 19005-1 sec 6.6.2 لتحذير التنافي بين PDF/A وJavaScript. تغطي الخريطة كل check وhint وwarning يصدره التقرير حتى v2.122.0. ينشر JSON Schema رسمي (draft 2020-12) يصف بنية إخراج pfJSON في Docs/preflight-schema.json حتى يستطيع downstream consumers التحقق من ملفات التقارير دون ربط parser خاص بـ HotPDF

يكتب EmbedPreflightReportInPDF نسخة من PDF المصدر إلى TargetFile مع إلحاق تقرير preflight النصي القديم بعد آخر %%EOF كسطور تعليق بنمط PDF. تتجاهل قارئات PDF هذه البايتات لأنها خارج object graph، لكن مسارات الأرشفة ومحررات النص وأدوات grep تستطيع إظهار التقرير لاحقًا للمراجعة. لا يتم تعديل object graph الأصلي أو cross-reference table أو trailer

LoadAndValidatePreflightReport extracts the report that EmbedPreflightReportInPDF previously appended, re-runs the current preflight algorithm against the source bytes preceding the embedded comment block, and compares the InputFingerprint values. The function returns True when both fingerprints match, indicating the embedded report still describes the file as it exists on disk When validation fails, callers can inspect OriginalReport and CurrentReport to diff what changed.

ComparePreflightReports emits a unified-diff-like body for two reports. Shared lines appear with a two-space prefix, lines unique to ReportA are prefixed with , and lines unique to ReportB are prefixed with . The algorithm is tuned for the well-formed key/value output produced by CreatePreflightReport where line order is deterministic; it is not a general-purpose LCS implementation but produces compact, readable diffs for the typical case of mostly-unchanged reports.

RepairPDFFromPreflightReport applies a conservative subset of byte-level repairs to a damaged PDF: it drops trailing bytes that follow the final %%EOF marker, and appends a missing %%EOF when one is not present anywhere. The function returns True when at least one repair was applied; RepairsApplied lists the repairs as one line per change. Object-graph repairs (rebuilding xref tables, patching stream lengths, fixing trailer dictionaries) are intentionally out of scope because such fixes can make a partially-recoverable file less recoverable; use a dedicated PDF recovery tool for deeper damage.

يأخذ AggregatePreflightReports مصفوفة من تقارير لكل ملف وينتج ملخص دفعة واحدًا. يحلل كل مدخل لاستخراج Input وSize وSummary، ويصدر سطرًا لكل ملف مع إجماليات التقارير الناجحة والفاشلة وذات التحذيرات، وإجمالي البايتات المفحوصة، وعدد النتائج العام. يفيد في CI وحلقات shell التي تعالج مجلد PDF وتحتاج ملخصًا موجزًا في النهاية

LoadPreflightProfile and ApplyPreflightProfile let callers tailor the report output without re-running the analysis. The profile file uses an INI-style format with three optional sections: [disable-checks] lists check names to suppress; [disable-warnings] lists warning names to suppress; and [options] accepts hints=false to suppress every Hint line. After filtering, the Summary line is recomputed so the suppressed entries no longer contribute to the Failed and Warnings totals; the rest of the report passes through unchanged.

يجتاز ValidatePreflightProfile قوائم DisableChecks وDisableWarnings في profile محمل ويبلغ عن أي اسم لا يعرفه تنفيذ preflight الحالي. يفيد لاكتشاف ملفات profile كتبت لإصدار HotPDF أحدث أو أقدم وكانت ستفشل في تعطيل أي شيء لأن الأسماء لا تطابق check أو warning صادر

GetBuiltInPreflightProfile returns ready-to-use profile records for common workflows. Recognised names (case-insensitive): default / '' returns an empty profile; compact disables every Hint line for shorter reports; silent-actions disables every PDF 1.7 sec 12.6.4 action warning plus EmbeddedFile and RichMedia, intended for workflows that intentionally embed multimedia or interactive actions and do not want the preflight report to flag them. Unknown names also return an empty profile.

SavePreflightProfile writes a THPDFPreflightProfile record back to an INI file in the same format that LoadPreflightProfile consumes The two functions are exact inverses for well-formed profiles, so callers can build a 'load preset, tweak, save' workflow: P := GetBuiltInPreflightProfile('compact'), edit P.DisableChecks, then SavePreflightProfile(P, 'tuned.ini') for later reuse.

CreatePreflightReportWithProfile غلاف مريح يجمع CreatePreflightReport وLoadPreflightProfile وApplyPreflightProfile ومحولات format حتى يصدر المستدعي الذي يملك PDF مصدرًا وكلمة مرور اختيارية وملف profile وتنسيق هدف استدعاء واحدًا بدل تسلسل أربعة استدعاءات. تمرير ProfileFile فارغ يتجاوز خطوة profile

يعيد MergePreflightProfiles الاتحاد المزال التكرار لملفي profile: تجمع DisableChecks وDisableWarnings الأسماء من كلا الإدخالين، وDisableHints هو OR منطقي. يفيد لوضع preset فوق تعديلات خاصة بالمشروع

DiffPreflightProfiles reports the structural difference between two profiles. Returns True when they are equivalent; otherwise False with OnlyInA and OnlyInB filled with newline-separated lines of the form check:<name>, warn:<name>, or option:hints=false describing which entries are exclusive to each side.

EmbedPreflightReportAsXMP is an archival-friendly variant of EmbedPreflightReportInPDF: it writes a copy of the source PDF with the preflight report appended as a PDF-style comment block whose payload is XMP / RDF (xmlns:hotpdf="http://www.loslab.com/hotpdf/preflight/") Each report line becomes a hotpdf:<name> element with severity carried as an attribute on check rows XMP-aware tools that scan a file for xpacket markers can surface the embedded report; PDF readers continue to ignore the appended bytes because they fall outside the object graph. This is intentionally not a spec-compliant XMP integration: the XMP payload is not referenced from the catalog /Metadata entry, so XMP readers that only follow the catalog reference will not see it.

يشكل ConvertPreflightReportToVeraPDFStyle تقرير HotPDF preflight في مستند JSON يتبع الخط العام لإخراج veraPDF، مع حقل profile أعلى، ومصفوفة jobs تحتوي itemDetails / taskResult / validationResult، ومصفوفة ruleViolations داخل validationResult.details. الإخراج بأسلوب HotPDF وليس wire-compatible مع veraPDF، والهدف تسهيل تكيف الأدوات التي تستهلك veraPDF JSON مع إخراج HotPDF

مثال

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;

انظر أيضا