///|
fn pdf_texttopdf_struct_parent_pages(
pages : ArrayView[@page.PdfPage],
) -> Array[@page.PdfPage] raise @core.PdfError {
let output : Array[@page.PdfPage] = []
for index, page in pages {
output.push({
..page,
rest: page.rest.add_dict_entry(
pdf_texttopdf_struct_parents_key(),
PdfInteger(index),
),
})
}
output
}
///|
fn pdf_texttopdf_tag_triples(
tags : ArrayView[Array[(String, Int)]],
) -> Array[(Int, Int, Int)] {
let output : Array[(Int, Int, Int)] = []
for page_index in 0.. Array[Array[(Int, Int, Int)]] {
let output : Array[Array[(Int, Int, Int)]] = []
for triple in triples {
if output.length() == 0 {
output.push([triple])
} else {
let current = output[output.length() - 1]
if current[0].0 == triple.0 {
current.push(triple)
} else {
output.push([triple])
}
}
}
output
}
///|
fn pdf_texttopdf_page_reference(
page_references : ArrayView[Int],
page_index : Int,
) -> @syntax.PdfObject raise @core.PdfError {
guard page_index >= 0 && page_index < page_references.length() else {
raise BadPageSpecification("texttopdf: page reference not found")
}
PdfIndirect(page_references[page_index])
}
///|
fn pdf_texttopdf_structure_elements(
document : PdfDocument,
parent_number : Int,
page_references : ArrayView[Int],
nodes : ArrayView[Array[(Int, Int, Int)]],
) -> Array[@syntax.PdfObject] raise @core.PdfError {
let output : Array[@syntax.PdfObject] = []
for parts in nodes {
let kids : Array[@syntax.PdfObject] = []
for part in parts {
let (_, page_index, mcid) = part
kids.push(
PdfDictionary([
(pdf_texttopdf_type_key(), PdfNameObject(pdf_texttopdf_mcr())),
(
pdf_texttopdf_pg_key(),
pdf_texttopdf_page_reference(page_references, page_index),
),
(pdf_texttopdf_mcid_key(), PdfInteger(mcid)),
]),
)
}
output.push(
PdfIndirect(
document.add_object(
PdfDictionary([
(pdf_structure_k_key(), PdfArray(kids)),
(pdf_texttopdf_p_key(), PdfIndirect(parent_number)),
(pdf_texttopdf_s_key(), PdfNameObject(pdf_texttopdf_p())),
]),
),
),
)
}
output
}
///|
fn pdf_texttopdf_structure_element_for_tag(
structure_elements : ArrayView[@syntax.PdfObject],
tag_number : Int,
) -> @syntax.PdfObject raise @core.PdfError {
guard tag_number >= 0 && tag_number < structure_elements.length() else {
raise BadPageSpecification("texttopdf: structure tag not found")
}
structure_elements[tag_number]
}
///|
fn pdf_texttopdf_parent_tree_entries(
page_count : Int,
triples : ArrayView[(Int, Int, Int)],
structure_elements : ArrayView[@syntax.PdfObject],
) -> Array[(Int, @syntax.PdfObject)] raise @core.PdfError {
let output : Array[(Int, @syntax.PdfObject)] = []
for page_index in 0.. Unit raise @core.PdfError {
let triples = pdf_texttopdf_tag_triples(tags)
let nodes = pdf_texttopdf_group_tag_triples(triples)
let structure_root_number = self.add_object(PdfNull)
let namespace_object = match subformat {
Some(PdfUA2) =>
Some(
@syntax.PdfIndirect(
self.add_object(
PdfDictionary([
(
pdf_texttopdf_ns_key(),
PdfString(pdf_texttopdf_pdfua2_namespace),
),
]),
),
),
)
_ => None
}
let document_number = match subformat {
Some(PdfUA2) => self.add_object(PdfNull)
_ => 0
}
let parent_number = match subformat {
Some(PdfUA2) => document_number
_ => structure_root_number
}
let page_references = self.page_reference_numbers()
let structure_elements = pdf_texttopdf_structure_elements(
self, parent_number, page_references, nodes,
)
let parent_tree = self.add_object(
self.build_number_tree(
pdf_texttopdf_parent_tree_entries(
tags.length(),
triples,
structure_elements,
),
),
)
let root_entries : Array[(@core.PdfName, @syntax.PdfObject)] = [
(pdf_texttopdf_type_key(), PdfNameObject(pdf_texttopdf_struct_tree_root())),
(pdf_structure_parent_tree_key(), PdfIndirect(parent_tree)),
]
let root_k = match (subformat, namespace_object) {
(Some(PdfUA2), Some(ns_object)) => {
self.add_object_given_number(
document_number,
PdfDictionary([
(pdf_structure_k_key(), PdfArray(structure_elements)),
(pdf_texttopdf_p_key(), PdfIndirect(structure_root_number)),
(pdf_texttopdf_s_key(), PdfNameObject(pdf_texttopdf_document_name())),
(pdf_texttopdf_ns_key(), ns_object),
]),
)
root_entries.push((pdf_texttopdf_namespaces_key(), PdfArray([ns_object])))
@syntax.PdfIndirect(document_number)
}
_ => PdfArray(structure_elements)
}
root_entries.push((pdf_structure_k_key(), root_k))
self.add_object_given_number(
structure_root_number,
PdfDictionary(root_entries),
)
self.replace_chain(
[pdf_structure_root_key(), pdf_structure_struct_tree_root_key()],
PdfIndirect(structure_root_number),
)
}