From 64f6e8fc0c6cb9254a6fe3db0b4ab31c51cf8524 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 4 Apr 2019 14:11:01 +0200 Subject: 2019-04-04 13:38:00 --- tex/context/base/mkiv/back-out.lua | 291 +++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 tex/context/base/mkiv/back-out.lua (limited to 'tex/context/base/mkiv/back-out.lua') diff --git a/tex/context/base/mkiv/back-out.lua b/tex/context/base/mkiv/back-out.lua new file mode 100644 index 000000000..a0e05afca --- /dev/null +++ b/tex/context/base/mkiv/back-out.lua @@ -0,0 +1,291 @@ +if not modules then modules = { } end modules ['back-out'] = { + 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" +} + +if CONTEXTLMTXMODE == 0 then + + return + +elseif CONTEXTLMTXMODE == 1 then + + local type = type + local getdata = nodes.nuts.getdata + local loadstring = loadstring + + function backends.latelua(current,pos_h,pos_v,cur_h,cur_v) + data = getdata(current) + local kind = type(data) + if kind == "function" then + data() + elseif kind == "table" then + data.action(data) + else + -- if kind ~= "string" then + -- data = tokentostring(data) + -- end + if #data ~= "" then + local code = loadstring(data) + if code then + code() + end + end + end + end + + return +end + +local type = type +local loadstring = loadstring + +local context = context + +-- tokens.scanners..... + +local get = token.get_index +local scaninteger = token.scan_int +local scanstring = token.scan_string +local scankeyword = token.scan_keyword +local scantokenlist = token.scan_tokenlist +local scancode = token.scan_code + +local tokentostring = token.to_string + +local logwriter = logs.writer +local openfile = io.open + +local nuts = nodes.nuts +local tonode = nuts.tonode +local copynode = nuts.copy +local nodepool = nuts.pool + +local getdata = nuts.getdata + +local whatsit_code = nodes.nodecodes.whatsit + +local whatsitcodes = nodes.whatsitcodes + +local literalvalues = nodes.literalvalues +local originliteral_code = literalvalues.origin +local pageliteral_code = literalvalues.page +local directliteral_code = literalvalues.direct +local rawliteral_code = literalvalues.raw + +local nodeproperties = nodes.properties.data + +local channels = { } + +local register = nodepool.register +local newnut = nuts.new + +local opennode = register(newnut(whatsit_code,whatsitcodes.open)) +local writenode = register(newnut(whatsit_code,whatsitcodes.write)) +local closenode = register(newnut(whatsit_code,whatsitcodes.close)) +local lateluanode = register(newnut(whatsit_code,whatsitcodes.latelua)) +local literalnode = register(newnut(whatsit_code,whatsitcodes.literal)) +local savenode = register(newnut(whatsit_code,whatsitcodes.save)) +local restorenode = register(newnut(whatsit_code,whatsitcodes.restore)) +local setmatrixnode = register(newnut(whatsit_code,whatsitcodes.setmatrix)) + +local tomatrix = drivers.helpers.tomatrix + +local open_command, write_command, close_command + +backends = backends or { } + +local function openout(immediate) + local channel = scaninteger() + scankeyword("=") -- hack + local filename = scanstring() + if not immediate then + local n = copynode(opennode) + nodeproperties[n] = { channel = channel, filename = filename } -- action = "open" + return context(tonode(n)) + elseif not channels[channel] then + local handle = openfile(filename,"wb") or false + if handle then + channels[channel] = handle + else + -- error + end + end +end + +function backends.openout(n) + local p = nodeproperties[n] + if p then + local handle = openfile(p.filename,"wb") or false + if handle then + channels[p.channel] = handle + else + -- error + end + end +end + +local function write(immediate) + local channel = scaninteger() + if not immediate then + local t = scantokenlist() + local n = copynode(writenode) + nodeproperties[n] = { channel = channel, data = t } -- action = "write" + return context(tonode(n)) + else + local content = scanstring() + local handle = channels[channel] + if handle then + handle:write(content,"\n") + else + logwriter(content,"\n") + end + end +end + +function backends.writeout(n) + local p = nodeproperties[n] + if p then + local handle = channels[p.channel] + local content = tokentostring(p.data) + if handle then + handle:write(content,"\n") + else + logwriter(content,"\n") + end + end +end + +local function closeout(immediate) + local channel = scaninteger() + if not immediate then + local n = copynode(closenode) + nodeproperties[n] = { channel = channel } -- action = "close" + return context(tonode(n)) + else + local handle = channels[channel] + if handle then + handle:close() + channels[channel] = false + else + -- error + end + end +end + +function backends.closeout(n) + local p = nodeproperties[n] + if p then + local channel = p.channel + local handle = channels[channel] + if handle then + handle:close() + channels[channel] = false + else + -- error + end + end +end + +local function immediate() + local command = scancode() + if command == write_command then + write(true) + elseif command == open_command then + openout(true) + elseif command == close_command then + closeout(true) + end +end + +local noflatelua = 0 + +local function latelua() + local node = copynode(lateluanode) + local name = "latelua" + if scankeyword("name") then + name = scanstring() + end + local data = scantokenlist() + nodeproperties[node] = { name = name, data = data } + return context(tonode(node)) +end + +function backends.latelua(current,pos_h,pos_v,cur_h,cur_v) + local p = nodeproperties[current] + if p then + data = p.data + else + data = getdata(current) + end + noflatelua = noflatelua + 1 + local kind = type(data) + if kind == "table" then + data.action(data.specification or data) + elseif kind == "function" then + data() + else + if kind ~= "string" then + data = tokentostring(data) + end + if #data ~= "" then + local code = loadstring(data) + if code then + code() + end + end + end +end + +function backends.noflatelua() + return noflatelua +end + +function nodepool.originliteral(str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = originliteral_code } return t end +function nodepool.pageliteral (str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = pageliteral_code } return t end +function nodepool.directliteral(str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = directliteral_code } return t end +function nodepool.rawliteral (str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = rawliteral_code } return t end + +local pdfliterals = { + [originliteral_code] = originliteral_code, [literalvalues[originliteral_code]] = originliteral_code, + [pageliteral_code] = pageliteral_code, [literalvalues[pageliteral_code]] = pageliteral_code, + [directliteral_code] = directliteral_code, [literalvalues[directliteral_code]] = directliteral_code, + [rawliteral_code] = rawliteral_code, [literalvalues[rawliteral_code]] = rawliteral_code, +} + +function nodepool.literal(mode,str) + local t = copynode(literalnode) + if str then + nodeproperties[t] = { data = str, mode = pdfliterals[mode] or pageliteral_code } + else + nodeproperties[t] = { data = mode, mode = pageliteral_code } + end + return t +end + +function nodepool.save() + return copynode(savenode) +end + +function nodepool.restore() + return copynode(restorenode) +end + +function nodepool.setmatrix(rx,sx,sy,ry,tx,ty) + local t = copynode(setmatrixnode) + nodeproperties[t] = { matrix = tomatrix(rx,sx,sy,ry,tx,ty) } + return t +end + +interfaces.implement { name = "immediate", actions = immediate, public = true, protected = true } +interfaces.implement { name = "openout", actions = openout, public = true, protected = true } +interfaces.implement { name = "write", actions = write, public = true, protected = true } +interfaces.implement { name = "closeout", actions = closeout, public = true, protected = true } +interfaces.implement { name = "latelua", actions = latelua, public = true, protected = true } +interfaces.implement { name = "special", actions = scanstring, public = true, protected = true } + +open_command = get(token.create("openout")) +write_command = get(token.create("write")) +close_command = get(token.create("closeout")) -- cgit v1.2.3