مقاله فنی

خودکارسازی بررسی‌های پیش‌از‌چاپ PDF در دلفی با HotPDF

فایل روی سیستم شما به درستی باز می‌شود. Acrobat آن را نشان می‌دهد، پیش‌نمایش چاپ درست به نظر می‌رسد و تمام صفحات سر جایشان هستند. سپس فایل به چاپخانه می‌رود یا وارد سیستم آرشیوی می‌شود که دسته فایل‌های ماهانه شما را دریافت می‌کند، و با یک پیام رد شدن بازمی‌گردد: تصاویر RGB در یک کار CMYK، نبود کلید /Trapped، یا هدف خروجی که با دستگاه چاپ مطابقت ندارد. هیچ ایرادی در سند وجود نداشت که کسی بتواند آن را ببیند. فایل در برابر یک پروفایل اشتباه بود و این پروفایل در جایی بررسی شد که شما در آنجا حضور نداشتید. Preflight نامی است که در مرحله پیش‌از‌چاپ برای این بررسی استفاده می‌شود، و سؤال اصلی این است که وقتی PDFها از کد دلفی خودتان بیرون می‌آیند نه از دسکتاپ یک طراح، جایگاه این بررسی کجاست

HotPDF تابعی برای فراخوانی بررسی پیش‌از‌چاپ (preflight) در اختیار شما قرار نمی‌دهد. این کامپوننت در دموی گرافیکی خود یک پنجره گزارش پیش‌از‌چاپ دارد، اما هیچ API در پس‌زمینه آن وجود ندارد که یک سرویس یا اسکریپت بیلد بتواند آن را فراخوانی کند و تظاهر به وجود آن، شما را به دنبال متدی می‌فرستد که وجود خارجی ندارد. این موضوع ممکن است به عنوان یک کمبود به نظر برسد تا زمانی که متوجه شوید برای فایل‌هایی که خودتان تولید می‌کنید، فراخوانی یک اعتبارسنج بر روی خروجی خودتان رویکرد درستی نیست. شما از قبل بر تمام ویژگی‌هایی که یک اعتبارسنج بررسی می‌کند، کنترل دارید. تفکیک کاربردی این است که تولیدکننده را از ایجاد یک فایل نامعتبر ناتوان کنید، و سپس این موضوع را با ابزاری که خودتان ننوشته‌اید اثبات نمایید

چرا باید خروجی خود را به روش متفاوتی بررسی کنید

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

علاوه بر این، یک دلیل اعتباری نیز برای واگذاری تأیید به ابزارهای خارجی وجود دارد. کتابخانه‌ای که خروجی خودش را تأیید می‌کند، در واقع دارد به امتحان خودش نمره می‌دهد. وقتی سیستم آرشیو یک مشتری یا RIP یک چاپخانه فایل شما را رد می‌کند، جمله «کامپوننت ما می‌گوید همه‌چیز مرتب است» هیچ اعتباری ندارد. اما تأیید از سوی veraPDF یا Acrobat اعتبار دارد، زیرا طرف مقابل نیز از همین ابزارها استفاده می‌کند

تطابق را به یک تنظیمات تبدیل کنید، نه یک چک‌لیست

لایه پیشگیری تنها یک پیکربندی است. با تنظیم PDFACompliance یا PDFXCompliance پیش از BeginDoc، کامپوننت HotPDF قوانین مربوطه را برای کل مرحله تولید اعمال می‌کند: فونت‌ها را تعبیه می‌کند، استفاده از DeviceRGB و DeviceCMYK را در برابر هدف خروجی اعلام شده بررسی می‌نماید و ویژگی‌هایی را که در پروفایل ممنوع شده‌اند، رد می‌کند. تناقضات در زمان اجرای EndDoc مشخص می‌شوند، جایی که دروازه‌های تطابق عمل می‌کنند تا از ارسال بی‌سر و صدای فایلی که در مراحل بعدی با شکست مواجه می‌شود، جلوگیری کنند. پس از ذخیره فایل، همین ویژگی‌ها آنچه را که واقعاً اعمال شده بازمی‌گردانند، که این دقیقاً همان واقعیتی است که گزارش خط لوله شما بیشتر از همه به آن نیاز دارد:

