Structure

Structure

تغطي هذه الصفحة تنقل المستند والهيكل المنطقي: المخططات (الإشارات المرجعية)، جداول المحتويات، الوجهات المسماة، وشجرة الهيكل الموسومة المستخدمة لإمكانية الوصول وإعادة التدفق.


المخططات (الإشارات المرجعية)

Document.GetOutlines() تُعيد شجرة المخطط الحالية كـ OutlineItem[] ([] عندما لا يوجد /Outlines); Document.SetOutlines() تستبدلها — تمرير [] يزيل المخطط بالكامل. كل OutlineItem يحتوي على Title، وDest (رقم صفحة أو وجهة مسماة)، وChildren اختياري للتعشيق، وتنسيق (Color، Bold، Italic، Open).

const items: OutlineItem[] = sections.map((s) => {
  const item: OutlineItem = { Title: s.title, Dest: { name: s.dest } };
  if (s.subtype === 'sales') {
    item.Open = true;
    item.Children = ['Pasta', 'Pizza', 'Antipasti']
      .map((cat) => ({ Title: cat, Dest: { name: s.dest } }));
  }
  return item;
});
doc.SetOutlines(items);

جدول المحتويات

Page.AddTOC() تُظهر قائمة من كائنات TOCEntry — كل منها يحتوي على title وpage رقم الهدف — داخل مستطيل على الصفحة، مع عناوين مُلتفة، ونقاط توصيل، وعناوين صفحات مُحاذاة إلى اليمين. تُرجع AddTOCResult تُبلغ عن عدد الإدخالات التي تم رسمها، وعند كون الصندوق صغيرًا جدًا، تُبلغ عن remainder التي لم تتسع.

page.AddTOC(
  sections.map((s, i) => ({ title: `${i + 1}. ${s.title}`, page: s.page.Number })),
  [72, 160, 400, 400],
  { font: 'Helvetica', fontSize: 13, rowGap: 18 },
);

الوجهات المسماة

Document.GetNamedDestinations() تُعيد كل الوجهة المُسماة — بدمج شجرة أسماء /Names /Dests والقاموس القديم /Dests — كأزواج { name, dest }، حيث إن dest هو PageDest ({ page, view }). هذه هي نفس الأهداف المُسماة التي يمكن لـ OutlineItem.Dest أو توضيح ارتباط الإشارة إليه بالاسم بدلاً من رقم صفحة صريح.

const destNames = new Set(doc.GetNamedDestinations().map((d) => d.name));
for (const { name, dest } of doc.GetNamedDestinations()) {
  console.log(name, '-> page', dest.page);
}

شجرة البنية الموسومة

Document.AutoTag() تستنتج وتؤلف /StructTreeRoot من تخطيط الصفحة — العناوين عن طريق تجميع أحجام الخط، الفقرات عن طريق كتل النص، الجداول عن طريق هندسة الحواشي، وقرارات /Figure مقابل /Artifact لكل صورة — وتُعيد AutoTagReport مع عدد لكل نوع عنصر. Document.GetStructTree() تقرأ StructTreeRoot الناتج، أو null عندما يكون المستند غير موسوم.

const report = doc.AutoTag({ lang: 'en-US', title: 'Quarterly Report', tables: true });
console.log(report.headings, report.paragraphs, report.tables, report.figures);

const tree = doc.GetStructTree();
console.log(tree ? tree.GetText() : '(no structure tree)');

المحتوى الذي يُضاف بعد أن AutoTag() قد تم تشغيله — مثل صفحة تُملأ لاحقًا — لا يغطيه ذلك المرور ولن يتم وضع علامة مزدوجة عليه. StructTreeRoot.Append() و StructElement.MarkContent() هما API التحرير اليدوي إلى جانب الطريقة الاستدلالية: Append() يضيف عنصرًا فرعيًا من نوع معين، وMarkContent() يحدد منطقة صفحة كأنها تنتمي إلى ذلك العنصر.


