summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/cldf-ini.lua
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-07-22 22:33:21 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-07-22 22:33:21 +0200
commitdd7c4b1a54bfc5e358eb9f766c0b865fc47cbe46 (patch)
tree2e8888da6188eb742a98c3c05a26e2b75b198e62 /tex/context/base/mkiv/cldf-ini.lua
parent50928735daee408de73737b055b2535d96424824 (diff)
downloadcontext-dd7c4b1a54bfc5e358eb9f766c0b865fc47cbe46.tar.gz
2016-07-22 20:13:00
Diffstat (limited to 'tex/context/base/mkiv/cldf-ini.lua')
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua900
1 files changed, 425 insertions, 475 deletions
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index f868975e5..a77f25f41 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -15,6 +15,8 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- 0.651 local foo = getcount("ctxcatcodes")
-- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes")
+-- maybe  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔)
+
-- This started as an experiment: generating context code at the lua end. After all
-- it is surprisingly simple to implement due to metatables. I was wondering if
-- there was a more natural way to deal with commands at the lua end. Of course it's
@@ -25,7 +27,6 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- currently no coroutine trickery
-- we could always use prtcatcodes (context.a_b_c) but then we loose protection
-- tflush needs checking ... sort of weird that it's not a table
--- __flushlines is an experiment and rather ugly so it will go away
--
-- tex.print == line with endlinechar appended
@@ -41,6 +42,16 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- context(string.formatters["%!tex!"]("${}"))
-- context("%!tex!","${}")
+-- We try not to polute the context namespace too much. For that reason the commands are
+-- registered in the context.core namespace. You can call all context commands using
+-- context.foo etc. and pipe to context with context("foo"). Defining a local command
+-- foo being context.foo is okay, as is context.core.foo. We will have some definitions
+-- that are plugged into the core namespace (mostly for speedup) but otherwise specialized
+-- writers are in the context namespace only. In your documents you can best use the
+-- context.foo(...) and context(...) variant but in some core modules we use the faster
+-- ones in critical places (no one will notice of course). The standard syntax highlighter
+-- that I use knows how to visualize ctx related code.
+
local format, stripstring = string.format, string.strip
local next, type, tostring, tonumber, setmetatable, unpack, select, rawset = next, type, tostring, tonumber, setmetatable, unpack, select, rawset
local insert, remove, concat = table.insert, table.remove, table.concat
@@ -274,14 +285,6 @@ local registerfunction, unregisterfunction, reservefunction, knownfunctions, cal
return slot
end
- -- do
- -- commands.test = function(str) report_cld("test function: %s", str) end
- -- if initex then
- -- registerfunction("commands.test") -- number 1
- -- end
- -- luafunctions[1]("okay")
- -- end
-
unregisterfunction = function(slot)
if luafunctions[slot] then
noffreed = noffreed + 1
@@ -430,12 +433,15 @@ local registerfunction, unregisterfunction, reservefunction, knownfunctions, cal
--
-- end
-context.registerfunction = registerfunction
-context.unregisterfunction = unregisterfunction
-context.reservefunction = reservefunction
-context.knownfunctions = knownfunctions
-context.callfunctiononce = callfunctiononce _cldo_ = callfunctiononce
-context.storenode = storenode -- private helper
+context.functions = {
+ register = registerfunction,
+ unregister = unregisterfunction,
+ reserve = reservefunction,
+ known = knownfunctions,
+ callonce = callfunctiononce,
+}
+
+context.storenode = storenode -- private helper
function commands.ctxfunction(code,namespace)
context(registerfunction(code,namespace))
@@ -670,10 +676,6 @@ local flushlines = context.newtexthandler {
simpleline = n_simpleline,
}
-context.__flushlines = flushlines -- maybe context.helpers.flushtexlines
-context.__flush = flush
-context.__flushdirect = flushdirect
-
-- The next variant is only used in rare cases (buffer to mp):
local printlines_ctx = (
@@ -698,302 +700,311 @@ end
local containseol = patterns.containseol
-local writer = nil
-local prtwriter = nil
-
--- if luafunctions then
-
- writer = function (parent,command,...) -- already optimized before call
- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
- local direct = false
- -- local t = { ... }
- -- for i=1,#t do
- -- local ti = t[i]
- for i=1,select("#",...) do
- local ti = (select(i,...))
- if direct then
- local typ = type(ti)
- if typ == "string" or typ == "number" then
- flush(currentcatcodes,ti)
- else -- node.write
- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
- end
- direct = false
- elseif ti == nil then
- -- nothing
- elseif ti == "" then
- flush(currentcatcodes,"{}")
- else
- local typ = type(ti)
- if typ == "string" then
- -- is processlines seen ?
- if processlines and lpegmatch(containseol,ti) then
- flush(currentcatcodes,"{")
- local flushlines = parent.__flushlines or flushlines
- flushlines(ti)
- flush(currentcatcodes,"}")
- elseif currentcatcodes == contentcatcodes then
- flush(currentcatcodes,"{",ti,"}")
- else
- flush(currentcatcodes,"{")
- flush(contentcatcodes,ti)
- flush(currentcatcodes,"}")
- end
- elseif typ == "number" then
- -- numbers never have funny catcodes
+local function writer(parent,command,...) -- already optimized before call
+ flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+ local direct = false
+ -- local t = { ... }
+ -- for i=1,#t do
+ -- local ti = t[i]
+ for i=1,select("#",...) do
+ local ti = (select(i,...))
+ if direct then
+ local typ = type(ti)
+ if typ == "string" or typ == "number" then
+ flush(currentcatcodes,ti)
+ else -- node.write
+ report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
+ end
+ direct = false
+ elseif ti == nil then
+ -- nothing
+ elseif ti == "" then
+ flush(currentcatcodes,"{}")
+ else
+ local typ = type(ti)
+ if typ == "string" then
+ -- is processlines seen ?
+ if processlines and lpegmatch(containseol,ti) then
+ flush(currentcatcodes,"{")
+ flushlines(ti)
+ flush(currentcatcodes,"}")
+ elseif currentcatcodes == contentcatcodes then
flush(currentcatcodes,"{",ti,"}")
- elseif typ == "table" then
- local tn = #ti
- if tn == 0 then
- local done = false
- for k, v in next, ti do
- if done then
- if v == "" then
- flush(currentcatcodes,",",k,'=')
- else
- flush(currentcatcodes,",",k,"={",v,"}")
- end
+ else
+ flush(currentcatcodes,"{")
+ flush(contentcatcodes,ti)
+ flush(currentcatcodes,"}")
+ end
+ elseif typ == "number" then
+ -- numbers never have funny catcodes
+ flush(currentcatcodes,"{",ti,"}")
+ elseif typ == "table" then
+ local tn = #ti
+ if tn == 0 then
+ local done = false
+ for k, v in next, ti do
+ if done then
+ if v == "" then
+ flush(currentcatcodes,",",k,'=')
else
- if v == "" then
- flush(currentcatcodes,"[",k,"=")
- else
- flush(currentcatcodes,"[",k,"={",v,"}")
- end
- done = true
+ flush(currentcatcodes,",",k,"={",v,"}")
end
- end
- if done then
- flush(currentcatcodes,"]")
else
- flush(currentcatcodes,"[]")
+ if v == "" then
+ flush(currentcatcodes,"[",k,"=")
+ else
+ flush(currentcatcodes,"[",k,"={",v,"}")
+ end
+ done = true
end
- elseif tn == 1 then -- some 20% faster than the next loop
- local tj = ti[1]
+ end
+ if done then
+ flush(currentcatcodes,"]")
+ else
+ flush(currentcatcodes,"[]")
+ end
+ elseif tn == 1 then -- some 20% faster than the next loop
+ local tj = ti[1]
+ if type(tj) == "function" then
+ flush(currentcatcodes,"[\\cldl",storefunction(tj),"]")
+ -- flush(currentcatcodes,"[",storefunction(tj),"]")
+ else
+ flush(currentcatcodes,"[",tj,"]")
+ end
+ else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
+ flush(currentcatcodes,"[")
+ for j=1,tn do
+ local tj = ti[j]
if type(tj) == "function" then
- flush(currentcatcodes,"[\\cldl",storefunction(tj),"]")
- -- flush(currentcatcodes,"[",storefunction(tj),"]")
+ if j == tn then
+ flush(currentcatcodes,"\\cldl",storefunction(tj),"]")
+ -- flush(currentcatcodes,"",storefunction(tj),"]")
+ else
+ flush(currentcatcodes,"\\cldl",storefunction(tj),",")
+ -- flush(currentcatcodes,"",storefunction(tj),",")
+ end
else
- flush(currentcatcodes,"[",tj,"]")
- end
- else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
- flush(currentcatcodes,"[")
- for j=1,tn do
- local tj = ti[j]
- if type(tj) == "function" then
- if j == tn then
- flush(currentcatcodes,"\\cldl",storefunction(tj),"]")
- -- flush(currentcatcodes,"",storefunction(tj),"]")
- else
- flush(currentcatcodes,"\\cldl",storefunction(tj),",")
- -- flush(currentcatcodes,"",storefunction(tj),",")
- end
+ if j == tn then
+ flush(currentcatcodes,tj,"]")
else
- if j == tn then
- flush(currentcatcodes,tj,"]")
- else
- flush(currentcatcodes,tj,",")
- end
+ flush(currentcatcodes,tj,",")
end
end
end
- elseif typ == "function" then
- flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
- -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
- elseif typ == "boolean" then
- if ti then
- flushdirect(currentcatcodes,"\r")
- else
- direct = true
- end
- elseif typ == "thread" then
- report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(ti) then -- slow
- flush(currentcatcodes,"{\\cldl",storenode(ti),"}")
- -- flush(currentcatcodes,"{",storenode(ti),"}")
+ end
+ elseif typ == "function" then
+ flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
+ -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if ti then
+ flushdirect(currentcatcodes,"\r")
else
- report_context("error: %a gets a weird argument %a",command,ti)
+ direct = true
end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(ti) then -- slow
+ flush(currentcatcodes,"{\\cldl",storenode(ti),"}")
+ -- flush(currentcatcodes,"{",storenode(ti),"}")
+ else
+ report_context("error: %a gets a weird argument %a",command,ti)
end
end
end
+end
- -- if performance really matters we can consider a compiler but it will never
- -- pay off
-
- prtwriter = function (command,...) -- already optimized before call
- flush(prtcatcodes,command)
- for i=1,select("#",...) do
- local ti = (select(i,...))
- if ti == nil then
- -- nothing
- elseif ti == "" then
- flush(prtcatcodes,"{}")
+-- if performance really matters we can consider a compiler but it will never
+-- pay off
+
+local function prtwriter(command,...) -- already optimized before call
+ flush(prtcatcodes,command)
+ for i=1,select("#",...) do
+ local ti = (select(i,...))
+ if ti == nil then
+ -- nothing
+ elseif ti == "" then
+ flush(prtcatcodes,"{}")
+ else
+ local tp = type(ti)
+ if tp == "string" or tp == "number"then
+ flush(prtcatcodes,"{",ti,"}")
+ elseif tp == "function" then
+ flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}")
+ -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
+ elseif isnode(ti) then
+ flush(prtcatcodes,"{\\cldl",storenode(ti),"}")
+ -- flush(currentcatcodes,"{",storenode(ti),"}")
else
- local tp = type(ti)
- if tp == "string" or tp == "number"then
- flush(prtcatcodes,"{",ti,"}")
- elseif tp == "function" then
- flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}")
- -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
- elseif isnode(ti) then
- flush(prtcatcodes,"{\\cldl",storenode(ti),"}")
- -- flush(currentcatcodes,"{",storenode(ti),"}")
- else
- report_context("fatal error: prt %a gets a weird argument %a",command,ti)
- end
+ report_context("fatal error: prt %a gets a weird argument %a",command,ti)
end
end
end
+end
--- else
+-- Originally we used this:
--
--- writer = function (parent,command,first,...) -- already optimized before call
--- local t = { first, ... }
--- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
--- local direct = false
--- for i=1,#t do
--- local ti = t[i]
--- local typ = type(ti)
--- if direct then
--- if typ == "string" or typ == "number" then
--- flush(currentcatcodes,ti)
--- else -- node.write
--- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
--- end
--- direct = false
--- elseif ti == nil then
--- -- nothing
--- elseif ti == "" then
--- flush(currentcatcodes,"{}")
--- elseif typ == "string" then
--- -- is processelines seen ?
--- if processlines and lpegmatch(containseol,ti) then
--- flush(currentcatcodes,"{")
--- local flushlines = parent.__flushlines or flushlines
--- flushlines(ti)
--- flush(currentcatcodes,"}")
--- elseif currentcatcodes == contentcatcodes then
--- flush(currentcatcodes,"{",ti,"}")
--- else
--- flush(currentcatcodes,"{")
--- flush(contentcatcodes,ti)
--- flush(currentcatcodes,"}")
--- end
--- elseif typ == "number" then
--- -- numbers never have funny catcodes
--- flush(currentcatcodes,"{",ti,"}")
--- elseif typ == "table" then
--- local tn = #ti
--- if tn == 0 then
--- local done = false
--- for k, v in next, ti do
--- if done then
--- if v == "" then
--- flush(currentcatcodes,",",k,'=')
--- else
--- flush(currentcatcodes,",",k,"={",v,"}")
--- end
--- else
--- if v == "" then
--- flush(currentcatcodes,"[",k,"=")
--- else
--- flush(currentcatcodes,"[",k,"={",v,"}")
--- end
--- done = true
--- end
--- end
--- if done then
--- flush(currentcatcodes,"]")
--- else
--- flush(currentcatcodes,"[]")
--- end
--- elseif tn == 1 then -- some 20% faster than the next loop
--- local tj = ti[1]
--- if type(tj) == "function" then
--- flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]")
--- else
--- flush(currentcatcodes,"[",tj,"]")
--- end
--- else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
--- for j=1,tn do
--- local tj = ti[j]
--- if type(tj) == "function" then
--- ti[j] = "\\cldf{" .. storefunction(tj) .. "}"
--- end
--- end
--- flush(currentcatcodes,"[",concat(ti,","),"]")
--- end
--- elseif typ == "function" then
--- flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes
--- elseif typ == "boolean" then
--- if ti then
--- flushdirect(currentcatcodes,"\r")
--- else
--- direct = true
--- end
--- elseif typ == "thread" then
--- report_context("coroutines not supported as we cannot yield across boundaries")
--- elseif isnode(ti) then -- slow
--- flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}")
+-- writer = function (parent,command,first,...) -- already optimized before call
+-- local t = { first, ... }
+-- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+-- local direct = false
+-- for i=1,#t do
+-- local ti = t[i]
+-- local typ = type(ti)
+-- if direct then
+-- if typ == "string" or typ == "number" then
+-- flush(currentcatcodes,ti)
+-- else -- node.write
+-- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
+-- end
+-- direct = false
+-- elseif ti == nil then
+-- -- nothing
+-- elseif ti == "" then
+-- flush(currentcatcodes,"{}")
+-- elseif typ == "string" then
+-- -- is processelines seen ?
+-- if processlines and lpegmatch(containseol,ti) then
+-- flush(currentcatcodes,"{")
+-- flushlines(ti)
+-- flush(currentcatcodes,"}")
+-- elseif currentcatcodes == contentcatcodes then
+-- flush(currentcatcodes,"{",ti,"}")
+-- else
+-- flush(currentcatcodes,"{")
+-- flush(contentcatcodes,ti)
+-- flush(currentcatcodes,"}")
+-- end
+-- elseif typ == "number" then
+-- -- numbers never have funny catcodes
+-- flush(currentcatcodes,"{",ti,"}")
+-- elseif typ == "table" then
+-- local tn = #ti
+-- if tn == 0 then
+-- local done = false
+-- for k, v in next, ti do
+-- if done then
+-- if v == "" then
+-- flush(currentcatcodes,",",k,'=')
+-- else
+-- flush(currentcatcodes,",",k,"={",v,"}")
+-- end
+-- else
+-- if v == "" then
+-- flush(currentcatcodes,"[",k,"=")
+-- else
+-- flush(currentcatcodes,"[",k,"={",v,"}")
+-- end
+-- done = true
+-- end
+-- end
+-- if done then
+-- flush(currentcatcodes,"]")
+-- else
+-- flush(currentcatcodes,"[]")
+-- end
+-- elseif tn == 1 then -- some 20% faster than the next loop
+-- local tj = ti[1]
+-- if type(tj) == "function" then
+-- flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]")
+-- else
+-- flush(currentcatcodes,"[",tj,"]")
+-- end
+-- else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
+-- for j=1,tn do
+-- local tj = ti[j]
+-- if type(tj) == "function" then
+-- ti[j] = "\\cldf{" .. storefunction(tj) .. "}"
+-- end
+-- end
+-- flush(currentcatcodes,"[",concat(ti,","),"]")
+-- end
+-- elseif typ == "function" then
+-- flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes
+-- elseif typ == "boolean" then
+-- if ti then
+-- flushdirect(currentcatcodes,"\r")
+-- else
+-- direct = true
+-- end
+-- elseif typ == "thread" then
+-- report_context("coroutines not supported as we cannot yield across boundaries")
+-- elseif isnode(ti) then -- slow
+-- flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}")
+-- else
+-- report_context("error: %a gets a weird argument %a",command,ti)
+-- end
+-- end
+-- end
+
+local generics = { } context.generics = generics
+
+-- local indexer = function(parent,k)
+-- if type(k) == "string" then
+-- local c = "\\" .. tostring(generics[k] or k)
+-- local f = function(first,...)
+-- if first == nil then
+-- flush(currentcatcodes,c)
-- else
--- report_context("error: %a gets a weird argument %a",command,ti)
+-- return writer(parent,c,first,...)
-- end
-- end
+-- parent[k] = f
+-- return f
+-- else
+-- return context -- catch
-- end
---
-- end
-local generics = { } context.generics = generics
-local indexer = nil
-local prtindexer = nil
-
--- if environment.initex then
-
- indexer = function(parent,k)
- if type(k) == "string" then
- local c = "\\" .. tostring(generics[k] or k)
- local f = function(first,...)
- if first == nil then
- flush(currentcatcodes,c)
- else
- return writer(parent,c,first,...)
- end
- end
- parent[k] = f
- return f
+local core = table.setmetatableindex(function(parent,k)
+ local c = "\\" .. tostring(generics[k] or k)
+ local f = function(first,...)
+ if first == nil then
+ flush(currentcatcodes,c)
else
- return context -- catch
+ return writer(context,c,first,...)
end
end
+ parent[k] = f
+ return f
+end)
+
+local indexer = function(parent,k)
+ if type(k) == "string" then
+ return core[k]
+ else
+ return context -- catch
+ end
+end
+
+context.core = core
--- else
+-- can only be done in non-ini mode so we'd have a bad mix and tracing
+-- is bad too, so we just keep it as commented
--
--- local create = token.create
--- local twrite = token.write
+-- local create = token.create
+-- local twrite = token.write
--
--- indexer = function(parent,k)
--- if type(k) == "string" then
--- local s = tostring(generics[k] or k)
--- local t = create(s)
--- if t.cmdname == "undefined_cs" then
--- report_cld("macro \\%s is not yet defined",s)
--- token.set_macro(s,"")
--- t = create(s)
--- end
--- local i = t.id
--- local f = function(first,...)
--- twrite(t.tok) --= we need to keep t uncollected
--- if first ~= nil then
--- return writer(parent,first,...)
--- end
+-- indexer = function(parent,k)
+-- if type(k) == "string" then
+-- local s = tostring(generics[k] or k)
+-- local t = create(s)
+-- if t.cmdname == "undefined_cs" then
+-- report_cld("macro \\%s is not yet defined",s)
+-- token.set_macro(s,"")
+-- t = create(s)
+-- end
+-- local i = t.id
+-- local f = function(first,...)
+-- twrite(t.tok) --= we need to keep t uncollected
+-- if first ~= nil then
+-- return writer(parent,first,...)
-- end
--- parent[k] = f
--- return f
--- else
--- return context -- catch
-- end
+-- parent[k] = f
+-- return f
+-- else
+-- return context -- catch
-- end
---
-- end
-- Potential optimization: after the first call we know if there will be an
@@ -1029,18 +1040,19 @@ local prtindexer = nil
-- only for internal usage:
+local prtindexer = nil
+
do
- function context.constructcsonly(k) -- not much faster than the next but more mem efficient
- local c = "\\" .. tostring(generics[k] or k)
- local v = function()
- flush(prtcatcodes,c)
- end
- rawset(context,k,v) -- context namespace
- return v
- end
+ -- the only variant is not much faster than the full but it's more
+ -- memory efficient
+
+ local protected = { }
+ local protectedcs = { }
+ context.protected = protected
+ context.protectedcs = protectedcs
- function context.constructcs(k)
+ local function fullindexer(t,k)
local c = "\\" .. tostring(generics[k] or k)
local v = function(first,...)
if first == nil then
@@ -1049,160 +1061,146 @@ do
return prtwriter(c,first,...)
end
end
- rawset(context,k,v) -- context namespace
+ rawset(t,k,v) -- protected namespace
return v
end
- local function prtindexer(t,k)
+ local function onlyindexer(t,k)
local c = "\\" .. tostring(generics[k] or k)
- local v = function(first,...)
- if first == nil then
- flush(prtcatcodes,c)
- else
- return prtwriter(c,first,...)
- end
+ local v = function()
+ flush(prtcatcodes,c)
end
- rawset(t,k,v) -- protected namespace
+ rawset(protected,k,v)
+ rawset(t,k,v)
return v
end
- context.protected = { } -- we could check for _ in the context namespace
-
- setmetatable(context.protected, { __index = prtindexer, __call = prtwriter } )
+ setmetatable(protected, { __index = fullindexer, __call = prtwriter } )
+ setmetatable(protectedcs, { __index = onlyindexer, __call = prtwriter } )
end
-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet)
-local caller
-
--- if luafunctions then
-
- caller = function(parent,f,a,...)
- if not parent then
- -- so we don't need to test in the calling (slower but often no issue)
- elseif f ~= nil then
- local typ = type(f)
- if typ == "string" then
- if f == "" then
- -- new, can save a bit sometimes
- -- if trace_context then
- -- report_context("empty argument to context()")
- -- end
- elseif a then
- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
- -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
- elseif processlines and lpegmatch(containseol,f) then
- local flushlines = parent.__flushlines or flushlines
- flushlines(f)
+local caller = function(parent,f,a,...)
+ if not parent then
+ -- so we don't need to test in the calling (slower but often no issue)
+ elseif f ~= nil then
+ local typ = type(f)
+ if typ == "string" then
+ if f == "" then
+ -- new, can save a bit sometimes
+ -- if trace_context then
+ -- report_context("empty argument to context()")
+ -- end
+ elseif a then
+ flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
+ -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
+ elseif processlines and lpegmatch(containseol,f) then
+ flushlines(f)
+ else
+ flush(contentcatcodes,f)
+ end
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,f,a,...)
+ else
+ flush(currentcatcodes,f)
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes
+ -- flush(currentcatcodes,"{",storefunction(f),"}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if f then
+ if a ~= nil then
+ flushlines(a)
else
- flush(contentcatcodes,f)
+ flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
end
- elseif typ == "number" then
- if a then
- flush(currentcatcodes,f,a,...)
+ else
+ if a ~= nil then
+ -- no command, same as context(a,...)
+ writer(parent,"",a,...)
else
- flush(currentcatcodes,f)
+ -- ignored
end
- elseif typ == "function" then
- -- ignored: a ...
- flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes
- -- flush(currentcatcodes,"{",storefunction(f),"}") -- todo: ctx|prt|texcatcodes
- elseif typ == "boolean" then
- if f then
- if a ~= nil then
- local flushlines = parent.__flushlines or flushlines
- flushlines(a)
- else
- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
- end
- else
- if a ~= nil then
- -- no command, same as context(a,...)
- writer(parent,"",a,...)
- else
- -- ignored
- end
- end
- elseif typ == "thread" then
- report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(f) then -- slow
- -- writenode(f)
- flush(currentcatcodes,"\\cldl",storenode(f)," ")
- -- flush(currentcatcodes,"",storenode(f)," ")
- else
- report_context("error: %a gets a weird argument %a","context",f)
end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(f) then -- slow
+ -- writenode(f)
+ flush(currentcatcodes,"\\cldl",storenode(f)," ")
+ -- flush(currentcatcodes,"",storenode(f)," ")
+ else
+ report_context("error: %a gets a weird argument %a","context",f)
end
end
+end
- function context.flushnode(n)
- flush(currentcatcodes,"\\cldl",storenode(n)," ")
- -- flush(currentcatcodes,"",storenode(n)," ")
- end
+function context.flushnode(n)
+ flush(currentcatcodes,"\\cldl",storenode(n)," ")
+ -- flush(currentcatcodes,"",storenode(n)," ")
+end
--- else
+-- old code, from the early days:
--
--- caller = function(parent,f,a,...)
--- if not parent then
--- -- so we don't need to test in the calling (slower but often no issue)
--- elseif f ~= nil then
--- local typ = type(f)
--- if typ == "string" then
--- if f == "" then
--- -- new, can save a bit sometimes
--- -- if trace_context then
--- -- report_context("empty argument to context()")
--- -- end
--- elseif a then
--- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
--- -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
--- elseif processlines and lpegmatch(containseol,f) then
--- local flushlines = parent.__flushlines or flushlines
--- flushlines(f)
--- else
--- flush(contentcatcodes,f)
--- end
--- elseif typ == "number" then
--- if a then
--- flush(currentcatcodes,f,a,...)
+-- caller = function(parent,f,a,...)
+-- if not parent then
+-- -- so we don't need to test in the calling (slower but often no issue)
+-- elseif f ~= nil then
+-- local typ = type(f)
+-- if typ == "string" then
+-- if f == "" then
+-- -- new, can save a bit sometimes
+-- -- if trace_context then
+-- -- report_context("empty argument to context()")
+-- -- end
+-- elseif a then
+-- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
+-- -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
+-- elseif processlines and lpegmatch(containseol,f) then
+-- flushlines(f)
+-- else
+-- flush(contentcatcodes,f)
+-- end
+-- elseif typ == "number" then
+-- if a then
+-- flush(currentcatcodes,f,a,...)
+-- else
+-- flush(currentcatcodes,f)
+-- end
+-- elseif typ == "function" then
+-- -- ignored: a ...
+-- flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes
+-- elseif typ == "boolean" then
+-- if f then
+-- if a ~= nil then
+-- flushlines(a)
-- else
--- flush(currentcatcodes,f)
+-- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
-- end
--- elseif typ == "function" then
--- -- ignored: a ...
--- flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes
--- elseif typ == "boolean" then
--- if f then
--- if a ~= nil then
--- local flushlines = parent.__flushlines or flushlines
--- flushlines(a)
--- else
--- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
--- end
+-- else
+-- if a ~= nil then
+-- -- no command, same as context(a,...)
+-- writer(parent,"",a,...)
-- else
--- if a ~= nil then
--- -- no command, same as context(a,...)
--- writer(parent,"",a,...)
--- else
--- -- ignored
--- end
+-- -- ignored
-- end
--- elseif typ == "thread" then
--- report_context("coroutines not supported as we cannot yield across boundaries")
--- elseif isnode(f) then -- slow
--- -- writenode(f)
--- flush(currentcatcodes,"\\cldn{",storenode(f),"}")
--- else
--- report_context("error: %a gets a weird argument %a","context",f)
-- end
+-- elseif typ == "thread" then
+-- report_context("coroutines not supported as we cannot yield across boundaries")
+-- elseif isnode(f) then -- slow
+-- -- writenode(f)
+-- flush(currentcatcodes,"\\cldn{",storenode(f),"}")
+-- else
+-- report_context("error: %a gets a weird argument %a","context",f)
-- end
-- end
+-- end
--
--- function context.flushnode(n)
--- flush(currentcatcodes,"\\cldn{",storenode(n),"}")
--- end
---
+-- function context.flushnode(n)
+-- flush(currentcatcodes,"\\cldn{",storenode(n),"}")
-- end
local defaultcaller = caller
@@ -1211,6 +1209,8 @@ setmetatable(context, { __index = indexer, __call = caller } )
-- now we tweak unprotect and protect
+-- context.call = caller -- somehow fails
+
function context.unprotect()
-- at the lua end
insert(catcodestack,currentcatcodes)
@@ -1376,14 +1376,9 @@ local function pushlogger(trace)
trace = trace or report_context
insert(trace_stack,currenttrace)
currenttrace = trace
- --
- flush = tracedflush
- flushdirect = tracedflushdirect
- writer = tracedwriter
- --
- context.__flush = flush
- context.__flushdirect = flushdirect
- --
+ flush = tracedflush
+ flushdirect = tracedflushdirect
+ writer = tracedwriter
return flush, writer, flushdirect
end
@@ -1393,9 +1388,6 @@ local function poplogger()
flush = normalflush
flushdirect = normalflushdirect
writer = normalwriter
- --
- context.__flush = flush
- context.__flushdirect = flushdirect
end
return flush, writer, flushdirect
end
@@ -1499,13 +1491,9 @@ do
if level == 0 then
collected = { }
nofcollected = 0
- --
flush = collect
flushdirect = collectdirect
permitted = tracingpermitted
- --
- context.__flush = flush
- context.__flushdirect = flushdirect
end
level = level + 1
end
@@ -1516,15 +1504,10 @@ do
flush = normalflush
flushdirect = normalflushdirect
tracingpermitted = permitted
- --
- context.__flush = flush
- context.__flushdirect = flushdirect
- --
viafile(concat(collected,sentinel))
- --
- collected = nil
- nofcollected = 0
- level = 0
+ collected = nil
+ nofcollected = 0
+ level = 0
end
end
@@ -1574,7 +1557,8 @@ local function indexer(parent,k)
local f = function(...)
local a = { ... }
return function()
- return context[k](unpack(a))
+ -- return context[k](unpack(a))
+ return core[k](unpack(a))
end
end
parent[k] = f
@@ -1584,48 +1568,11 @@ end
local function caller(parent,...) -- todo: nodes
local a = { ... }
return function()
- return context(unpack(a))
+ -- return context(unpack(a))
+ return defaultcaller(context,unpack(a))
end
end
--- local function indexer(parent,k)
--- local f = function(a,...)
--- if not a then
--- return function()
--- return context[k]()
--- end
--- elseif select("#",...) == 0 then
--- return function()
--- return context[k](a)
--- end
--- elseif a then
--- local t = { ... }
--- return function()
--- return context[k](a,unpack(t))
--- end
--- end
--- end
--- parent[k] = f
--- return f
--- end
---
--- local function caller(parent,a,...) -- todo: nodes
--- if not a then
--- return function()
--- return context()
--- end
--- elseif select("#",...) == 0 then
--- return function()
--- return context(a)
--- end
--- elseif a then
--- local t = { ... }
--- return function()
--- return context(a,unpack(t))
--- end
--- end
--- end
-
setmetatable(delayed, { __index = indexer, __call = caller } )
-- context.nested (todo: lines)
@@ -1639,7 +1586,8 @@ local function indexer(parent,k) -- not ok when traced
n = n + 1
t[n] = s and concat{f,s,...} or f -- optimized for #args == 1
end
- context[k](...)
+ -- context[k](...)
+ core[k](...)
flush = savedflush
return concat(t)
end
@@ -1653,7 +1601,8 @@ local function caller(parent,...)
n = n + 1
t[n] = s and concat{f,s,...} or f -- optimized for #args == 1
end
- context(...)
+ -- context(...)
+ defaultcaller(context,...)
flush = savedflush
return concat(t)
end
@@ -1666,7 +1615,8 @@ function context.newindexer(catcodes)
local handler = { }
local function indexer(parent,k)
- local command = context[k]
+ -- local command = context[k]
+ local command = core[k]
local f = function(...)
local savedcatcodes = contentcatcodes
contentcatcodes = catcodes