مقاله فنی

تبدیل PDF به PDF/A و تعمیر فراداده آن

ConvertToPDFA در یک فراخوانی یک سند معمولی را به سند آرشیوی تبدیل می‌کند: آنچه بخش انتخابی ممنوع می‌کند را حذف می‌کند، آنچه بخش الزام می‌کند را اضافه می‌کند، بخشی که سند ادعا می‌کند را بیان می‌کند، و سپس نتیجه را بررسی می‌کند. ادعا تنها زمانی برآورده‌شده گزارش می‌شود که بررسی بگذرد، و GetPDFAConversionReport فهرست می‌کند چه کاری انجام شده و چه چیزی هنوز مانع است

آخرین ویژگی تصمیم طراحی است که ارزش تأمل دارد. یک مبدل که ادعا را بدون بررسی مهر می‌زند بدتر از هیچ مبدلی نیست، چون فایلی که می‌گوید آرشیوی است و نیست مستقیماً از همان سیستم‌هایی عبور می‌کند که در غیر این صورت آن را گرفتار می‌کردند. شکست سال‌ها بعد، در یک ممیزی، روی سندی ظاهر می‌شود که هیچ‌کس نمی‌تواند دوباره تولید کند

چرا یک PDF معتبر به‌نظر می‌رسد در یک بررسی PDF/A شکست می‌خورد؟

اغلب چون دو جایی که یک PDF می‌گوید چه کسی آن را نوشته موافق نیستند. یک اعتبارسنجی هم دیکشنری اطلاعات سند و هم بسته XMP را می‌خواند و فایلی را که در آن تفاوت دارند رد می‌کند — و اکثر فایل‌هایی که روی این نکته شکست می‌خورند اصلاً نیمه XMP نوشته نشده بوده

RepairDocumentMetadata آن‌ها را به توافق می‌آورد و برمی‌گرداند چند entry تعمیر کرده. جایی که فقط یک نیمه مقدار حمل می‌کند، نیمه دیگر از آن پر می‌شود، پس هیچ‌چیز از پیش ثبت‌شده دور ریخته نمی‌شود. هیچ‌کس نباید تصمیم بگیرد کدام کپی معتبر است، چون در عمل یک کپی خالی است

یک تعمیر دوم در همان فراخوانی وجود دارد که یک مورد ظریف‌تر را می‌گیرد. یک سند که در حالت PDF/A تنظیم شده، شناسایی استانداردهایش را در صورت گم‌شدگی بازمی‌گرداند، که هر زمان یک فراخواننده بسته XMP خودش را فراهم کند رخ می‌دهد. بدون آن شناسایی، یک اعتبارسنجی فایل را به‌عنوان یک PDF معمولی می‌خواند و هر قانون بخش ادعاشده را به‌عنوان برآورده‌نشده گزارش می‌کند — یک شکست نمایشی با یک علت کوچک

var
  Lib: TPDFlib;
  Repaired: Integer;
begin
  Lib := TPDFlib.Create;
  try
    Lib.LoadFromFile('incoming.pdf', '');
    Repaired := Lib.RepairDocumentMetadata;
    Log(Format('%d metadata entries brought into agreement', [Repaired]));
    Lib.SaveToFile('incoming-fixed.pdf');
  finally
    Lib.Free;
  end;
end;

انتخاب بخش قبل از تبدیل

SetPDFAMode و ConvertToPDFA شماره‌گذاری حالت مشترکی دارند، و سه مورد از مقادیر اخیر هستند. حالت 9 برابر PDF/A-4 است، بخش ساخته‌شده روی PDF 2.0. حالت 10 برابر PDF/A-4e است، که به‌اضافه 3D و رسانه غنی را مجاز می‌کند، و حالت 11 برابر PDF/A-4f است، که یک فایل جاسازی‌شده با هر فرمتی را مجاز می‌کند

بخش 4 خود را متفاوت از بخش‌های قبلش شناسایی می‌کند: با شماره بخش و سال انتشار بخشش، بدون حرف انطباق برای PDF/A-4 ساده و حرف E یا F برای دو پسوند. بررسی بخش 4 را شناسایی می‌کند، فایل‌هایش را در برابر PDF 2.0 به‌جای 1.7 قضاوت می‌کند، و یک فایل بخش 4 که سال بازبینی خود را بیان نمی‌کند را گزارش می‌کند

هر فایل جاسازی‌شده در یک سند بخش 4 بیان می‌کند چگونه به سند مربوط است، همان‌طور که بخش 3 و 4 هر دو الزام می‌کنند. این همان قانونی است که قبلاً پیوست‌های معمولی را می‌گرفت: رابطه فقط برای پیوست‌های بعد از اولی نوشته می‌شد و هرگز برای آخری، پس سندی با یک پیوست — مورد رایج — اصلاً هیچ‌کدام حمل نمی‌کرد و دقیقاً روی همان نکته در اعتبارسنجی شکست می‌خورد

var
  Verdict: Integer;
