تخطَّ إلى المحتوى

محركات التخطيط المخصّصة واعتراض النص في أثناء التخطيط

لا يوفّر ⁨NextPDF⁩ واجهة لمحرك تخطيط قابل للتوصيل. استخدم عقد امتداد التخطيط العام، TextPreprocessorInterface، لربط النص في أثناء التخطيط. تتيح لك أحداث دورة حياة المحتوى مراقبة ما ينتجه التخطيط.

Terminal window
composer require nextpdf/core:^3

مسار التخطيط داخلي، ويشمل تخطيط المحارف، وتجزئة الخط، وإخراج ⁨ToUnicode CMap⁩، وشجرة البنية. لا يسمح لك ⁨NextPDF⁩ باستبداله. يعتمد استقرار إخراج البايتات ومطابقة ⁨tagged-PDF⁩ على بناء واحد مُحكَم التحكّم.

ومع ذلك، يكشف ⁨NextPDF⁩ عن نقطة ما قبل التخطيط: TextPreprocessorInterface. يتلقّى التنفيذ النص الخام ويُعيد نتيجة مجزّأة قبل أن يدخل ذلك النص في تخطيط المحارف، أو تجزئة الخط، أو ⁨ToUnicode CMap⁩، أو شجرة البنية. استخدم هذا المسار المدعوم لتغيير محتوى النص دون المساس بمحرك التخطيط.

ينص ⁨PHPDoc⁩ في المصدر على قاعدة صارمة: يجب ألّا يُغيّر التنفيذ آلية عمل التخطيط. يجب ألّا يُضيف محارف تؤثّر في التخطيط مثل تغذية السطر، أو إرجاع العربة، أو الجدولة، ويجب أن يحافظ على ترتيب القراءة المنطقي. يمثّل المعالج المسبق استبدالًا للمحتوى؛ فهو لا يتّخذ قرارات تخطيط. التزم بهذه القاعدة، وإلا تعطّل استقرار الإخراج وإمكانية الوصول.

لمراقبة نتيجة التخطيط، لا لتغييرها، استخدم أحداث دورة حياة المحتوى في مشغّلات الإجراءات ومستمعو الأحداث. يُطلَق ContentRenderedEvent بعد رسم المحتوى على صفحة. ويُطلَق FontLoadedEvent مرة واحدة لكل عائلة خط ونمط.

NextPDF\Contracts\TextPreprocessorInterface (مستقر، منذ 1.9.0):

الطريقةالقيمة المُعادةالغرض
process(string $text)TextPreprocessResultحوّل النص الخام قبل مسار العرض، وأعِد نتيجة مجزّأة مع بيانات وصفية خاصة بالتنقيح.

إنّ NextPDF\Contracts\TextPreprocessResult المُعاد هو كائن قيمة مُجمّد. يبقى توقيع بانيه وخصائصه العامة مستقرة، ولا تتغيّر في إصدار ثانوي أو تصحيحي. قد تُضاف طرق جديدة.

يقنّع المعالج المسبق الصغير أدناه رمزًا ثابتًا. وهو لا يُضيف محارف تؤثّر في التخطيط، ويحافظ على ترتيب القراءة.

<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;
use NextPDF\Contracts\TextPreprocessResult;
use NextPDF\Contracts\TextSegment;
final class TokenMaskingPreprocessor implements TextPreprocessorInterface
{
public function process(string $text): TextPreprocessResult
{
$masked = \str_replace('SECRET-TOKEN', '••••••••••••', $text);
return new TextPreprocessResult([
new TextSegment($masked, redacted: $masked !== $text),
]);
}
}

يُبقي المعالج المسبق الإنتاجي قواعد المطابقة في مكان واحد. ويفشل بأمان عند ورود نمط غير صالح، ولا يُسجّل النص الأصلي مطلقًا.

<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;
use NextPDF\Contracts\TextPreprocessResult;
use NextPDF\Contracts\TextSegment;
use Psr\Log\LoggerInterface;
final class PatternRedactionPreprocessor implements TextPreprocessorInterface
{
/**
* @param non-empty-string $pattern A valid PCRE pattern for sensitive spans
*/
public function __construct(
private readonly string $pattern,
private readonly LoggerInterface $logger,
) {}
public function process(string $text): TextPreprocessResult
{
$result = \preg_replace($this->pattern, '[REDACTED]', $text);
if ($result === null) {
// Fail closed: never emit unredacted text on a pattern error.
$this->logger->error('Redaction pattern failed; substituting empty text');
return new TextPreprocessResult([new TextSegment('', redacted: true)]);
}
return new TextPreprocessResult([
new TextSegment($result, redacted: $result !== $text),
]);
}
}
  • لا استبدال للتخطيط. لا يمكنك استبدال تخطيط الصناديق، أو فصل الأسطر، أو ترقيم الصفحات عبر هذا العقد. فتوصيل محرك تخطيط من طرف ثالث خارج النطاق بحكم التصميم.
  • فرض القاعدة. إذا أضفت \n، أو \r، أو \t في process()، فإنك تُفسد التخطيط وتُعطّل الإخراج المستقر. يثق المحرك بهذه القاعدة؛ ولا يُعيد فحص مخرجاتك بحثًا عن محارف تؤثّر في التخطيط.
  • ترتيب القراءة. إذا أعدت ترتيب الأجزاء، فإنك تُعطّل ترتيب القراءة في ⁨tagged-PDF⁩ ومطابقة ⁨PDF/UA.⁩
  • مسؤولية واحدة. يمثّل المعالج المسبق استبدالًا للمحتوى. استخدم أحداث دورة الحياة للمراقبة، ولا تُدخل آثارًا جانبية عبر process().

يُنفَّذ process() مرة واحدة لكل مقطع نصي على المسار الحرج للتخطيط. حافظ على انخفاض استخدام الذاكرة. حضّر الأنماط مرة واحدة في الباني، لا عند كل استدعاء. لا تكلّف أحداث دورة حياة المحتوى شيئًا عندما لا يكون أي مستمع مرتبطًا.

استخدم TextPreprocessorInterface لإزالة المحتوى الحسّاس قبل أن يصل إلى دفق المحتوى، أو مجموعات الخط الفرعية، أو البيانات الوصفية. وبما أنه يُنفَّذ قبل التجزئة و ⁨ToUnicode CMap⁩، فإن المحارف المُنقّحة لا تدخل الملف مطلقًا. عامِل فشل المعالج المسبق على أنه فشل بأمان، وأخرِج نصًا فارغًا أو مُقنّعًا بدلًا من النص الأصلي.

لا تقدّم هذه الصفحة أي ادّعاءات معيارية بشأن التوقيع أو الأرشفة. تجعل قاعدة ترتيب القراءة العقد متوافقًا مع احتياجات ⁨tagged-PDF.⁩ يغطّي مرجع إمكانية الوصول المطابقة على مستوى الوسوم.

يوفّر ⁨NextPDF Pro⁩ استراتيجيات جاهزة للإنتاج للمعالجة المسبقة للنص، بما في ذلك تنقيح معلومات التعريف الشخصية (⁨PII⁩) المضبوط لأنواع المستندات الشائعة. في ⁨Core⁩، تكتب تطبيق TextPreprocessorInterface بنفسك، أو تعتمد بناءً مُتحقَّقًا منه من الإصدار المدفوع عبر العقد العام نفسه.

يعرّف المسرد المعالج المسبق للنص ونقطة الامتداد؛ راجع المسرد المنشور للحصول على كل تعريف قياسي.