summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua244
1 files changed, 140 insertions, 104 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
index f4ecfc8a601..0a2fe679ea8 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
@@ -13,7 +13,8 @@ local settings_to_hash = utilities.parsers.settings_to_hash
local sortedhash = table.sortedhash
local formatters = string.formatters
-local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
+local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
+local trace_info = false trackers.register("structures.tags.info", function(v) trace_info = v end)
local report_tags = logs.reporter("backend","tags")
@@ -51,11 +52,9 @@ local a_tagged = attributes.private('tagged')
local a_image = attributes.private('image')
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local nodepool = nuts.pool
-local pdfpageliteral = nodepool.pdfpageliteral
+local pageliteral = nodepool.pageliteral
local register = nodepool.register
local getid = nuts.getid
@@ -68,17 +67,17 @@ local setlink = nuts.setlink
local setlist = nuts.setlist
local copy_node = nuts.copy
-local traverse_nodes = nuts.traverse
local tosequence = nuts.tosequence
-local structure_stack = { }
-local structure_kids = pdfarray()
-local structure_ref = pdfreserveobject()
-local parent_ref = pdfreserveobject()
-local root = { pref = pdfreference(structure_ref), kids = structure_kids }
+local nextnode = nuts.traversers.node
+
+local structure_kids -- delayed
+local structure_ref -- delayed
+local parent_ref -- delayed
+local root -- delayed
+local names -- delayed
local tree = { }
local elements = { }
-local names = pdfarray()
local structurestags = structures.tags
local taglist = structurestags.taglist
@@ -112,7 +111,7 @@ local usedmapping = { }
-- end
local function finishstructure()
- if #structure_kids > 0 then
+ if root and #structure_kids > 0 then
local nums, n = pdfarray(), 0
for i=1,#tree do
n = n + 1 ; nums[n] = i - 1
@@ -171,6 +170,7 @@ local index, pageref, pagenum, list = 0, nil, 0, nil
local pdf_mcr = pdfconstant("MCR")
local pdf_struct_element = pdfconstant("StructElem")
+local pdf_s = pdfconstant("S")
local function initializepage()
index = 0
@@ -183,6 +183,8 @@ end
local function finishpage()
-- flush what can be flushed
addtopageattributes("StructParents",pagenum-1)
+ -- there might be more
+ addtopageattributes("Tabs",s)
end
-- here we can flush and free elements that are finished
@@ -255,9 +257,10 @@ local function makeelement(fulltag,parent)
AF = af,
}
local s = pdfreference(pdfflushobject(d))
- if id then
- names[#names+1] = id
- names[#names+1] = s
+ if id and names then
+ local size = #names
+ names[size+1] = id
+ names[size+2] = s
end
local kids = parent.kids
kids[#kids+1] = s
@@ -314,27 +317,35 @@ end
-- no need to adapt head, as we always operate on lists
local EMCliteral = nil
+local visualize = nil
function nodeinjections.addtags(head)
if not EMCliteral then
- EMCliteral = register(pdfpageliteral("EMC"))
+ EMCliteral = register(pageliteral("EMC"))
end
local last = nil
local ranges = { }
local range = nil
- local head = tonut(head)
+
+ if not root then
+ structure_kids = pdfarray()
+ structure_ref = pdfreserveobject()
+ parent_ref = pdfreserveobject()
+ root = { pref = pdfreference(structure_ref), kids = structure_kids }
+ names = pdfarray()
+ end
local function collectranges(head,list)
- for n in traverse_nodes(head) do
- local id = getid(n)
+ for n, id in nextnode, head do
if id == glyph_code then
-- maybe also disc
- local at = getattr(n,a_tagged)
- if not at then
- range = nil
- elseif last ~= at then
+ local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
+ -- if not at then
+ -- range = nil
+ -- elseif ...
+ if last ~= at then
range = { at, "glyph", n, n, list } -- attr id start stop list
ranges[#ranges+1] = range
last = at
@@ -344,12 +355,12 @@ function nodeinjections.addtags(head)
elseif id == hlist_code or id == vlist_code then
local at = getattr(n,a_image)
if at then
- local at = getattr(n,a_tagged)
- if not at then
- range = nil
- else
+ local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
+ -- if not at then
+ -- range = nil
+ -- else
ranges[#ranges+1] = { at, "image", n, n, list } -- attr id start stop list
- end
+ -- end
last = nil
else
collectranges(getlist(n),n)
@@ -379,89 +390,117 @@ function nodeinjections.addtags(head)
local top = nil
local noftop = 0
+
+ local function inject(start,stop,list,literal,left,right)
+ local prev = getprev(start)
+ if prev then
+ setlink(prev,literal)
+ end
+ if left then
+ setlink(literal,left,start)
+ else
+ setlink(literal,start)
+ end
+ if list and getlist(list) == start then
+ setlist(list,literal)
+ end
+ local literal = copy_node(EMCliteral)
+ -- use insert instead:
+ local next = getnext(stop)
+ if next then
+ setlink(literal,next)
+ end
+ if right then
+ setlink(stop,right,literal)
+ else
+ setlink(stop,literal)
+ end
+ end
+
for i=1,#ranges do
- local range = ranges[i]
- local attr = range[1]
- local id = range[2]
- local start = range[3]
- local stop = range[4]
- local list = range[5]
- local specification = taglist[attr]
- local taglist = specification.taglist
- local noftags = #taglist
- local common = 0
- if top then
- for i=1,noftags >= noftop and noftop or noftags do
- if top[i] == taglist[i] then
- common = i
- else
- break
+
+ local range = ranges[i]
+ local attr = range[1]
+ local id = range[2]
+ local start = range[3]
+ local stop = range[4]
+ local list = range[5]
+
+ if attr then
+
+ local specification = taglist[attr]
+ local taglist = specification.taglist
+ local noftags = #taglist
+ local common = 0
+ local literal = nil
+ local ignore = false
+
+ if top then
+ for i=1,noftags >= noftop and noftop or noftags do
+ if top[i] == taglist[i] then
+ common = i
+ else
+ break
+ end
end
end
- end
- local prev = common > 0 and elements[taglist[common]] or root
- local ignore = false
- local literal = nil
-
- for j=common+1,noftags do
- local tag = taglist[j]
- local prv = elements[tag] or makeelement(tag,prev)
- if prv == false then
- -- ignore this one
- prev = false
- ignore = true
- break
- elseif prv == true then
- -- skip this one
- else
- prev = prv
+ local prev = common > 0 and elements[taglist[common]] or root
+
+ for j=common+1,noftags do
+ local tag = taglist[j]
+ local prv = elements[tag] or makeelement(tag,prev)
+ if prv == false then
+ -- ignore this one
+ prev = false
+ ignore = true
+ break
+ elseif prv == true then
+ -- skip this one
+ else
+ prev = prv
+ end
end
- end
- if prev then
- literal = pdfpageliteral(makecontent(prev,id,specification))
- elseif ignore then
- literal = pdfpageliteral(makeignore(specification))
- end
- if literal then
- local prev = getprev(start)
if prev then
- setlink(prev,literal)
- end
- setlink(literal,start)
- if list and getlist(list) == start then
- setlist(list,literal)
+ literal = pageliteral(makecontent(prev,id,specification))
+ elseif ignore then
+ literal = pageliteral(makeignore(specification))
+ else
+ -- maybe also ignore or maybe better: comment or so
end
- local literal = copy_node(EMCliteral)
- -- use insert instead:
- local next = getnext(stop)
- if next then
- setlink(literal,next)
+
+ if literal then
+ local left,right
+ if trace_info then
+ local name = specification.tagname
+ if name then
+ if not visualize then
+ visualize = nodes.visualizers.register("tags")
+ end
+ left = visualize(name)
+ right = visualize()
+ end
+ end
+ inject(start,stop,list,literal,left,right)
end
- setlink(stop,literal)
- end
--- if literal then
--- if list and getlist(list) == start then
--- setlink(literal,start)
--- setlist(list,literal)
--- else
--- setlink(getprev(start),literal,start)
--- end
--- -- use insert instead:
--- local literal = copy_node(EMCliteral)
--- setlink(stop,literal,getnext(stop))
--- end
+ top = taglist
+ noftop = noftags
+
+ else
+
+ local literal = pageliteral(makeignore(specification))
+
+ inject(start,stop,list,literal)
+
+ end
- top = taglist
- noftop = noftags
end
finishpage()
- head = tonode(head)
- return head, true
+ return head
end
@@ -472,8 +511,7 @@ end
-- local last, ranges, range = nil, { }, nil
--
-- local function collectranges(head,list)
--- for n in traverse_nodes(head) do
--- local id = getid(n) -- 14: image, 8: literal (mp)
+-- for n, id in nextnode, head do
-- if id == glyph_code then
-- local at = getattr(n,a_tagged)
-- if not at then
@@ -505,7 +543,6 @@ end
--
-- initializepage()
--
--- head = tonut(head)
-- collectranges(head)
--
-- if trace_tags then
@@ -577,9 +614,9 @@ end
-- end
--
-- if r > 0 then
--- local literal = pdfpageliteral(concat(result,"\n"))
+-- local literal = pageliteral(concat(result,"\n"))
-- -- use insert instead:
--- local literal = pdfpageliteral(result)
+-- local literal = pageliteral(result)
-- local prev = getprev(start)
-- if prev then
-- setlink(prev,literal)
@@ -601,7 +638,7 @@ end
-- for i=1,noftop do
-- result[i] = "EMC"
-- end
--- local literal = pdfpageliteral(concat(result,"\n"))
+-- local literal = pageliteral(concat(result,"\n"))
-- -- use insert instead:
-- local next = getnext(last)
-- if next then
@@ -612,8 +649,7 @@ end
--
-- finishpage()
--
--- head = tonode(head)
--- return head, true
+-- return head
--
-- end