// Request PDF/X-4 compliance before generation starts
HotPDF1.PDFXCompliance := pdfx4;
HotPDF1.BeginDoc;
// ... drawing ...
HotPDF1.EndDoc;

// After EndDoc, read the flag back to confirm what was actually enforced.
// If your drawing code violated the standard (e.g. RGB in a CMYK intent)
// and you swallowed the exception, this value will have reverted.
if HotPDF1.PDFXCompliance <> pdfx4 then
  Log.Error('File generated, but PDF/X-4 compliance was dropped.');

این پرچم‌ها را در همان خطی از گزارش (log) قرار دهید که هش داده‌های ورودی و نسخه HotPDF ثبت می‌شوند. روزی که یک اعتبارسنج و تولیدکننده شما بر سر یک فایل اختلاف نظر پیدا کنند، آن خط به شما می‌گوید کدام الگو فایل را تولید کرده و کدام بیلد از کتابخانه بارگذاری شده است؛ در این صورت، بحثی که می‌توانست کل یک بعدازظهر وقت شما را بگیرد، به یک جستجوی ساده با grep تبدیل می‌شود. اهداف خروجی، پروفایل‌های ICC و تگ‌گذاری‌هایی که در پس‌زمینه این پرچم‌ها قرار دارند، به تفصیل در راهنمای خروجی‌های PDF/A، PDF/X و PDF/UA با HotPDF توضیح داده شده‌اند

یک دروازه اولیه کم‌هزینه برای فایل‌هایی که تولید نکرده‌اید

هر خط لوله‌ای صرفاً جنبه تولیدی ندارد. مشتریان فایل‌های PDF آپلود می‌کنند، اسکنرها آن‌ها را در یک پوشه می‌ریزند و همکاران آن‌ها را به ایمیل پیوست می‌کنند. ارسال هر کدام از این فایل‌ها به یک اعتبارسنج ساختاری کامل، باعث اتلاف زمان صف برای فایل‌هایی می‌شود که حتی باز هم نمی‌شوند. Direct File API در HotPDF به اندازه کافی از ساختار فایل را می‌خواند تا بدون نیاز به بارگذاری کل درخت اشیاء، به این سؤال پاسخ دهد که «آیا این فایل اصلاً یک PDF قابل استفاده است یا خیر»؛ که این ویژگی آن را به مکانی مناسب برای رد سریع خطاهای اولیه تبدیل می‌کند:

// Fast triage for incoming files before they reach the validator
HFile := THotPDF.DAOpenFileReadOnly(InPath, '');
try
  // If the handle is zero, the file is corrupt, not a PDF, or encrypted.
  // Do not send it to veraPDF.
  if HFile = 0 then
    Exit(False);

  // If the handle is valid but the page count is not positive, the PDF
  // is structurally useless. Reject it early.
  if THotPDF.DAGetPageCount(HFile) <= 0 then
    Exit(False);

  Result := True;
finally
  if HFile <> 0 then
    THotPDF.DACloseFile(HFile);
end;

دو واقعیت در مورد این API تعیین می‌کنند که چگونه باید از آن استفاده کنید. میانبر خواندن در حافظه مسطح (flat-memory) فقط برای ورودی‌های رمزنگاری‌نشده صدق می‌کند؛ اگر یک رمز عبور به DAOpenFileReadOnly بدهید، به طور بی‌صدا به حالت تجزیه کامل بازمی‌گردد. بنابراین فایلی که می‌دانید رمزگذاری شده است، باید پیش از تریاژ از طریق DecryptFile به یک کپی کاری ساده تبدیل شود. همچنین، DAGetPageCount روی هندلی که به درستی باز نشده باشد هیچ معنایی ندارد، بنابراین بررسی هندل باید سخت‌گیرانه باقی بماند و یک نتیجه غیرمثبت به معنای رد کردن است، نه تلاش مجدد. الگوهای بیشتری از این دست در مقاله Direct File API برای گردش کارهای PDF بزرگ موجود است

