Named destinations and improved outline interface
There is no support for PDFTeX's outline command yet, but the new one is much easier to use.
This commit is contained in:
parent
c83b7ffc5e
commit
7e3a4e3c74
3 changed files with 206 additions and 4 deletions
53
luametalatex-pdf-nametree.lua
Normal file
53
luametalatex-pdf-nametree.lua
Normal file
|
@ -0,0 +1,53 @@
|
|||
local min = math.min
|
||||
local format = string.format
|
||||
local concat = table.concat
|
||||
local move = table.move
|
||||
local function write(pdf, tree, escaped, step)
|
||||
local nextcount = (#tree-1)//6+1
|
||||
for i=1, nextcount do
|
||||
if #tree > 6 then
|
||||
tree[i] = pdf:indirect(nil, format('<</Limits[%s %s]/Kids[%s 0 R]>>', escaped[step*(i-1)+1], escaped[step*i] or escaped[#escaped], concat(tree, ' 0 R ', 6*i-5, min(#tree, 6*i))))
|
||||
else
|
||||
return pdf:indirect(nil, format('<</Kids[%s 0 R]>>', concat(tree, ' 0 R ', 6*i-5, #tree)))
|
||||
end
|
||||
end
|
||||
move(tree, #tree+1, 2*#tree-nextcount, nextcount+1)
|
||||
return write(pdf, tree, escaped, step*6)
|
||||
end
|
||||
local function pdf_string(s)
|
||||
-- Emulate other engines here: If looks like an escaped string, treat it as such. Otherwise, add parenthesis.
|
||||
return s:match("^%(.*%)$") or s:match("^<.*>$") or '(' .. s .. ')'
|
||||
end
|
||||
local serialized = {}
|
||||
return function(values, pdf)
|
||||
local tree = {}
|
||||
for k in next, values do
|
||||
if type(k) ~= "string" then
|
||||
error[[Invalid entry in nametree]] -- Might get ignored in a later version
|
||||
end
|
||||
tree[#tree+1] = k
|
||||
end
|
||||
table.sort(tree)
|
||||
local total = #tree
|
||||
local newtree = {}
|
||||
for i=0,(total-1)//6 do
|
||||
for j=1, 6 do
|
||||
local key = tree[6*i+j]
|
||||
if key then
|
||||
local value = values[key]
|
||||
key = pdf_string(key)
|
||||
tree[6*i+j] = key
|
||||
serialized[2*j-1] = key
|
||||
serialized[2*j] = value
|
||||
else
|
||||
serialized[2*j-1], serialized[2*j] = nil, nil
|
||||
end
|
||||
end
|
||||
if total > 6 then
|
||||
newtree[i+1] = pdf:indirect(nil, format('<</Limits[%s %s]/Names[%s]>>', tree[6*i+1], tree[6*i+6] or tree[total], concat(serialized, ' ')))
|
||||
else
|
||||
return pdf:indirect(nil, format('<</Names[%s]>>', concat(serialized, ' ')))
|
||||
end
|
||||
end
|
||||
return write(pdf, newtree, tree, 36)
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue