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Дані рядка змісту та результат його відображення
Document.GetNamedDestinations()Перелічити всі іменовані призначення в документі
Document.AutoTag()Вивести та створити тегове дерево структури з макету сторінки
Document.GetStructTree() / Document.CreateStructTree()Прочитати або створити StructTreeRoot документа
StructTreeRoot.Append() / StructElement.Append() / StructElement.MarkContent()Ручно створювати або розширювати дерево структури

Дивіться також

 Українська