مقاله فنی

خروجی PDF 2.0، PDF/A-4 و PDF/UA-2 با HotPDF در Delphi

HotPDF اسناد PDF 2.0 بومی را از Delphi و C++Builder می‌نویسد، شامل سه profile آرشیوی PDF/A-4 و خروجی دسترس‌پذیر PDF/UA-2 با عنصر ساختار دارای فضای نام. انتخاب آن‌ها به دو ویژگی ختم می‌شود، اما استانداردهای پشت آن ویژگی‌ها بیشتر از آنچه شماره نسخه پیشنهاد می‌کند تغییر کرده‌اند: PDF/A-4 حروف انطباقی که همه با PDF/A-2 یاد گرفتند را حذف کرد، و PDF/UA-2 فضاهای نام ساختار معرفی کرد که یک سند بخش ۱ هرگز نداشت

این مقاله پوشش می‌دهد چه چیزی واقعاً در فایل تولیدشده تغییر می‌کند، و کدام اشتباهات HotPDF در EndDoc به یک استثنا تبدیل می‌کند به‌جای سندی که در سایت مشتری در اعتبارسنجی شکست می‌خورد

شناسایی PDF/A-4 چگونه از بخش 2 و 3 متفاوت است

PDF/A-4 خود را با شماره بخش و سال بازبینی شناسایی می‌کند، بدون حرف انطباق برای بخش پایه. PDFACompliance را روی '4' تنظیم کنید و HotPDF pdfaid:part=4 با pdfaid:rev=2020 و اصلاً هیچ pdfaid:conformance emit می‌کند. حرف گم نشده — بخش ۴ هیچ سطح A/B/U ندارد، چون الزاماتی که قبلاً آن‌ها را جدا می‌کرد در بخش پایه تاشده

دو پسوند یک حرف نگه می‌دارند. '4E' PDF/A-4e را برای اسناد مهندسی انتخاب می‌کند و انطباق E را emit می‌کند، که مسیرهای annotation برای 3D و RichMedia را که profileهای دیگر ممنوع می‌کنند مجاز می‌کند. '4F' PDF/A-4f را انتخاب می‌کند و انطباق F را emit می‌کند، که یک فایل جاسازی‌شده با هر فرمتی را مجاز می‌کند. هر سه یک سرآیند PDF 2.0 اعمال می‌کنند، بررسی‌های output intent و فراداده معمول PDF/A را الزام می‌کنند، و رمزنگاری را ممنوع می‌کنند — یک فایل آرشیوی رمزنگاری‌شده تناقضی است که استاندارد به آن نمی‌پردازد

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'invoice-archive.pdf';
    Pdf.PDFACompliance := '4F';   // PDF/A-4f: associated files of any format
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 760, 0, 'Invoice 2026-0731');
    Pdf.AddPDFAssociatedFile('invoice.xml', 'text/xml',
      'Structured invoice data', 'Data', LoadInvoiceBytes);
    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

AddPDFAssociatedFile فایل را جاسازی می‌کند، FileSpec آن را با یک /AFRelationship می‌سازد، و آن را هم در آرایه /AF کاتالوگ و هم در name tree برای EmbeddedFiles ثبت می‌کند. هر دو ثبت الزامی‌اند؛ فایلی که تنها در یکی فهرست‌شده شایع‌ترین دلیل یک فاکتور هیبریدی است که یک بررسی سریع چشمی را می‌گذراند و در یک اعتبارسنجی واقعی شکست می‌خورد. رشته رابطه Source، Data، Alternative، Supplement یا Unspecified را می‌پذیرد، و profile فعال باید PDF/A-3، PDF/A-4e یا PDF/A-4f باشد — profile بخش پایه ۴ فایل‌های مرتبط را نمی‌پذیرد. نام قدیمی‌تر AddPDFA3AssociatedFile هنوز برای کد موجود کار می‌کند

PDF/UA-2 چه چیزی را می‌خواهد که PDF/UA-1 نمی‌خواست

PDF/UA-2 PDF 2.0 را اعمال می‌کند و pdfuaid:part=2 با pdfuaid:rev=2024 را emit می‌کند، و فضاهای نام را در درخت ساختار معرفی می‌کند. یک سند بخش ۱ یک واژگان تخت از نقش‌های استاندارد داشت. یک سند بخش ۲ می‌تواند نقش‌های سفارشی حمل کند به‌شرطی که هر یکی به یک فضای نام اعلام‌شده تعلق داشته باشد، که همان چیزی است نشانه‌گذاری خاص دامنه را برای فناوری کمکی به‌جای حدس قابل خواندن می‌کند

دو روش این را پیاده می‌کنند. RegisterStructureNamespace یک دیکشنری /Type /Namespace غیرمستقیم می‌سازد یا بازاستفاده می‌کند و آن را در StructTreeRoot /Namespaces فهرست می‌کند، و دیکشنری را برمی‌گرداند تا بتوانید بازاستفاده کنید. AddStructureElementNS یک عنصر ساختار می‌سازد که ورودی /NS آن به آن دیکشنری اشاره می‌کند، که همان چیزی است یک نام نقش خارج از مجموعه استاندارد را مجاز می‌کند. فراخوانی‌های مکرر با همان URI یک دیکشنری را بازاستفاده می‌کنند به‌جای انباشت نسخه‌های تکراری

var
  Root: THPDFDictionaryObject;
