diff options
Diffstat (limited to 'tex/context/base/mkiv/lpdf-wid.lua')
-rw-r--r-- | tex/context/base/mkiv/lpdf-wid.lua | 339 |
1 files changed, 182 insertions, 157 deletions
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua index a538a9ad2..96b36324f 100644 --- a/tex/context/base/mkiv/lpdf-wid.lua +++ b/tex/context/base/mkiv/lpdf-wid.lua @@ -222,6 +222,25 @@ local referenced = { } local ignorereferenced = true -- fuzzy pdf spec .. twice in attachment list, can become an option local tobesavedobjrefs = utilities.storage.allocate() local collectedobjrefs = utilities.storage.allocate() +local permitted = true +local enabled = true +local embedded = true + +function codeinjections.setattachmentsupport(option) + if option == false then + permitted = false + enabled = false + embedded = true + elseif not permitted then + -- already dealt with + elseif option == "internal" or option == true then + enabled = true + embedded = true + elseif option == "external" then + enabled = true + embedded = false + end +end local fileobjreferences = { collected = collectedobjrefs, @@ -238,7 +257,7 @@ end job.register('job.fileobjreferences.collected', tobesavedobjrefs, initializer) local function flushembeddedfiles() - if next(filestreams) then + if enabled and next(filestreams) then local e = pdfarray() for tag, reference in sortedhash(filestreams) do if not reference then @@ -259,178 +278,182 @@ end lpdf.registerdocumentfinalizer(flushembeddedfiles,"embeddedfiles") function codeinjections.embedfile(specification) - local data = specification.data - local filename = specification.file - local name = specification.name or "" - local title = specification.title or "" - local hash = specification.hash or filename - local keepdir = specification.keepdir -- can change - local usedname = specification.usedname - local filetype = specification.filetype - local compress = specification.compress - local mimetype = specification.mimetype or specification.mime - if filename == "" then - filename = nil - end - if compress == nil then - compress = true - end - if data then - local r = filestreams[hash] - if r == false then - return nil - elseif r then - return r - elseif not filename then - filename = specification.tag - if not filename or filename == "" then - filename = specification.registered + if enabled then + local data = specification.data + local filename = specification.file + local name = specification.name or "" + local title = specification.title or "" + local hash = specification.hash or filename + local keepdir = specification.keepdir -- can change + local usedname = specification.usedname + local filetype = specification.filetype + local compress = specification.compress + local mimetype = specification.mimetype or specification.mime + if filename == "" then + filename = nil + end + if compress == nil then + compress = true + end + if data then + local r = filestreams[hash] + if r == false then + return nil + elseif r then + return r + elseif not filename then + filename = specification.tag + if not filename or filename == "" then + filename = specification.registered + end + if not filename or filename == "" then + filename = hash + end end - if not filename or filename == "" then - filename = hash + else + if not filename then + return nil + end + local r = filestreams[hash] + if r == false then + return nil + elseif r then + return r + else + local foundname = resolvers.findbinfile(filename) or "" + if foundname == "" or not lfs.isfile(foundname) then + filestreams[filename] = false + return nil + else + specification.foundname = foundname + end end end - else - if not filename then - return nil + -- needs to cleaned up: + usedname = usedname ~= "" and usedname or filename or name + local basename = keepdir == true and usedname or file.basename(usedname) + local basename = gsub(basename,"%./","") + local savename = name ~= "" and name or basename + if not filetype or filetype == "" then + filetype = name and (filename and file.suffix(filename)) or "txt" end - local r = filestreams[hash] - if r == false then - return nil - elseif r then - return r + savename = file.addsuffix(savename,filetype) -- type is mandate for proper working in viewer + local a = pdfdictionary { + Type = pdfconstant("EmbeddedFile"), + Subtype = mimetype and mimetype ~= "" and pdfconstant(mimetype) or nil, + } + local f + if data then + f = pdfflushstreamobject(data,a) + specification.data = true -- signal that still data but already flushed else + local foundname = specification.foundname or filename + local attributes = lfs.attributes(foundname) + if attributes then + a.Params = { + Size = attributes.size, + ModDate = lpdf.pdftimestamp(attributes.modification), + } + end + f = pdfflushstreamfileobject(foundname,a,compress) + end + local d = pdfdictionary { + Type = pdfconstant("Filespec"), + F = pdfstring(savename), + -- UF = pdfstring(savename), + UF = pdfunicode(savename), + EF = pdfdictionary { F = pdfreference(f) }, + Desc = title ~= "" and pdfunicode(title) or nil, + AFRelationship = pdfconstant("Unspecified"), -- Supplement, Data, Source, Alternative, Data + } + local r = pdfreference(pdfflushobject(d)) + filestreams[hash] = r + return r + end +end + +function nodeinjections.attachfile(specification) + if enabled then + local registered = specification.registered or "<unset>" + local data = specification.data + local hash + local filename + if data then + hash = md5.HEX(data) + else + filename = specification.file + if not filename or filename == "" then + report_attachment("no file specified, using registered %a instead",registered) + filename = registered + specification.file = registered + end local foundname = resolvers.findbinfile(filename) or "" if foundname == "" or not lfs.isfile(foundname) then - filestreams[filename] = false + report_attachment("invalid filename %a, ignoring registered %a",filename,registered) return nil else specification.foundname = foundname end + hash = filename end - end - -- needs to cleaned up: - usedname = usedname ~= "" and usedname or filename or name - local basename = keepdir == true and usedname or file.basename(usedname) - local basename = gsub(basename,"%./","") - local savename = name ~= "" and name or basename - if not filetype or filetype == "" then - filetype = name and (filename and file.suffix(filename)) or "txt" - end - savename = file.addsuffix(savename,filetype) -- type is mandate for proper working in viewer - local a = pdfdictionary { - Type = pdfconstant("EmbeddedFile"), - Subtype = mimetype and mimetype ~= "" and pdfconstant(mimetype) or nil, - } - local f - if data then - f = pdfflushstreamobject(data,a) - specification.data = true -- signal that still data but already flushed - else - local foundname = specification.foundname or filename - local attributes = lfs.attributes(foundname) - if attributes then - a.Params = { - Size = attributes.size, - ModDate = lpdf.pdftimestamp(attributes.modification), - } + specification.hash = hash + nofattachments = nofattachments + 1 + local registered = specification.registered or "" + local title = specification.title or "" + local subtitle = specification.subtitle or "" + local author = specification.author or "" + if registered == "" then + registered = filename end - f = pdfflushstreamfileobject(foundname,a,compress) - end - local d = pdfdictionary { - Type = pdfconstant("Filespec"), - F = pdfstring(savename), - -- UF = pdfstring(savename), - UF = pdfunicode(savename), - EF = pdfdictionary { F = pdfreference(f) }, - Desc = title ~= "" and pdfunicode(title) or nil, - AFRelationship = pdfconstant("Unspecified"), -- Supplement, Data, Source, Alternative, Data - } - local r = pdfreference(pdfflushobject(d)) - filestreams[hash] = r - return r -end - -function nodeinjections.attachfile(specification) - local registered = specification.registered or "<unset>" - local data = specification.data - local hash - local filename - if data then - hash = md5.HEX(data) - else - filename = specification.file - if not filename or filename == "" then - report_attachment("no file specified, using registered %a instead",registered) - filename = registered - specification.file = registered + if author == "" and title ~= "" then + author = title + title = filename or "" + end + if author == "" then + author = filename or "<unknown>" + end + if title == "" then + title = registered end - local foundname = resolvers.findbinfile(filename) or "" - if foundname == "" or not lfs.isfile(foundname) then - report_attachment("invalid filename %a, ignoring registered %a",filename,registered) - return nil + local aref = attachments[registered] + if not aref then + aref = codeinjections.embedfile(specification) + attachments[registered] = aref + end + local reference = specification.reference + if reference and aref then + tobesavedobjrefs[reference] = aref[1] + end + if not aref then + report_attachment("skipping attachment, registered %a",registered) + -- already reported + elseif specification.method == v_hidden then + referenced[hash] = "hidden" else - specification.foundname = foundname + referenced[hash] = "annotation" + local name, appearance = analyzesymbol(specification.symbol,attachment_symbols) + local d = pdfdictionary { + Subtype = pdfconstant("FileAttachment"), + FS = aref, + Contents = pdfunicode(title), + Name = name, + NM = pdfstring("attachment:"..nofattachments), + T = author ~= "" and pdfunicode(author) or nil, + Subj = subtitle ~= "" and pdfunicode(subtitle) or nil, + C = analyzecolor(specification.colorvalue,specification.colormodel), + CA = analyzetransparency(specification.transparencyvalue), + AP = appearance, + OC = analyzelayer(specification.layer), + } + local width = specification.width or 0 + local height = specification.height or 0 + local depth = specification.depth or 0 + local box = hpack_node(nodeinjections.annotation(width,height,depth,d())) + box.width = width + box.height = height + box.depth = depth + return box end - hash = filename - end - specification.hash = hash - nofattachments = nofattachments + 1 - local registered = specification.registered or "" - local title = specification.title or "" - local subtitle = specification.subtitle or "" - local author = specification.author or "" - if registered == "" then - registered = filename - end - if author == "" and title ~= "" then - author = title - title = filename or "" - end - if author == "" then - author = filename or "<unknown>" - end - if title == "" then - title = registered - end - local aref = attachments[registered] - if not aref then - aref = codeinjections.embedfile(specification) - attachments[registered] = aref - end - local reference = specification.reference - if reference and aref then - tobesavedobjrefs[reference] = aref[1] - end - if not aref then - report_attachment("skipping attachment, registered %a",registered) - -- already reported - elseif specification.method == v_hidden then - referenced[hash] = "hidden" - else - referenced[hash] = "annotation" - local name, appearance = analyzesymbol(specification.symbol,attachment_symbols) - local d = pdfdictionary { - Subtype = pdfconstant("FileAttachment"), - FS = aref, - Contents = pdfunicode(title), - Name = name, - NM = pdfstring("attachment:"..nofattachments), - T = author ~= "" and pdfunicode(author) or nil, - Subj = subtitle ~= "" and pdfunicode(subtitle) or nil, - C = analyzecolor(specification.colorvalue,specification.colormodel), - CA = analyzetransparency(specification.transparencyvalue), - AP = appearance, - OC = analyzelayer(specification.layer), - } - local width = specification.width or 0 - local height = specification.height or 0 - local depth = specification.depth or 0 - local box = hpack_node(nodeinjections.annotation(width,height,depth,d())) - box.width = width - box.height = height - box.depth = depth - return box end end @@ -438,6 +461,8 @@ function codeinjections.attachmentid(filename) -- not used in context return filestreams[filename] end +-- Comments + local nofcomments = 0 local usepopupcomments = false |