نصائح وأفضل الممارسات

  • شغِّل Document.AutoTag() مرة واحدة، بعد أن يصبح محتوى الصفحة نهائيًا — فهو لا يعيد وضع علامات على المحتوى المضاف لاحقًا، لذا ضع علامة يدوية على أي شيء يُضاف فيما بعد باستخدام StructTreeRoot.Append() / StructElement.MarkContent().
  • مرّر opts.title إلى AutoTag() — فهو أيضًا يحدد /ViewerPreferences /DisplayDocTitle، وهو ما يتطلبه PDF/UA جنبًا إلى جنب مع عنوان المستند.
  • يمكن لـ OutlineItem.Dest استهداف إما صفحة صريحة أو وجهة مُسماة ({ name: '...' }) — استخدم الوجهات المُسماة عندما قد يتغير رقم الصفحة المستهدفة مع تغير المحتوى.
  • تحقق من AddTOCResult.remainder عندما يكون الترقيم التلقائي معطلاً — صندوق جدول المحتويات صغير جدًا لجميع الإدخالات يتوقف عن الرسم بصمت بدلاً من تجاوز حد الصندوق.

مشكلات شائعة

المشكلةالسببالإصلاح
Document.GetStructTree() يرجع nullلم يتم وسم المستنداستدعِ Document.AutoTag() أو Document.CreateStructTree() أولاً
رابط عنصر المخطط لا يتم حلهإن Dest الخاص به يحدد وجهة غير موجودة في Document.GetNamedDestinations()تأكد من وجود الوجهة المسماة، أو استخدم صفحة صريحة Dest بدلاً من ذلك
Page.AddTOC() يتوقف قبل القسم الأخيرالهدف rect صغير جدًا لكل إدخال وautoPaginate معطلوسّع الـrect، مرّر autoPaginate: true، أو عالج AddTOCResult.remainder
المحتوى المضاف بعد AutoTag() غير موجود في شجرة الهيكلAutoTag() يعلّم فقط المحتوى الموجود عندما تم تشغيلهضع علامة يدوية على المحتوى اللاحق باستخدام StructTreeRoot.Append() / StructElement.MarkContent()

FAQ

كيف أضيف إشارات مرجعية إلى ملف PDF؟

أنشئ مصفوفة من كائنات OutlineItem (Title, Dest, اختياري Children) ومرّرها إلى Document.SetOutlines().

هل يمكن لجدول المحتويات أن يمتد على صفحات متعددة؟

نعم — مرّر autoPaginate: true في خيارات Page.AddTOC()، أو تحقق من AddTOCResult.remainder واستدعِ AddTOC() مرة أخرى على صفحة جديدة لأي شيء لم يتسع.

كيف أجعل ملف PDF قابلاً للوصول (موسومًا)؟

استدعِ Document.AutoTag()، الذي يستنتج العناوين والفقرات والجداول والرسوم من تخطيط الصفحة. للمحتوى المضاف لاحقًا، أو حيث تحتاج نتيجة الخوارزمية إلى تصحيح، استخدم StructTreeRoot.Append() وStructElement.MarkContent() مباشرةً.

ما الفرق بين وجهة رقم الصفحة ووجهة مسماة؟

وجهة رقم الصفحة (PageDest) تستهدف صفحة صريحة ذات ترقيم يبدأ من 1. وجهة مسماة (NamedDest) تستهدف اسمًا يقوم عارض المستند بحلّه عبر جداول الوجهات المسماة الخاصة بالمستند — وهذا مفيد عندما قد تتحرك الصفحة المستهدفة.


API Reference ملخص

فئة/طريقةوصف
Document.GetOutlines() / Document.SetOutlines()قراءة أو استبدال شجرة مخطط المستند (الإشارة المرجعية)
OutlineItemعقدة مخطط واحدة: Title، Dest، اختياري Children
Page.AddTOC()عرض جدول المحتويات داخل مستطيل الصفحة
TOCEntry / AddTOCResultبيانات صف TOC، ونتيجة رسمه
Document.GetNamedDestinations()قائمة بكل الوجهات المسماة في المستند
Document.AutoTag()استنتاج وإنشاء شجرة بنية موسومة من تخطيط الصفحة
Document.GetStructTree() / Document.CreateStructTree()اقرأ أو أنشئ StructTreeRoot الخاص بالمستند
StructTreeRoot.Append() / StructElement.Append() / StructElement.MarkContent()أنشئ يدويًا أو وسّع شجرة الهيكل

انظر أيضاً

 العربية