begin
  Pdf.PDFUACompliance := True;
  Pdf.PDFUAPart := 2;             // part 2 forces PDF 2.0
  Pdf.Lang := 'en-US';
  Pdf.BeginDoc;
  Root := Pdf.AddStructureElement('Document', nil);
  Pdf.AddStructureElementNS('WidgetGroup',
    'https://example.com/ns/widgets', Root);
  Pdf.EndDoc;
end;

Lang اینجا تزئین نیست. یک سند تگ‌دار بدون زبان طبیعی اعلام‌شده یک screen reader را در حدس تلفظ رها می‌کند، و PDF/UA آن حذف را به‌عنوان یک نقص در نظر می‌گیرد نه یک ترجیح

کدام خطاهای ساختار را EndDoc می‌گیرد؟

چهار مورد، و هر یکی به سندی متناظر است که در غیر این صورت شکسته به یک اعتبارسنجی می‌رسید. ریشه ساختار باید دقیقاً یک عنصر Document سطح بالا داشته باشد. هر دیکشنری فضای نام باید غیرمستقیم، به‌نوع Namespace، و حامل یک URI یکتای غیرخالی باشد. هر ارجاع /NS عنصر ساختار باید به دیکشنری‌ای حل شود که واقعاً در آرایه ریشه /Namespaces فهرست‌شده. و یک نقش بدون فضای نام باید یک نقش استاندارد PDF 2.0 باشد یا از طریق RoleMap حل شود

این‌ها در EndDoc شلیک می‌شوند چون همان آخرین لحظه‌ای است که کل درخت در حافظه وجود دارد و اولین لحظه‌ای است که کامل است. گرفتن آن‌ها زودتر یعنی رد کردن وضعیت‌های میانی معتبر؛ گرفتن آن‌ها دیرتر یعنی اصلاً نگرفتنشان. پیامد عملی برای کد شما این است که یک bug ساختاری در پایان تولید با پیامی که نام مسئله را می‌آورد ظاهر می‌شود، به‌جای آنکه هفته‌ها بعد به‌عنوان یک گزارش veraPDF که کسی از یک مشتری فوروارد می‌کند ظاهر شود

نقش‌های PDF 2.0 که ارزش دانستن دارند

enum نقش تایپ‌شده DocumentFragment، Aside، Title، FENote، Sub، Em، Strong و Artifact را کسب می‌کند. سه مورد از آن‌ها نحوه نشانه‌گذاری اسناد تجاری معمول را تغییر می‌دهند. Aside در نهایت به نوارهای کناری و pull quoteها خانه‌ای می‌دهد که یک Sect سوءاستفاده‌شده نباشد. FENote پاورقی‌ها و endnoteها را به‌عنوان آنچه هستند علامت‌گذاری می‌کند، تا یک خواننده بتواند آن‌ها را عرضه کند به‌جای درهم‌آمیختن با متن بدنه. Em و Strong حدس معنایی را که از نشانه‌گذاری تأکید به‌عنوان قالب‌بندی سطح span می‌آمد جایگزین می‌کنند

overload رشته به‌اضافه فرم باز Hn از جمله H7 و فراتر را می‌پذیرد. PDF 1.7 در H6 متوقف می‌شد، که اسناد فنی عمیق را مجبور به تخت‌کردن outlineشان یا بازاستفاده سطح‌ها می‌کرد. اگر اسناد استاندارد، کدهای قانونی یا کاتالوگ قطعات تولید می‌کنید، این به‌تنهایی می‌تواند دلیلی برای حرکت دادن خروجی به PDF 2.0 باشد

چه چیزی را قبل از تعویض خروجی تولید بررسی کنید

PDF 2.0 یک تغییر سرآیند با دمی طولانی است. ابزارهای ingest آرشیو قدیمی‌تر، برخی RIPهای چاپ و شمارتی تعجب‌آور از viewerهای line-of-business فقط تا PDF 1.7 را می‌پذیرند، و آن‌ها روی سرآیند شکست می‌خورند نه روی هر چیزی که شما اشتباه کرده‌اید. قبل از تعویض، سیستم‌های مصرف‌کننده را تأیید کنید، و به یاد داشته باشید که انتخاب یک profile برای PDF/A-4 یعنی انتخاب PDF 2.0 چه درخواست کرده باشید چه نه

ترتیب امن این است که PDF/A-3 را برای اسنادی که به خواننده‌های ناشناس خارج می‌شوند نگه دارید، PDF/A-4f را برای آرشیوهای داخلی که ingest را کنترل می‌کنید استفاده کنید، و PDF/UA-2 را تنها جایی بپذیرید که خط‌مشی دسترس‌پذیری آن را نام می‌برد. اگر اول روی جانب آرشیوی کار می‌کنید، راهنماهای اعتبارسنجی PDF/A، PDF/X و PDF/UA و فاکتورهای هیبریدی ZUGFeRD و Factur-X روی PDF/A-3 انتخاب‌های profileی را پوشش می‌دهند که قبل از شماره نسخه اهمیت دارند، و یادداشت‌های گزارش‌دهی خودکار preflight نشان می‌دهند چگونه حکم را بخشی از build کنید به‌جای یک مرحله دستی

HotPDF کل سطح تألیف PDF 2.0 را به‌عنوان کد VCL بومی برای Delphi و C++Builder حرکت می‌دهد، تا خروجی PDF/A-4 و PDF/UA-2 هیچ موتور خارجی یا redistributable نیاز نداشته باشد — صفحه جزء HotPDF profileهای پشتیبانی‌شده و نسخه‌های RAD Studio را فهرست می‌کند