\pdfcatalog openaction and page actions
This commit is contained in:
parent
f6895d8b50
commit
b8dbb5a4c8
@ -57,6 +57,7 @@ end, 'force', 'protected')
|
|||||||
local infodir = ""
|
local infodir = ""
|
||||||
local namesdir = ""
|
local namesdir = ""
|
||||||
local catalogdir = ""
|
local catalogdir = ""
|
||||||
|
local catalog_openaction
|
||||||
local creationdate = os.date("D:%Y%m%d%H%M%S%z"):gsub("+0000$", "Z"):gsub("%d%d$", "'%0")
|
local creationdate = os.date("D:%Y%m%d%H%M%S%z"):gsub("+0000$", "Z"):gsub("%d%d$", "'%0")
|
||||||
local function write_infodir(p)
|
local function write_infodir(p)
|
||||||
local additional = ""
|
local additional = ""
|
||||||
@ -118,6 +119,9 @@ callback.register("stop_run", function()
|
|||||||
if outline then
|
if outline then
|
||||||
catalogdir = string.format("/Outlines %i 0 R%s", outline:write(pfile), catalogdir)
|
catalogdir = string.format("/Outlines %i 0 R%s", outline:write(pfile), catalogdir)
|
||||||
end
|
end
|
||||||
|
if catalog_openaction then
|
||||||
|
catalogdir = catalogdir .. '/OpenAction' .. catalog_openaction
|
||||||
|
end
|
||||||
pfile:indirect(pfile.root, string.format([[<</Type/Catalog/Version/%s/Pages %i 0 R%s>>]], pfile.version, pfile:writepages(), catalogdir))
|
pfile:indirect(pfile.root, string.format([[<</Type/Catalog/Version/%s/Pages %i 0 R%s>>]], pfile.version, pfile:writepages(), catalogdir))
|
||||||
pfile.info = write_infodir(pfile)
|
pfile.info = write_infodir(pfile)
|
||||||
local size = pfile:close()
|
local size = pfile:close()
|
||||||
@ -198,19 +202,30 @@ local function get_action_attr(p, action, is_link)
|
|||||||
error[[FIXME]]
|
error[[FIXME]]
|
||||||
elseif action_type == 1 then -- GoTo
|
elseif action_type == 1 then -- GoTo
|
||||||
local id = action.id
|
local id = action.id
|
||||||
if file then
|
if id then
|
||||||
assert(type(id) == "string")
|
if file then
|
||||||
action_attr = action_attr .. "/S/GoToR/D" .. pdf_bytestring(id) .. ">>"
|
assert(type(id) == "string")
|
||||||
else
|
action_attr = action_attr .. "/S/GoToR/D" .. pdf_bytestring(id) .. ">>"
|
||||||
local dest = dests[id]
|
|
||||||
if not dest then
|
|
||||||
dest = pfile:getobj()
|
|
||||||
dests[id] = dest
|
|
||||||
end
|
|
||||||
if type(id) == "string" then
|
|
||||||
action_attr = action_attr .. "/S/GoTo/D" .. pdf_bytestring(id) .. ">>"
|
|
||||||
else
|
else
|
||||||
action_attr = string.format("%s/S/GoTo/D %i 0 R>>", action_attr, dest)
|
local dest = dests[id]
|
||||||
|
if not dest then
|
||||||
|
dest = pfile:getobj()
|
||||||
|
dests[id] = dest
|
||||||
|
end
|
||||||
|
if type(id) == "string" then
|
||||||
|
action_attr = action_attr .. "/S/GoTo/D" .. pdf_bytestring(id) .. ">>"
|
||||||
|
else
|
||||||
|
action_attr = string.format("%s/S/GoTo/D %i 0 R>>", action_attr, dest)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
id = assert(action.page, 'GoTo action must contain either an id or a page')
|
||||||
|
local tokens = action.tokens
|
||||||
|
if file then
|
||||||
|
action_attr = string.format("%s/S/GoToR/D[%i %s]>>", action_attr, id-1, tokens)
|
||||||
|
else
|
||||||
|
local page_objnum = pfile:reservepage(id)
|
||||||
|
action_attr = string.format("%s/S/GoTo/D[%i 0 R %s]>>", action_attr, page_objnum, tokens)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -486,9 +501,15 @@ local function scan_action()
|
|||||||
file = token.scan_keyword'file' and token.scan_string(),
|
file = token.scan_keyword'file' and token.scan_string(),
|
||||||
}
|
}
|
||||||
if token.scan_keyword'page' then
|
if token.scan_keyword'page' then
|
||||||
error[[TODO]]
|
assert(action_type == 1)
|
||||||
|
local page = token.scan_int()
|
||||||
|
if page <= 0 then
|
||||||
|
error[[page must be positive in action specified]]
|
||||||
|
end
|
||||||
|
action.page = page
|
||||||
|
action.tokens = token.scan_string()
|
||||||
elseif token.scan_keyword'num' then
|
elseif token.scan_keyword'num' then
|
||||||
if action.file and action_type == 3 then
|
if action.file and action_type == 1 then
|
||||||
error[[num style GoTo actions must be internal]]
|
error[[num style GoTo actions must be internal]]
|
||||||
end
|
end
|
||||||
action.id = token.scan_int()
|
action.id = token.scan_int()
|
||||||
@ -585,6 +606,15 @@ token.luacmd("pdfextension", function(_, imm)
|
|||||||
infodir = infodir .. token.scan_string()
|
infodir = infodir .. token.scan_string()
|
||||||
elseif token.scan_keyword"catalog" then
|
elseif token.scan_keyword"catalog" then
|
||||||
catalogdir = catalogdir .. ' ' .. token.scan_string()
|
catalogdir = catalogdir .. ' ' .. token.scan_string()
|
||||||
|
if token.scan_keyword'openaction' then
|
||||||
|
if catalog_openaction then
|
||||||
|
tex.error("Duplicate openaction", {"Only one use of \\pdfextension catalog is allowed to \z
|
||||||
|
have an openaction."})
|
||||||
|
else
|
||||||
|
local action = scan_action()
|
||||||
|
catalog_openaction = get_action_attr(get_pfile(), action)
|
||||||
|
end
|
||||||
|
end
|
||||||
elseif token.scan_keyword"names" then
|
elseif token.scan_keyword"names" then
|
||||||
namesdir = namesdir .. ' ' .. token.scan_string()
|
namesdir = namesdir .. ' ' .. token.scan_string()
|
||||||
elseif token.scan_keyword"obj" then
|
elseif token.scan_keyword"obj" then
|
||||||
|
@ -35,15 +35,31 @@ local function write(pdf, tree, total, max)
|
|||||||
return newtree[1]
|
return newtree[1]
|
||||||
end
|
end
|
||||||
local function newpage(pdf)
|
local function newpage(pdf)
|
||||||
local pageid = pdf:getobj()
|
local pages = pdf.pages
|
||||||
local pagenumber = #pdf.pages
|
local pagenumber = #pages+1
|
||||||
pdf.pages[pagenumber+1] = pageid
|
local pageid = pages.reserved and pages.reserved[pagenumber] or pdf:getobj()
|
||||||
if 0 == pagenumber % 6 then
|
pages.reserved[pagenumber] = nil
|
||||||
pdf.pages[-(pagenumber//6)] = pdf:getobj()
|
pages[pagenumber] = pageid
|
||||||
|
if 1 == pagenumber % 6 then
|
||||||
|
pages[-((pagenumber-1)//6)] = pdf:getobj()
|
||||||
end
|
end
|
||||||
return pageid, pdf.pages[-(pagenumber//6)]
|
return pageid, pages[-((pagenumber-1)//6)]
|
||||||
|
end
|
||||||
|
local function reservepage(pdf, num)
|
||||||
|
local pages = pdf.pages
|
||||||
|
if pages[num] then return pages[num] end
|
||||||
|
local reserved = pages.reserved
|
||||||
|
if reserved then
|
||||||
|
if reserved[num] then return reserved[num] end
|
||||||
|
else
|
||||||
|
reserved = {}
|
||||||
|
pages.reserved = reserved
|
||||||
|
end
|
||||||
|
reserved[num] = pdf:getobj()
|
||||||
|
return reserved[num]
|
||||||
end
|
end
|
||||||
return {
|
return {
|
||||||
write = write,
|
write = write,
|
||||||
newpage = newpage,
|
newpage = newpage,
|
||||||
|
reservepage = reservepage,
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,7 @@ local pdfmeta = {
|
|||||||
indirect = indirect,
|
indirect = indirect,
|
||||||
stream = stream,
|
stream = stream,
|
||||||
newpage = pagetree.newpage,
|
newpage = pagetree.newpage,
|
||||||
|
reservepage = pagetree.reservepage,
|
||||||
writepages = pagetree.write,
|
writepages = pagetree.write,
|
||||||
delayed = delay,
|
delayed = delay,
|
||||||
delayedstream = delayedstream,
|
delayedstream = delayedstream,
|
||||||
|
Loading…
Reference in New Issue
Block a user