diff options
Diffstat (limited to 'tex/context/base/mkiv/lpdf-ano.lua')
-rw-r--r-- | tex/context/base/mkiv/lpdf-ano.lua | 207 |
1 files changed, 90 insertions, 117 deletions
diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua index 21bc1e076..f4f5f1a8e 100644 --- a/tex/context/base/mkiv/lpdf-ano.lua +++ b/tex/context/base/mkiv/lpdf-ano.lua @@ -153,10 +153,7 @@ end) -- the caching is somewhat memory intense on the one hand but -- it saves many small temporary tables so it might pay off -local pagedestinations = allocate() -local pagereferences = allocate() -- annots are cached themselves - -setmetatableindex(pagedestinations, function(t,k) +local pagedestinations = setmetatableindex(function(t,k) k = tonumber(k) if not k or k <= 0 then return pdfnull() @@ -174,7 +171,7 @@ setmetatableindex(pagedestinations, function(t,k) return v end) -setmetatableindex(pagereferences,function(t,k) +local pagereferences = setmetatableindex(function(t,k) k = tonumber(k) if not k or k <= 0 then return nil @@ -191,9 +188,6 @@ setmetatableindex(pagereferences,function(t,k) return v end) -lpdf.pagereferences = pagereferences -- table -lpdf.pagedestinations = pagedestinations -- table - local defaultdestination = pdfarray { 0, pdf_fit } -- fit is default (see lpdf-nod) @@ -369,6 +363,7 @@ local destinationactions = { -- [v_minheight] = function(r,w,h,d) return f_fitbv(r,(getvpos()+h)*factor) end, -- left coordinate, fit height of content in window [v_minheight] = function(r,w,h,d) return f_fitbv(r,gethpos()*factor) end, -- left coordinate, fit height of content in window [v_fit] = f_fit, -- fit page in window [v_tight] = f_fitb, -- fit content in window + -- new: [v_fit] = f_fit, } @@ -387,10 +382,10 @@ local defaultview = v_fit local defaultaction = destinationactions[defaultview] -- A complication is that we need to use named destinations when we have views so we --- end up with a mix. A previous versions just output multiple destinations but not +-- end up with a mix. A previous versions just output multiple destinations but now -- that we moved all to here we can be more sparse. -local pagedestinations = table.setmetatableindex(function(t,k) +local pagedestinations = setmetatableindex(function(t,k) -- not the same as the one above! local v = pdfdelayedobject(f_fit(k)) t[k] = v return v @@ -424,49 +419,19 @@ function nodeinjections.destination(width,height,depth,names,view) -- we could save some aut's by using a name when given but it doesn't pay off apart -- from making the code messy and tracing hard .. we only save some destinations -- which we already share anyway - -- for n=1,#names do - -- local name = names[n] - -- if usedviews[name] then - -- -- already done, maybe a warning - -- elseif type(name) == "number" then - -- if noview then - -- usedviews[name] = view - -- names[n] = false - -- elseif method == v_page then - -- usedviews[name] = view - -- names[n] = false - -- else - -- local used = usedinternals[name] - -- if used and used ~= defaultview then - -- usedviews[name] = view - -- names[n] = autoprefix .. name - -- doview = true - -- else - -- -- names[n] = autoprefix .. name - -- names[n] = false - -- end - -- end - -- elseif method == v_page then - -- usedviews[name] = view - -- else - -- usedviews[name] = view - -- doview = true - -- end - -- end - if method == v_page then for n=1,#names do local name = names[n] if usedviews[name] then -- already done, maybe a warning elseif type(name) == "number" then - if noview then - usedviews[name] = view - names[n] = false - else + -- if noview then + -- usedviews[name] = view + -- names[n] = false + -- else usedviews[name] = view names[n] = false - end + -- end else usedviews[name] = view end @@ -519,56 +484,55 @@ end -- we could share dictionaries ... todo -local function somedestination(destination,internal,page) -- no view anyway +local function pdflinkpage(page) + return pagereferences[page] +end + +local function pdflinkinternal(internal,page) local method = references.innermethod - if method == v_auto then - if type(destination) == "number" then - if not internal then - internal = destination - end - destination = nil + if internal then + flaginternals[internal] = true -- for bookmarks and so + local used = usedinternals[internal] + if used == defaultview or used == true then + return pagereferences[page] end - if internal then - flaginternals[internal] = true -- for bookmarks and so - local used = usedinternals[internal] - if used == defaultview or used == true then - return pagereferences[page] - end - if type(destination) ~= "string" then - destination = autoprefix .. internal - end - return pdfdictionary { - S = pdf_goto, - D = destination, - } - elseif destination then - -- hopefully this one is flushed - return pdfdictionary { - S = pdf_goto, - D = destination, - } + if type(internal) ~= "string" then + internal = autoprefix .. internal end - elseif method == v_name then - if not destination and internal then - flaginternals[internal] = true -- for bookmarks and so - if type(destination) ~= "string" then - destination = autoprefix .. internal - end - end - if destination then - return pdfdictionary { - S = pdf_goto, - D = destination, - } + return pdfdictionary { + S = pdf_goto, + D = internal, + } + else + return pagereferences[page] + end +end + +local function pdflinkname(destination,internal,page) + local method = references.innermethod + if method == v_auto then + flaginternals[internal] = true -- for bookmarks and so + local used = usedinternals[internal] + if used == defaultview then -- or used == true then + return pagereferences[page] end + return pdfdictionary { + S = pdf_goto, + D = destination, + } + elseif method == v_name then + -- flaginternals[internal] = true -- for bookmarks and so + return pdfdictionary { + S = pdf_goto, + D = destination, + } + else + return pagereferences[page] end - return pagereferences[page] end -- annotations -local pdflink = somedestination - local function pdffilelink(filename,destination,page,actions) if not filename or filename == "" or file.basename(filename) == tex.jobname then return false @@ -701,7 +665,7 @@ local f_annot = formatters["<< /Type /Annot %s /Rect [ %0.3F %0.3F %0.3F %0.3F ] directives.register("refences.sharelinks", function(v) share = v end) -table.setmetatableindex(hashed,function(t,k) +setmetatableindex(hashed,function(t,k) local v = pdfdelayedobject(k) if share then t[k] = v @@ -781,37 +745,46 @@ end) -- runners and specials +local splitter = lpeg.splitat(",",true) + runners["inner"] = function(var,actions) local internal = false - local inner = nil + local name = nil local method = references.innermethod - if method == v_auto or method == v_name then - local vi = var.i - if vi then - local vir = vi.references - if vir then - -- todo: no need for it when we have a real reference - local reference = vir.reference - if reference and reference ~= "" then - var.inner = reference - local prefix = var.p - if prefix and prefix ~= "" then - var.prefix = prefix - inner = prefix .. ":" .. reference - else - inner = reference - end - end - internal = vir.internal - if internal then - flaginternals[internal] = true + local vi = var.i + local page = var.page + if vi then + local vir = vi.references + if vir then + -- todo: no need for it when we have a real reference ... although we need + -- this mess for prefixes anyway + local reference = vir.reference + if reference and reference ~= "" then + reference = lpegmatch(splitter,reference) or reference + var.inner = reference + local prefix = var.p + if prefix and prefix ~= "" then + var.prefix = prefix + name = prefix .. ":" .. reference + else + name = reference end end + internal = vir.internal + if internal then + flaginternals[internal] = true + end end + end + if name then + return pdflinkname(name,internal,page) + elseif internal then + return pdflinkinternal(internal,page) + elseif page then + return pdflinkpage(page) else - var.inner = nil + -- real bad end - return pdflink(inner,internal,var.r) end runners["inner with arguments"] = function(var,actions) @@ -878,7 +851,7 @@ function specials.internal(var,actions) -- better resolve in strc-ref report_reference("no internal reference %a",i or "<unset>") else flaginternals[i] = true - return pdflink(nil,i,v.references.realpage) + return pdflinkinternal(i,v.references.realpage) end end @@ -902,7 +875,7 @@ function specials.page(var,actions) p = references.realpageofpage(tonumber(p)) end end - return pdflink(nil,nil,p or var.operation) + return pdflinkpage(p or var.operation) end end @@ -911,7 +884,7 @@ function specials.realpage(var,actions) if file then return pdffilelink(references.checkedfile(file),nil,var.operation,actions) else - return pdflink(nil,nil,var.operation) + return pdflinkpage(var.operation) end end @@ -930,7 +903,7 @@ function specials.userpage(var,actions) -- var.r = p -- end end - return pdflink(nil,nil,p or var.operation) + return pdflinkpage(p or var.operation) end end @@ -938,7 +911,7 @@ function specials.deltapage(var,actions) local p = tonumber(var.operation) if p then p = references.checkedrealpage(p + texgetcount("realpageno")) - return pdflink(nil,nil,p) + return pdflinkpage(p) end end @@ -1195,7 +1168,7 @@ local function build(levels,start,parent,method,nested) end local action = nil if variant == "list" then - action = somedestination(reference.internal,reference.internal,reference.realpage) + action = pdflinkinternal(reference.internal,reference.realpage) elseif variant == "realpage" then action = pagereferences[realpage] else @@ -1207,7 +1180,7 @@ local function build(levels,start,parent,method,nested) Prev = prev and pdfreference(prev), A = action, } - -- entry.Dest = somedestination(reference.internal,reference.internal,reference.realpage) + -- entry.Dest = pdflinkinternal(reference.internal,reference.realpage) if not first then first, last = child, child end |