diff options
Diffstat (limited to 'tex/context/base/lpdf-epa.lua')
-rw-r--r-- | tex/context/base/lpdf-epa.lua | 452 |
1 files changed, 226 insertions, 226 deletions
diff --git a/tex/context/base/lpdf-epa.lua b/tex/context/base/lpdf-epa.lua index 034e6d7e2..8d00c8c26 100644 --- a/tex/context/base/lpdf-epa.lua +++ b/tex/context/base/lpdf-epa.lua @@ -1,226 +1,226 @@ -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, gsub = string.format, string.gsub -local formatters = string.formatters - ------ lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns - -local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) - -local report_link = logs.reporter("backend","merging") - -local backends, lpdf = backends, lpdf - -local variables = interfaces.variables -local codeinjections = backends.pdf.codeinjections ------ urlescaper = lpegpatterns.urlescaper ------ utftohigh = lpegpatterns.utftohigh -local escapetex = characters.filters.utf.private.escape - -local layerspec = { -- predefining saves time - "epdflinks" -} - -local function makenamespace(filename) - return format("lpdf-epa-%s-",file.removesuffix(file.basename(filename))) -end - -local function add_link(x,y,w,h,destination,what) - x = x .. "bp" - y = y .. "bp" - w = w .. "bp" - h = h .. "bp" - if trace_links then - report_link("destination %a, type %a, dx %s, dy %s, wd %s, ht %s",destination,what,x,y,w,h) - end - local locationspec = { -- predefining saves time - x = x, - y = y, - preset = "leftbottom", - } - local buttonspec = { - width = w, - height = h, - offset = variables.overlay, - frame = trace_links and variables.on or variables.off, - } - context.setlayer ( - layerspec, - locationspec, - function() context.button ( buttonspec, "", { destination } ) end - -- context.nested.button(buttonspec, "", { destination }) -- time this - ) -end - -local function link_goto(x,y,w,h,document,annotation,pagedata,namespace) - local a = annotation.A - if a then - local destination = a.D -- [ 18 0 R /Fit ] - local what = "page" - if type(destination) == "string" then - local destinations = document.destinations - local wanted = destinations[destination] - destination = wanted and wanted.D - if destination then what = "named" end - end - local pagedata = destination and destination[1] - if pagedata then - local destinationpage = pagedata.number - if destinationpage then - add_link(x,y,w,h,namespace .. destinationpage,what) - end - end - end -end - -local function link_uri(x,y,w,h,document,annotation) - local url = annotation.A.URI - if url then - -- url = lpegmatch(urlescaper,url) - -- url = lpegmatch(utftohigh,url) - url = escapetex(url) - add_link(x,y,w,h,formatters["url(%s)"](url),"url") - end -end - -local function link_file(x,y,w,h,document,annotation) - local a = annotation.A - if a then - local filename = a.F - if filename then - filename = escapetex(filename) - local destination = a.D - if not destination then - add_link(x,y,w,h,formatters["file(%s)"](filename),"file") - elseif type(destination) == "string" then - add_link(x,y,w,h,formatters["%s::%s"](filename,destination),"file (named)") - else - destination = destination[1] -- array - if tonumber(destination) then - add_link(x,y,w,h,formatters["%s::page(%s)"](filename,destination),"file (page)") - else - add_link(x,y,w,h,formatters["file(%s)"](filename),"file") - end - end - end - end -end - -function 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.epdf.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 pagedata = document.pages[pagenumber] - local annotations = pagedata and pagedata.Annots - if annotations and annotations.n > 0 then - local namespace = format("lpdf-epa-%s-",file.removesuffix(file.basename(fullname))) - local reference = namespace .. pagenumber - local mediabox = pagedata.MediaBox - local llx, lly, urx, ury = mediabox[1], mediabox[2], mediabox[3], mediabox[4] - local width, height = xscale * (urx - llx), yscale * (ury - lly) -- \\overlaywidth, \\overlayheight - context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" }) - for i=1,annotations.n do - local annotation = annotations[i] - if annotation then - local subtype = annotation.Subtype - local rectangle = annotation.Rect - local a_llx, a_lly, a_urx, a_ury = rectangle[1], rectangle[2], rectangle[3], rectangle[4] - 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 a = annotation.A - if a then - local linktype = a.S - if linktype == "GoTo" then - link_goto(x,y,w,h,document,annotation,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 %a",linktype) - end - else - report_link("mising link annotation") - end - elseif trace_links then - report_link("unsupported annotation %a",subtype) - end - elseif trace_links then - report_link("broken annotation, index %a",i) - end - end - context.flushlayer { "epdflinks" } - -- context("\\gdef\\figurereference{%s}",reference) -- global - context.setgvalue("figurereference",reference) -- global - if trace_links then - report_link("setting figure reference to %a",reference) - end - specification.reference = reference - return namespace - end - end - end - return ""-- no namespace, empty, not nil -end - -function codeinjections.mergeviewerlayers(specification) - -- todo: parse included page for layers - if true then - return - end - 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.epdf.load(fullname) - if document then - local namespace = format("lpdf:epa:%s:",file.removesuffix(file.basename(fullname))) - local layers = document.layers - if layers then - for i=1,layers.n do - local layer = layers[i] - if layer then - local tag = namespace .. gsub(layer," ",":") - local title = tag - if trace_links then - report_link("using layer %a",tag) - end - attributes.viewerlayers.define { -- also does some cleaning - tag = tag, -- todo: #3A or so - title = title, - visible = variables.start, - editable = variables.yes, - printable = variables.yes, - } - codeinjections.useviewerlayer(tag) - elseif trace_links then - report_link("broken layer, index %a",i) - end - end - end - end - end -end - +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, gsub = string.format, string.gsub
+local formatters = string.formatters
+
+----- lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+
+local trace_links = false trackers.register("figures.links", function(v) trace_links = v end)
+
+local report_link = logs.reporter("backend","merging")
+
+local backends, lpdf = backends, lpdf
+
+local variables = interfaces.variables
+local codeinjections = backends.pdf.codeinjections
+----- urlescaper = lpegpatterns.urlescaper
+----- utftohigh = lpegpatterns.utftohigh
+local escapetex = characters.filters.utf.private.escape
+
+local layerspec = { -- predefining saves time
+ "epdflinks"
+}
+
+local function makenamespace(filename)
+ return format("lpdf-epa-%s-",file.removesuffix(file.basename(filename)))
+end
+
+local function add_link(x,y,w,h,destination,what)
+ x = x .. "bp"
+ y = y .. "bp"
+ w = w .. "bp"
+ h = h .. "bp"
+ if trace_links then
+ report_link("destination %a, type %a, dx %s, dy %s, wd %s, ht %s",destination,what,x,y,w,h)
+ end
+ local locationspec = { -- predefining saves time
+ x = x,
+ y = y,
+ preset = "leftbottom",
+ }
+ local buttonspec = {
+ width = w,
+ height = h,
+ offset = variables.overlay,
+ frame = trace_links and variables.on or variables.off,
+ }
+ context.setlayer (
+ layerspec,
+ locationspec,
+ function() context.button ( buttonspec, "", { destination } ) end
+ -- context.nested.button(buttonspec, "", { destination }) -- time this
+ )
+end
+
+local function link_goto(x,y,w,h,document,annotation,pagedata,namespace)
+ local a = annotation.A
+ if a then
+ local destination = a.D -- [ 18 0 R /Fit ]
+ local what = "page"
+ if type(destination) == "string" then
+ local destinations = document.destinations
+ local wanted = destinations[destination]
+ destination = wanted and wanted.D
+ if destination then what = "named" end
+ end
+ local pagedata = destination and destination[1]
+ if pagedata then
+ local destinationpage = pagedata.number
+ if destinationpage then
+ add_link(x,y,w,h,namespace .. destinationpage,what)
+ end
+ end
+ end
+end
+
+local function link_uri(x,y,w,h,document,annotation)
+ local url = annotation.A.URI
+ if url then
+ -- url = lpegmatch(urlescaper,url)
+ -- url = lpegmatch(utftohigh,url)
+ url = escapetex(url)
+ add_link(x,y,w,h,formatters["url(%s)"](url),"url")
+ end
+end
+
+local function link_file(x,y,w,h,document,annotation)
+ local a = annotation.A
+ if a then
+ local filename = a.F
+ if filename then
+ filename = escapetex(filename)
+ local destination = a.D
+ if not destination then
+ add_link(x,y,w,h,formatters["file(%s)"](filename),"file")
+ elseif type(destination) == "string" then
+ add_link(x,y,w,h,formatters["%s::%s"](filename,destination),"file (named)")
+ else
+ destination = destination[1] -- array
+ if tonumber(destination) then
+ add_link(x,y,w,h,formatters["%s::page(%s)"](filename,destination),"file (page)")
+ else
+ add_link(x,y,w,h,formatters["file(%s)"](filename),"file")
+ end
+ end
+ end
+ end
+end
+
+function 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.epdf.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 pagedata = document.pages[pagenumber]
+ local annotations = pagedata and pagedata.Annots
+ if annotations and annotations.n > 0 then
+ local namespace = format("lpdf-epa-%s-",file.removesuffix(file.basename(fullname)))
+ local reference = namespace .. pagenumber
+ local mediabox = pagedata.MediaBox
+ local llx, lly, urx, ury = mediabox[1], mediabox[2], mediabox[3], mediabox[4]
+ local width, height = xscale * (urx - llx), yscale * (ury - lly) -- \\overlaywidth, \\overlayheight
+ context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" })
+ for i=1,annotations.n do
+ local annotation = annotations[i]
+ if annotation then
+ local subtype = annotation.Subtype
+ local rectangle = annotation.Rect
+ local a_llx, a_lly, a_urx, a_ury = rectangle[1], rectangle[2], rectangle[3], rectangle[4]
+ 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 a = annotation.A
+ if a then
+ local linktype = a.S
+ if linktype == "GoTo" then
+ link_goto(x,y,w,h,document,annotation,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 %a",linktype)
+ end
+ else
+ report_link("mising link annotation")
+ end
+ elseif trace_links then
+ report_link("unsupported annotation %a",subtype)
+ end
+ elseif trace_links then
+ report_link("broken annotation, index %a",i)
+ end
+ end
+ context.flushlayer { "epdflinks" }
+ -- context("\\gdef\\figurereference{%s}",reference) -- global
+ context.setgvalue("figurereference",reference) -- global
+ if trace_links then
+ report_link("setting figure reference to %a",reference)
+ end
+ specification.reference = reference
+ return namespace
+ end
+ end
+ end
+ return ""-- no namespace, empty, not nil
+end
+
+function codeinjections.mergeviewerlayers(specification)
+ -- todo: parse included page for layers
+ if true then
+ return
+ end
+ 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.epdf.load(fullname)
+ if document then
+ local namespace = format("lpdf:epa:%s:",file.removesuffix(file.basename(fullname)))
+ local layers = document.layers
+ if layers then
+ for i=1,layers.n do
+ local layer = layers[i]
+ if layer then
+ local tag = namespace .. gsub(layer," ",":")
+ local title = tag
+ if trace_links then
+ report_link("using layer %a",tag)
+ end
+ attributes.viewerlayers.define { -- also does some cleaning
+ tag = tag, -- todo: #3A or so
+ title = title,
+ visible = variables.start,
+ editable = variables.yes,
+ printable = variables.yes,
+ }
+ codeinjections.useviewerlayer(tag)
+ elseif trace_links then
+ report_link("broken layer, index %a",i)
+ end
+ end
+ end
+ end
+ end
+end
+
|