begin
  Lib.LoadFromFile('report.pdf', '');
  Verdict := Lib.ConvertToPDFA(9);        // 9 = PDF/A-4, 10 = 4e, 11 = 4f
  Memo1.Lines.Text := Lib.GetPDFAConversionReport;
  if Verdict = 1 then
    Lib.SaveToFile('report-pdfa4.pdf')
  else
    Log('conversion incomplete - see the report for what stands in the way');
end;

گزارش تبدیل برای چیست

تصمیم‌گیری درباره کار بعدی. یک تبدیل که موفق می‌شود گزارشی نیاز ندارد؛ یک تبدیل که نمی‌شود کل دلیل وجود گزارش است. برخی موانع توسط یک مبدل قابل‌حذف هستند و برخی نیستند — رمزنگاری، محتوای ممنوعه که معنا حمل می‌کند، یک برنامه فونت که ساده روی ماشین موجود نیست. گزارش آنچه انجام شده را از آنچه باقی مانده متمایز می‌کند، که «تبدیل شکست خورد» را به یک مورد کاری تبدیل می‌کند

حکم را به‌عنوان gate در یک pipeline دسته‌ای در نظر بگیرید. تبدیل کنید، حکم را بخوانید، و فایل را مسیریابی کنید: آن‌هایی که گذشتند را آرشیو کنید، بقیه را با گزارش پیوست برای یک انسان صف کنید. آنچه نباید بکنید ذخیره خروجی یک تبدیل شکست‌خورده در آرشیو است چون بهتر از ورودی به‌نظر می‌رسد — اکنون ادعایی حمل می‌کند که بررسی از تأیید آن امتناع کرده

خواندن علامتی که فایل از قبل حمل می‌کند

قبل از تبدیل هر چیزی، بدانید سند درباره خود چه می‌گوید. یک بررسی PDF/A که نمی‌تواند علامت استانداردهای موجود را بخواند هر فایل را در برابر بخش 1 قضاوت می‌کند هرچه اعلام کرده باشد، که یعنی یک سند کاملاً معتبر PDF/A-2 یا PDF/A-3 به‌عنوان حمل‌کننده هیچ علامتی و داشتن نسخه‌ای خیلی بالا گزارش می‌شود — نقطه مقابل حقیقت

علامت خوانده می‌شود چه تولیدکننده آن را به‌عنوان عنصر XMP نوشته باشد یا به‌عنوان ویژگی. هر دو فرم XMP معمولی هستند، و پذیرفتن فقط یکی آن‌ها فایل‌های تولیدکنندگان دیگر را بدون علامت جلوه می‌دهد. اگر تا به حال تعجب کرده‌اید چرا سندی که جای دیگری اعتبارسنجی می‌شود در pipeline خودتان شکست می‌خورد، این یک جای خوب برای نگاه اول است

پاک‌سازی قبل از آرشیو، و باگی که ارزش دانستن دارد

تبدیل آرشیوی و پاک‌سازی اغلب با هم اجرا می‌شوند، چون محتوایی که یک خط‌مشی امنیتی می‌خواهد حذف شود به‌طور سنگینی با محتوایی که PDF/A ممنوع می‌کند همپوشانی دارد. SanitizeDocument جاوااسکریپت را حذف می‌کند، و حذف آخرین اسکریپت همچنین name tree خالی‌ای را که پشت سر می‌گذارد حذف می‌کند — درختی که در غیر این صورت هنوز به خواننده می‌گفت سند اسکریپت حمل می‌کند

نیمه دوم به روش سخت‌گیر آموخته شد: یک off-by-one در لیست بسته‌ها یعنی پاک‌سازی گزارش می‌کرد اسکریپت‌ها را حذف کرده در حالی که هیچ‌کدام را حذف نمی‌کرد، پس سندی که پاک‌سازی شده بود هنوز هنگام باز شدن اسکریپت‌هایش را اجرا می‌کرد. این استدلال خوبی برای اصل کلی است که کل این مقاله روی آن تکیه می‌کند — نتیجه را تأیید کنید به‌جای اعتماد به عملیات، در pipeline خودتان به همان اندازه کتابخانه

برای کارهای آرشیوی پیرامون، مرورهای preflight برای PDF/A و PDF/UA، حذف محتوای واقعی و سانسور، و شمای‌های پسوند XMP برای PDF/A-3 در Factur-X را ببینید، که جانب فراداده را وقتی سند آرشیوشده همچنین داده‌های ساختاریافته فاکتور حمل می‌کند پوشش می‌دهد

PDFlibPas یک کتابخانه PDF بومی Pascal برای Delphi، C++Builder و Lazarus است، تا تبدیل، تعمیر و اعتبارسنجی همگی درون پردازش خودتان بدون هیچ ابزار خارجی در زنجیره اتفاق بیفتد — صفحه محصول PDFlibPas را برای بخش‌های PDF/A پشتیبانی‌شده و پلتفرم‌ها ببینید