veraPDF، اجرا شده به عنوان بخشی از بیلد

برای هر فایلی که ادعا می‌کنید منطبق بر استاندارد PDF/A یا PDF/UA است، veraPDF همان اعتبارسنجی است که باید از آن استفاده کنید. این ابزار به صورت بدون رابط کاربری (headless) اجرا می‌شود، فایل‌ها را به صورت دسته‌ای دریافت می‌کند، خروجی XML یا JSON تولید می‌کند و هر شکست را با بند ایزو مربوطه نام‌گذاری می‌کند. بنابراین، شکست در قانونی مانند بند 6.2.2 از استاندارد ISO 19005-1 به جای این که شما را به حدس زدن وادارد، مستقیماً به یکی از تنظیمات تولیدکننده اشاره می‌کند. اجرای آن در دلفی به سادگی کنترل یک پردازش است:

// Drive veraPDF as an external process. The critical part is the timeout.
// A malformed PDF can send a parser into an infinite loop.
function ValidateWithVeraPDF(const PDFPath, ReportPath: string): Boolean;
var
  Cmd: string;
begin
  Cmd := Format('verapdf --format xml --report "%s" "%s"',
    [ReportPath, PDFPath]);
  // Use CreateProcess or JCL/MadExcept wrappers, but you MUST wait with
  // a timeout (e.g. 30000 ms), not INFINITE. If it times out, terminate
  // the veraPDF process and treat the PDF as rejected.
  Result := RunProcessWithTimeout(Cmd, 30000);
end;

محدودیت زمانی (timeout) در اینجا اهمیت خود را نشان می‌دهد. یک فایل ناقص می‌تواند هر تجزیه‌کننده‌ای را در شرایطی گرفتار کند که هرگز از آن خارج نشود، و یک انتظار بی‌پایان درون یک worker صف، بقیه صف را نیز با خود متوقف می‌کند. زمان انتظار را محدود کنید، به خطای timeout یک کد اختصاص دهید و فایل را برای بررسی انسانی کنار بگذارید. هنگام خواندن نتایج، XML را برای شناسه‌های قانون (rule identifiers) تجزیه کنید، نه برای متنی که قابل خواندن برای انسان است. شناسه‌های قانون در طول به‌روزرسانی‌های اعتبارسنج تغییر نمی‌کنند، در حالی که متن پیام‌ها ممکن است عوض شود؛ و یک کد پایدار چیزی است که مهندس پشتیبانی می‌تواند بر اساس آن تیکت‌های قدیمی را جستجو کند

نحوه اجرای پردازش دسته‌ای به اندازه این که هر فایل عبور می‌کند یا خیر، مهم است. به ازای هر فایل یک پردازش اجرا کنید، نه یک پردازش برای کل دسته؛ تا در صورت وجود ورودی مخرب، تنها هزینه آن همان محدودیت زمانی فایل باشد و نه بیشتر. تعداد پردازش‌های اعتبارسنجی را به تعداد هسته‌های پردازنده محدود کنید، زیرا ساخت گزارش XML پردازنده را به شدت درگیر می‌کند و تخصیص بیش از حد منابع تنها باعث افت عملکرد سیستم می‌شود. همچنین، برای اندازه فایل ورودی سقف تعیین کنید، زیرا یک کتاب اسکن‌شده دو گیگابایتی، فارغ از اینکه تجزیه‌کننده چقدر صبور باشد، تمام صف را به خود اختصاص خواهد داد. هیچ‌کدام از این موارد به معنای دقیق کلمه، پیش‌از‌چاپ (preflight) محسوب نمی‌شوند. این‌ها همان تفاوتی است که بین یک دروازه مقاوم در برابر حجم کار پایان ماه، و دروازه‌ای که در اولین شبی که خط لوله را ساعت ۲ بامداد متوقف می‌کند خاموش می‌شود، وجود دارد

