diff options
Diffstat (limited to 'tex/context/base/lpdf-epa.lua')
-rw-r--r-- | tex/context/base/lpdf-epa.lua | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/tex/context/base/lpdf-epa.lua b/tex/context/base/lpdf-epa.lua new file mode 100644 index 000000000..35c0c086b --- /dev/null +++ b/tex/context/base/lpdf-epa.lua @@ -0,0 +1,162 @@ +if not modules then modules = { } end modules ['lpdf-epa'] = { + version = 1.001, + comment = "companion to lpdf-epa.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is a rather experimental feature and the code will probably +-- change. + +local type, tonumber = type, tonumber +local format = string.format + +local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) + +local report_link = logs.new("links") + +local variables = interfaces.variables + +local function add_link(x,y,w,h,destination,what) + if trace_links then + report_link("dx: %04i, dy: %04i, wd: %04i, ht: %04i, destination: %s, type: %s",x,y,w,h,destination,what) + end + context.setlayer ( + { "epdflinks" }, + { x = x .. "bp", y = y .. "bp", preset = "leftbottom" }, + function() + -- context.blackrule { width = w.."bp", height = h.."bp", depth = "0bp" } + context.button ( + { + width = w.."bp", + height = h.."bp", + offset = variables.overlay, + frame = trace_links and variables.on or variables.off, + }, + "", + { destination } + ) + end + ) +end + +local function link_goto(x,y,w,h,document,annotation,pagesdata,pagedata,namespace) + -- print("border",table.unpack(annotation.Border.all)) + -- print("flags",annotation.F) + -- print("pagenumbers",pagedata.reference.num,destination[1].num) + -- print("pagerefs",pagedata.number,pagesdata.references[destination[1].num]) + local destination = annotation.A.D -- [ 18 0 R /Fit ] + local what = "page" + if type(destination) == "string" then + local destinations = document.Catalog.Destinations + local wanted = destinations[destination] + destination = wanted and wanted.D + if destination then what = "named" end + end + local whereto = destination and destination[1] -- array + if whereto and whereto.num then + local currentpage = pagedata.number + local destinationpage = pagesdata.references[whereto.num] + add_link(x,y,w,h,namespace .. destinationpage,what) + return + end +end + +local function link_uri(x,y,w,h,document,annotation) + local url = annotation.A.URI + if url then + add_link(x,y,w,h,format("url(%s)",url),"url") + end +end + +local function link_file(x,y,w,h,document,annotation) + local filename = annotation.A.F + if filename then + local destination = annotation.A.D + if not destination then + add_link(x,y,w,h,format("file(%s)",filename),"file") + elseif type(destination) == "string" then + add_link(x,y,w,h,format("%s::%s",filename,destination),"file (named)") + else + destination = destination[1] -- array + if tonumber(destination) then + add_link(x,y,w,h,format("%s::page(%s)",filename,destination),"file (page)") + else + add_link(x,y,w,h,format("file(%s)",filename),"file") + end + end + end +end + +function backends.codeinjections.mergereferences(specification) + if figures and not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if specification then + local fullname = specification.fullname + local document = lpdf.load(fullname) + if document then + local pagenumber = specification.page or 1 + local xscale = specification.yscale or 1 + local yscale = specification.yscale or 1 + local size = specification.size or "crop" -- todo + local pagesdata = document.Catalog.Pages + local pagedata = pagesdata[pagenumber] + local annotations = pagedata.Annots + local namespace = format("lpdf-epa-%s-",file.removesuffix(file.basename(fullname))) + local reference = namespace .. pagenumber + if annotations.size > 0 then + local llx, lly, urx, ury = table.unpack(pagedata.MediaBox.all) + local width, height = xscale * (urx - llx), yscale * (ury - lly) -- \\overlaywidth, \\overlayheight + context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" }) + for i=1,annotations.size do + local annotation = annotations[i] + local subtype = annotation.Subtype + local a_llx, a_lly, a_urx, a_ury = table.unpack(annotation.Rect.all) + local x, y = xscale * (a_llx - llx), yscale * (a_lly - lly) + local w, h = xscale * (a_urx - a_llx), yscale * (a_ury - a_lly) + if subtype == "Link" then + local linktype = annotation.A.S + if linktype == "GoTo" then + link_goto(x,y,w,h,document,annotation,pagesdata,pagedata,namespace) + elseif linktype == "GoToR" then + link_file(x,y,w,h,document,annotation) + elseif linktype == "URI" then + link_uri(x,y,w,h,document,annotation) + elseif trace_links then + report_link("unsupported link annotation '%s'",linktype) + end + elseif trace_links then + report_link("unsupported annotation '%s'",subtype) + end + end + context.flushlayer { "epdflinks" } + context("\\gdef\\figurereference{%s}",reference) -- global + specification.reference = reference + return namespace + end + end + end + return ""-- no namespace, empty, not nil +end + +function backends.codeinjections.mergelayers(specification) + if not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if specification then + local fullname = specification.fullname + local document = lpdf.load(fullname) + if document then + local pagenumber = specification.page or 1 + local pagesdata = document.Catalog.Pages + local pagedata = pagesdata[pagenumber] + local resources = pagedata.Resources +--~ table.print(resources) +--~ local properties = resources.Properties + end + end +end |