summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/minim-pdf/minim-pdf.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/minim-pdf/minim-pdf.lua')
-rw-r--r--macros/luatex/generic/minim-pdf/minim-pdf.lua138
1 files changed, 66 insertions, 72 deletions
diff --git a/macros/luatex/generic/minim-pdf/minim-pdf.lua b/macros/luatex/generic/minim-pdf/minim-pdf.lua
index 101a548e4b..9d824a829f 100644
--- a/macros/luatex/generic/minim-pdf/minim-pdf.lua
+++ b/macros/luatex/generic/minim-pdf/minim-pdf.lua
@@ -2,7 +2,6 @@
local M = { }
local alloc = require('minim-alloc')
local cb = require('minim-callbacks')
-alloc.remember('minim-hooks')
alloc.remember('minim-pdf')
-- 1 helper functions
@@ -32,25 +31,10 @@ local pdf_name = alloc.pdf_name
local pdf_string = alloc.pdf_string
local options_scanner = alloc.options_scanner
--- is this table empty?
-local function is_empty(t)
- for _, _ in pairs(t or {}) do
- return false
- end
- return true
-end
-
--- has this table just one element?
local function singleton(t)
- local one = false
- for _, _ in pairs(t) do
- if one then
- return false
- else
- one = true
- end
- end
- return one
+ local v = next(t)
+ v = v and not next(t, v)
+ return v and true or false
end
-- in-depth node list traversal; returns current and parent node
@@ -92,6 +76,7 @@ local structure = { {
index = 1,
struct = 'Document',
children = { },
+ level = 0, -- for debugging only
} }
-- the parent tree will be filled automatically and separately
@@ -158,7 +143,7 @@ local structure_types = alloc.saved_table('structure types', {
-- block level structure elements (BLSE)
P = { type = 'block' },
H = { type = 'block' },
- H1 = { type = 'block' }, -- for nonhierarchical tagging (do not use?)
+ H1 = { type = 'block' }, -- for nonhierarchical tagging (do not use)
H2 = { type = 'block' }, -- __________ „ __________
H3 = { type = 'block' }, -- __________ „ __________
H4 = { type = 'block' }, -- __________ „ __________
@@ -328,7 +313,8 @@ local function make_rolemap()
return ''
end
-local function make_attributes(res, t)
+local function make_attributes(t)
+ local res = { }
-- is there just one attribute?
local list = not singleton(t)
if list then table.insert(res, '[') end
@@ -340,6 +326,7 @@ local function make_attributes(res, t)
table.insert(res, '>>')
end
if list then table.insert(res, ']') end
+ return table.concat(res, ' ')
end
local attribute_classes = alloc.saved_table('attribute classes')
@@ -347,7 +334,7 @@ local function make_classmap()
local classes = { }
for c, as in pairs(attribute_classes) do
insert_formatted(classes, '\n%s', pdf_name(c))
- make_attributes(classes, as)
+ table.insert(classes, make_attributes(as))
end
if #classes > 0 then
return '\n/ClassMap << ' .. table.concat(classes, ' ') .. ' >>'
@@ -355,11 +342,59 @@ local function make_classmap()
return ''
end
+local id_tree = { }
+
+local function write_structure_element(se)
+ local res = { '<<' }
+ insert_formatted(res, '/Type/StructElem /S%s /P %d 0 R', pdf_name(se.struct), se.parent.objnum)
+ if se.id then insert_formatted(res, '/ID %s', pdf_string(se.id)) end
+ if se.lang and se.lang ~= se.parent.lang then insert_formatted(res, '/Lang %s', pdf_string(se.lang)) end
+ if se.alt then insert_formatted(res, '/Alt %s', pdf_string(se.alt)) end
+ if se.actual then insert_formatted(res, '/ActualText %s', pdf_string(se.actual)) end
+ if se.title then insert_formatted(res, '/T %s', pdf_string(se.title)) end
+ if #se.children > 0 then insert_formatted(res, '\n/K %s', format_K_array(se)) end
+ if se.mainpage then insert_formatted(res, '/Pg %d 0 R', se.mainpage) end
+ if se.class then
+ table.insert(res, '/C')
+ if #se.class > 1 then table.insert(res, '[') end
+ for _, c in ipairs(se.class) do
+ insert_formatted(res, '%s', pdf_name(c))
+ end
+ if #se.class > 1 then table.insert(res, ']') end
+ end
+ if se.ref then
+ table.insert(res, '/Ref')
+ table.insert(res, '[')
+ for _, c in ipairs(se.ref) do
+ local onum = id_tree[c]
+ if onum then
+ insert_formatted(res, '%d 0 R', onum)
+ else
+ alloc.err('Invalid structure element ID: %s', c)
+ end
+ end
+ table.insert(res, ']')
+ end
+ if next(se.attributes or {}) then
+ table.insert(res, '/A')
+ table.insert(res, make_attributes(se.attributes))
+ end
+ if se.files then
+ table.insert(res, '/AF [')
+ for _, fs in ipairs(se.files) do
+ insert_formatted(res, '%d 0 R', fs)
+ end
+ table.insert(res, ']')
+ end
+ table.insert(res, '>>')
+ pdf.immediateobj(se.objnum, table.concat(res, ' '))
+end
+
local function write_structure()
if #structure == 1 then return end
-- reserve object numbers, prepare for writing
- local root_obj, parent_tree_obj = pdf.reserveobj(), pdf.reserveobj()
- local id_tree, id_tree_obj = { }, pdf.reserveobj()
+ local root_obj, parent_tree_obj, id_tree_obj =
+ pdf.reserveobj(), pdf.reserveobj(), pdf.reserveobj()
structure[1].parent = { objnum = root_obj }
for _, se in ipairs(structure) do
if not se.hidden then
@@ -383,49 +418,7 @@ local function write_structure()
-- write structure elements
for _, se in ipairs(structure) do
if not se.hidden then
- local res = { '<<' }
- insert_formatted(res, '/Type/StructElem /S%s /P %d 0 R', pdf_name(se.struct), se.parent.objnum)
- if se.id then insert_formatted(res, '/ID %s', pdf_string(se.id)) end
- if se.lang and se.lang ~= se.parent.lang then insert_formatted(res, '/Lang %s', pdf_string(se.lang)) end
- if se.alt then insert_formatted(res, '/Alt %s', pdf_string(se.alt)) end
- if se.actual then insert_formatted(res, '/ActualText %s', pdf_string(se.actual)) end
- if se.title then insert_formatted(res, '/T %s', pdf_string(se.title)) end
- if #se.children > 0 then insert_formatted(res, '\n/K %s', format_K_array(se)) end
- if se.mainpage then insert_formatted(res, '/Pg %d 0 R', se.mainpage) end
- if se.class then
- table.insert(res, '/C')
- if #se.class > 1 then table.insert(res, '[') end
- for _, c in ipairs(se.class) do
- insert_formatted(res, '%s', pdf_name(c))
- end
- if #se.class > 1 then table.insert(res, ']') end
- end
- if se.ref then
- table.insert(res, '/Ref')
- table.insert(res, '[')
- for _, c in ipairs(se.ref) do
- local onum = id_tree[c]
- if onum then
- insert_formatted(res, '%d 0 R', onum)
- else
- alloc.err('Invalid structure element ID: %s', c)
- end
- end
- table.insert(res, ']')
- end
- if not is_empty(se.attributes) then
- table.insert(res, '/A')
- make_attributes(res, se.attributes)
- end
- if se.files then
- table.insert(res, '/AF [')
- for _, fs in ipairs(se.files) do
- insert_formatted(res, '%d 0 R', fs)
- end
- table.insert(res, ']')
- end
- table.insert(res, '>>')
- pdf.immediateobj(se.objnum, table.concat(res, ' '))
+ write_structure_element(se)
end
end
-- write the parent tree (a number tree)
@@ -519,7 +512,6 @@ end
local function get_ancestor_of_type(se, stype)
while se and se.struct ~= stype do
- if se.level == -1000 then return end
se = se.parent
end
return se and se.parent
@@ -527,7 +519,8 @@ end
function M.close_structure_node(stype, raiseerror)
local strict = tex.count['strictstructuretagging'] > 0
- local current, open = current_structure_element()
+ local current = current_structure_element()
+ local open
if strict then
open = current.struct == stype and current.parent
else
@@ -574,6 +567,7 @@ function M.open_structure_node(n)
n.order = n.order or tex.getattribute(current_order)
n.parent = (n.parent and structure[n.parent])
or determine_parent_node(current_structure_element(), n)
+ n.level = n.parent.level + 1
table.insert(structure, n)
-- determine the proper language code
if n.lang then
@@ -664,7 +658,7 @@ local mcid_list, pageobj
local function clear_page_tagging_parameters()
mcid_list, pageobj = { }, nil
- _open_mci_node_ = function (se_num, order)
+ _open_mci_node_ = function (se_num, order) --luacheck: ignore 111
pageobj = pageobj or pdf.getpageref(status.total_pages + 1)
local se = structure[se_num]
pdf.print(string.format('%s <</MCID %d>> BDC ', pdf_name(se.struct), #mcid_list))
@@ -854,7 +848,7 @@ end)
local function scan_escaped_argument(chars_to_escape)
local stored = { }
- for char in string.utfvalues(chars_to_escape) do
+ for _, char in utf8.codes(chars_to_escape) do
stored[char] = tex.getcatcode(char)
tex.setcatcode(char, 12)
end
@@ -1060,7 +1054,7 @@ function M.mark_discretionaries(head, gc)
if #actual == 0 and pre and pre.char and pre.char == 0x2D then
actual = '­' -- soft hyphen U+00AD
elseif #actual > 0 then
- actual = string.utfcharacter(table.unpack(actual))
+ actual = utf8.char(table.unpack(actual))
else
goto continue
end