در زمینه PDF/X، این رویکرد به بن‌بست می‌رسد. veraPDF این استاندارد را تأیید نمی‌کند، بنابراین بررسی کارآمد همچنان ابزار Preflight در Acrobat با پروفایل ISO 15930 است که چاپخانه شما مشخص کرده است. Acrobat نیازمند تعامل انسانی است، که به معنای نمونه‌برداری به جای پوشش کامل می‌باشد: بررسی اولین فایل تولید شده از یک الگوی جدید، به علاوه یک انتخاب تصادفی کوچک از هر دسته فایل. در این میان، دروازه خودکار کارهایی را مدیریت می‌کند که می‌توانند بدون نیاز به انسان انجام شوند. یک بررسی نمونه‌گیری شده که واقعاً اجرا شود، بهتر از یک اتوماسیون کامل است که برای همیشه نیمه‌کاره باقی بماند

گزارشی که هنوز یک سال بعد به آن نیاز خواهید داشت

یک دروازه پیش‌از‌چاپ دو بار سودمند واقع می‌شود. یک بار زمانی که فایلی نامعتبر را پیش از ورود متوقف می‌کند، و بار دیگر مدت‌ها بعد که کسی می‌پرسد چرا اجازه عبور یک فایل خاص داده شده است. آن لحظه دوم همان زمانی است که باید فرمت گزارش را تعیین کند، زیرا در این شرایط است که یک گزارش ناقص و مختصر شما را سردرگم رها می‌سازد. برای هر فایل بررسی‌شده، این اطلاعات را ثبت کنید: هش ورودی، پرچم‌های تطابق تولیدکننده و نسخه کتابخانه از روی خط گزارشِ (log) اشاره شده در بالا، نام و نسخه ابزار اعتبارسنج، پروفایلی که فایل با آن بررسی شده، موفقیت یا شکست عملیات، و شناسه‌های قانون نقض شده به همراه شماره صفحات (در صورت ارائه از سوی اعتبارسنج). این گزارش را در کنار فایلی که توصیف می‌کند ذخیره نمایید. اگر آن را در سیستم مجزایی ذخیره کنید، احتمالاً آن سیستم پیش از آرشیوی که در حال مستندسازی آن است، از رده خارج خواهد شد

موارد استثنا نیز باید مکتوب شوند. وقتی مشتری اصرار دارد فایلی ارسال شود که دروازه آن را رد می‌کند، راه‌حل این نیست که قانون را برای همه تسهیل کنید. ثبت کنید که چه کسی این فایل را تأیید کرده، بر چه اساسی و تا چه تاریخی، سپس این معافیت را به گزارش فایل پیوست نمایید. یک معافیت همراه با نام و تاریخ انقضا، تصمیمی است که مسئولیت آن بر عهده شخص خاصی است. اما کدی که به صورت موقت غیرفعال (commented out) شده، فاجعه‌ای است که منتظر زمان وقوع خود می‌باشد

یک عادت دیگر نیز وجود دارد که ارزش خود را ثابت می‌کند: وقتی فایلی در بررسی شکست می‌خورد، پیش از آنکه کسی تغییری در آن ایجاد کند، آن را در یک پوشه تست رگرسیون با نام مشخص کپی کنید. تقریباً هر مشکل پیش‌از‌چاپی که ارزش دیباگ کردن داشته باشد، به یک ورودی خاص برمی‌گردد. تیم‌هایی که این ورودی‌ها را حفظ می‌کنند، می‌توانند بروز مجدد مشکل را به جای انتظار برای تکرار در محیط عملیاتی، در عرض یک ساعت برطرف نمایند. ویژگی‌های تطابق و Direct File API که در اینجا نشان داده شدند، بخشی از کامپوننت HotPDF برای دلفی و C++Builder هستند که مستندات آن تمامی فراخوانی‌ها را به طور کامل پوشش می‌دهد