diff options
author | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
commit | 85b7bc695629926641c7cb752fd478adfdf374f3 (patch) | |
tree | 80293f5aaa7b95a500a78392c39688d8ee7a32fc /tex/context/base/lpdf-wid.lua | |
download | context-85b7bc695629926641c7cb752fd478adfdf374f3.tar.gz |
stable 2010-05-24 13:10
Diffstat (limited to 'tex/context/base/lpdf-wid.lua')
-rw-r--r-- | tex/context/base/lpdf-wid.lua | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua new file mode 100644 index 000000000..40a81e7d4 --- /dev/null +++ b/tex/context/base/lpdf-wid.lua @@ -0,0 +1,355 @@ +if not modules then modules = { } end modules ['lpdf-wid'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gmatch, gsub, find = string.format, string.gmatch, string.gsub, string.find +local texsprint, ctxcatcodes, texbox, texcount = tex.sprint, tex.ctxcatcodes, tex.box, tex.count + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local executers = jobreferences.executers +local variables = interfaces.variables + +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfcolorspec = lpdf.colorspec +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject + +local pdfreserveobj = pdf.reserveobj +local pdfimmediateobj = pdf.immediateobj + +local pdfannotation = nodes.pdfannotation + +local hpack_node, write_node = node.hpack, node.write + +-- symbols + +local presets = { } -- xforms + +function codeinjections.registersymbol(name,n) + presets[name] = pdfreference(n) +end + +function codeinjections.registeredsymbol(name) + return presets[name] +end + +function codeinjections.presetsymbol(symbol) + if not presets[symbol] then + texsprint(ctxcatcodes,format("\\predefinesymbol[%s]",symbol)) + end +end + +function codeinjections.presetsymbollist(list) + if list then + for symbol in gmatch(list,"[^, ]+") do + codeinjections.presetsymbol(symbol) + end + end +end + +-- comments + +local symbols = { + New = pdfconstant("Insert"), + Insert = pdfconstant("Insert"), + Balloon = pdfconstant("Comment"), + Comment = pdfconstant("Comment"), + Text = pdfconstant("Note"), + Addition = pdfconstant("NewParagraph"), + NewParagraph = pdfconstant("NewParagraph"), + Help = pdfconstant("Help"), + Paragraph = pdfconstant("Paragraph"), + Key = pdfconstant("Key"), + Graph = pdfconstant("Graph"), + Paperclip = pdfconstant("Paperclip"), + Attachment = pdfconstant("Attachment"), + Tag = pdfconstant("Tag"), +} + +symbols[variables.normal] = pdfconstant("Note") + +local nofcomments, usepopupcomments, stripleading = 0, true, true + +local function analyzesymbol(symbol) + if not symbol or symbol == "" then + return symbols.normal, nil + elseif symbols[symbol] then + return symbols[symbol], nil + else + local set = aux.settings_to_array(symbol) + local normal, down = set[1], set[2] + if normal then + normal = codeinjections.registeredsymbol(down or normal) + end + if down then + down = codeinjections.registeredsymbol(normal) + end + if down or normal then + return nil, pdfdictionary { + N = normal, + D = down, + } + end + end +end + +local function analyzelayer(layer) + -- todo: (specification.layer ~= "" and pdfreference(specification.layer)) or nil, -- todo: ref to layer +end + +function codeinjections.registercomment(specification) + nofcomments = nofcomments + 1 + local text = buffers.collect(specification.buffer) + if stripleading then + text = gsub(text,"[\n\r] *","\n") + end + local name, appearance = analyzesymbol(specification.symbol) + local d = pdfdictionary { + Subtype = pdfconstant("Text"), + Open = specification.open, + Contents = pdfunicode(text), + T = (specification.title ~= "" and pdfunicode(specification.title)) or nil, + C = pdfcolorspec(specification.colormodel,specification.colorvalue), + OC = analyzelayer(specification.layer), + Name = name, + AP = appearance, + } + -- watch the nice feed back to tex hack + if usepopupcomments then + local nd = pdfreserveobject() + local nc = pdfreserveobject() + local c = pdfdictionary { + Subtype = pdfconstant("Popup"), + Parent = pdfreference(nd), + } + d.Popup = pdfreference(nc) + texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d(),nd)) -- current dir + texbox["commentboxtwo"] = hpack_node(pdfannotation(specification.width,specification.height,0,c(),nc)) -- current dir + else + texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d())) -- current dir + texbox["commentboxtwo"] = nil + end +end + +-- + +local nofattachments, attachments, filestreams = 0, { }, { } + +function codeinjections.embedfile(filename) + local r = filestreams[filename] + if r == false then + return nil + elseif r then + return r + elseif not lfs.isfile(filename) then + interfaces.showmessage("interactions",5,filename) + filestreams[filename] = false + return nil + else + local basename = file.basename(filename) + local a = pdfdictionary { Type = pdfconstant("EmbeddedFile") } + local f = pdfimmediateobj("streamfile",filename,a()) + local d = pdfdictionary { + Type = pdfconstant("Filespec"), + F = pdfstring(newname or basename), + UF = pdfstring(newname or basename), + EF = pdfdictionary { F = pdfreference(f) }, + } + local r = pdfreference(pdfflushobject(d)) + filestreams[filename] = r + return r + end +end + +function codeinjections.attachfile(specification) + local attachment = interactions.attachment(specification.label) + if not attachment then + -- todo: message + return + end + local filename = attachment.filename + if not filename or filename == "" then + -- todo: message + return + end + nofattachments = nofattachments + 1 + local label = attachment.label or "" + local title = attachment.title or "" + local newname = attachment.newname or "" + if label == "" then label = filename end + if title == "" then title = label end + if newname == "" then newname = filename end + local aref = attachments[label] + if not aref then + aref = codeinjections.embedfile(filename,newname) + attachments[label] = aref + end + local name, appearance = analyzesymbol(specification.symbol) + local d = pdfdictionary { + Subtype = pdfconstant("FileAttachment"), + FS = aref, + Contents = pdfunicode(title), + Name = name, + AP = appearance, + OC = analyzelayer(specification.layer), + C = pdfcolorspec(specification.colormodel,specification.colorvalue), + } + -- as soon as we can ask for the dimensions of an xform we can + -- use them here + local width = specification.width or 0 + local height = specification.height or 0 + local depth = specification.depth or 0 + write_node(pdfannotation(width,height,depth,d())) +end + +function codeinjections.attachmentid(filename) + return filestreams[filename] +end + +-- rendering stuff +-- +-- object_1 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >> +-- object_2 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >> +-- rendering -> <</Type /Rendition /S /MS [objref_1 objref_2]>> +-- +-- we only work foreward here +-- annotation is to be packed at the tex end + +-- aiff audio/aiff +-- au audio/basic +-- avi video/avi +-- mid audio/midi +-- mov video/quicktime +-- mp3 audio/x-mp3 (mpeg) +-- mp4 audio/mp4 +-- mp4 video/mp4 +-- mpeg video/mpeg +-- smil application/smil +-- swf application/x-shockwave-flash + +local ms, mu, mf = { }, { }, { } + +local delayed = { } + +local function insertrenderingwindow(label,width,height,specification) + if options == variables.auto then + if openpageaction then + -- \handlereferenceactions{\v!StartRendering{#2}} + end + if closepageaction then + -- \handlereferenceactions{\v!StopRendering {#2}} + end + end + local actions = nil + if openpage or closepage then + actions = pdfdictionary { + PO = (openpage and lpdf.pdfaction(openpage )) or nil, + PC = (closepage and lpdf.pdfaction(closepage)) or nil, + } + end + local page = tonumber(specification.page) or texcount.realpageno + local d = pdfdictionary { + Subtype = pdfconstant("Screen"), + P = pdfreference(tex.pdfpageref(page)), + A = mf[label], + Border = pdfarray { 0, 0, 0 } , + AA = actions, + } + local r = pdfreserveobj("annot") + write_node(pdfannotation(width,height,0,d(),r)) -- save ref + return pdfreference(r) +end + +local function insertrendering(specification) + local label = specification.label + if not mf[label] then + local filename = specification.filename + local isurl = find(filename,"://") + local d = pdfdictionary { + Type = pdfconstant("Rendition"), + S = pdfconstant("MR"), + C = pdfdictionary { + Type = pdfconstant("MediaClip"), + S = pdfconstant("MCD"), + N = label, + CT = specification.mime, + Alt = pdfarray { + "", "file not found", -- language id + message + }, + D = pdfdictionary { + Type = pdfconstant("Filespec"), + F = filename, + FS = (isurl and pdfconstant("URL")) or nil, + } + } + } + mf[label] = pdfreference(pdfflushobject(d)) + if not ms[label] then + mu[label] = insertrenderingwindow(label,0,0,specification.options) + end + end +end + +local function insertrenderingobject(specification) + local label = specification.label + if not mf[label] then + local d = pdfdictionary { + Type = pdfconstant("Rendition"), + S = pdfconstant("MR"), + C = pdfdictionary { + Type = pdfconstant("MediaClip"), + S = pdfconstant("MCD"), + N = label, + D = pdfreference(unknown), -- not label but objectname, hm + } + } + mf[label] = pdfreference(pdfflushobject(d)) + if ms[label] then + insertrenderingwindow(label,0,0,specification) + end + end +end + +function codeinjections.insertrenderingwindow(specification) + local label = specification.label + codeinjections.processrendering(label) -- was check at tex end + ms[label] = insertrenderingwindow(label,specification.width,specification.height,specification) +end + +function codeinjections.processrendering(label) + local specification = interactions.rendering(label) + if specification then + if specification.kind == "external" then + insertrendering(specification) + else + insertrenderingobject(specification) + end + end +end + +local function set(operation,arguments) + codeinjections.processrendering(arguments) -- was check at the tex end + return pdfdictionary { + S = pdfconstant("Rendition"), + OP = operation, + R = mf[arguments], + AN = ms[arguments] or mu[arguments], + } +end + +function executers.startrendering (arguments) return set(0,arguments) end +function executers.stoprendering (arguments) return set(1,arguments) end +function executers.pauserendering (arguments) return set(2,arguments) end +function executers.resumerendering(arguments) return set(3,arguments) end |