summaryrefslogtreecommitdiff
path: root/tex/context/base/mult-cld.lua
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2010-10-18 12:40:11 +0300
committerMarius <mariausol@gmail.com>2010-10-18 12:40:11 +0300
commit8009e0ec2449002df344f784da9fe6846abc774f (patch)
treecd39782dfd7bbf7a3a30f157ba763bfd9425043c /tex/context/base/mult-cld.lua
parent406cef06476f30c68f58cb5074efb10f79de129f (diff)
downloadcontext-8009e0ec2449002df344f784da9fe6846abc774f.tar.gz
beta 2010.10.18 11:11
Diffstat (limited to 'tex/context/base/mult-cld.lua')
-rw-r--r--tex/context/base/mult-cld.lua262
1 files changed, 212 insertions, 50 deletions
diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua
index 382370dea..a9fbab0bc 100644
--- a/tex/context/base/mult-cld.lua
+++ b/tex/context/base/mult-cld.lua
@@ -15,6 +15,7 @@ if not modules then modules = { } end modules ['mult-cld'] = {
--
-- Todo: optional checking against interface
-- Todo: coroutine trickery
+-- Todo: maybe use txtcatcodes
-- tflush needs checking ... sort of weird that it's not a table
@@ -22,7 +23,7 @@ context = context or { }
local context = context
local format, concat = string.format, table.concat
-local next, type, tostring = next, type, tostring
+local next, type, tostring, setmetatable = next, type, tostring, setmetatable
local insert, remove = table.insert, table.remove
local tex = tex
@@ -32,9 +33,16 @@ local textprint = tex.tprint
local texprint = tex.print
local texiowrite = texio.write
local texcount = tex.count
+
+local isnode = node.is_node
+local writenode = node.write
+
local ctxcatcodes = tex.ctxcatcodes
local prtcatcodes = tex.prtcatcodes
+local texcatcodes = tex.texcatcodes
+local txtcatcodes = tex.txtcatcodes
local vrbcatcodes = tex.vrbcatcodes
+local xmlcatcodes = tex.xmlcatcodes
local flush = texsprint
@@ -52,13 +60,17 @@ local function _flush_(n)
local sn = _stack_[n]
if not sn then
report_cld("data with id %s cannot be found on stack",n)
- elseif not sn() and texcount.trialtypesettingmode == 0 then
+ elseif not sn() and texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private!
_stack_[n] = nil
else
-- keep, beware, that way the stack can grow
end
end
+function context.restart()
+ _stack_, _n_ = { }, 0
+end
+
context._stack_ = _stack_
context._store_ = _store_
context._flush_ = _flush_
@@ -68,9 +80,18 @@ context._flush_ = _flush_
local catcodestack = { }
local currentcatcodes = ctxcatcodes
+local catcodes = {
+ ctx = ctxcatcodes, ctxcatcodes = ctxcatcodes, context = ctxcatcodes,
+ prt = prtcatcodes, prtcatcodes = prtcatcodes, protect = prtcatcodes,
+ tex = texcatcodes, texcatcodes = texcatcodes, plain = texcatcodes,
+ txt = txtcatcodes, txtcatcodes = txtcatcodes, text = txtcatcodes,
+ vrb = vrbcatcodes, vrbcatcodes = vrbcatcodes, verbatim = vrbcatcodes,
+ xml = xmlcatcodes, xmlcatcodes = xmlcatcodes,
+}
+
function context.pushcatcodes(c)
insert(catcodestack,currentcatcodes)
- currentcatcodes = c
+ currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes
end
function context.popcatcodes()
@@ -90,14 +111,6 @@ function tex.fprint(...) -- goodie
texsprint(currentcatcodes,format(...))
end
---~ function context.direct(...)
---~ context.flush(...)
---~ end
-
---~ function context.verbose(...)
---~ context.flush(vrbcatcodes,...)
---~ end
-
local trace_context = logs.new("context") -- here
function context.trace(intercept)
@@ -122,25 +135,33 @@ function context.setflush(newflush)
end
trackers.register("context.flush", function(v) if v then context.trace() end end)
-trackers.register("context.intercept", function(v) if v then context.trace(true) end end)
+trackers.register("context.intercept", function(v) if v then context.trace(true) end end) -- will become obsolete
--~ context.trace()
-- beware, we had command as part of the flush and made it "" afterwards so that we could
-- keep it there (...,command,...) but that really confuses the tex machinery
-local function writer(command,first,...) -- 5% faster than just ... and separate flush of command
+local function writer(command,first,...)
if not command then
-- error
- elseif not first then
+ elseif first == nil then
flush(currentcatcodes,command)
else
local t = { first, ... }
- flush(currentcatcodes,command)
+ flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+ local direct = false
for i=1,#t do
local ti = t[i]
local typ = type(ti)
- if ti == nil then
+ if direct then
+ if typ == "string" or typ == "number" then
+ flush(currentcatcodes,ti)
+ else
+ trace_context("error: invalid use of direct in '%s', only strings and numbers can be flushed directly, not '%s'",command,typ)
+ end
+ direct = false
+ elseif ti == nil then
-- nothing
elseif typ == "string" then
if ti == "" then
@@ -188,29 +209,33 @@ local function writer(command,first,...) -- 5% faster than just ... and separate
flush(currentcatcodes,"[",concat(ti,","),"]")
end
elseif typ == "function" then
- flush(currentcatcodes,"{\\mkivflush{",_store_(ti),"}}")
- -- elseif typ == "boolean" then
- -- flush(currentcatcodes,"\n")
- elseif ti == true then
- flush(currentcatcodes,"\n")
- elseif typ == false then
- -- if force == "direct" then
- flush(currentcatcodes,tostring(ti))
- -- end
+ flush(currentcatcodes,"{\\mkivflush{",_store_(ti),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if ti then
+ flush(currentcatcodes,"^^M")
+ else
+ direct = true
+ end
elseif typ == "thread" then
trace_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(ti) then
+ writenode(ti)
else
- trace_context("error: %s gets a weird argument %s",command,tostring(ti))
+ trace_context("error: '%s' gets a weird argument '%s'",command,tostring(ti))
end
end
+ if direct then
+ trace_context("error: direct flushing used in '%s' without following argument",command)
+ end
end
end
--~ experiments.register("context.writer",function()
--~ writer = newwriter
--~ end)
+
local function indexer(t,k)
- local c = "\\" .. k .. " "
+ local c = "\\" .. k -- .. " "
local f = function(...) return writer(c,...) end
t[k] = f
return f
@@ -219,14 +244,38 @@ end
local function caller(t,f,a,...)
if not t then
-- so we don't need to test in the calling (slower but often no issue)
- elseif a then
- flush(currentcatcodes,format(f,a,...))
- elseif type(f) == "function" then
- flush(currentcatcodes,"{\\mkivflush{" .. _store_(f) .. "}}")
- elseif f then
- flush(currentcatcodes,f)
- else
- flush(currentcatcodes,"\n")
+ elseif f ~= nil then
+ local typ = type(f)
+ if typ == "string" then
+ if a then
+ flush(currentcatcodes,format(f,a,...))
+ else
+ flush(currentcatcodes,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,"{\\mkivflush{",_store_(f),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ -- ignored: a ...
+ if f then
+ flush(currentcatcodes,"^^M")
+ else
+ writer("",a,...)
+ -- trace_context("warning: 'context' gets argument 'false' which is currently unsupported")
+ end
+ elseif typ == "thread" then
+ trace_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(f) then
+ writenode(f)
+ else
+ trace_context("error: 'context' gets a weird argument '%s'",tostring(f))
+ end
end
end
@@ -237,24 +286,24 @@ setmetatable(context, { __index = indexer, __call = caller } )
local trace_cld = false
function context.runfile(filename)
- filename = resolvers.findtexfile(filename) or ""
- if filename ~= "" then
- local ok = dofile(filename)
+ local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or ""
+ if foundname ~= "" then
+ local ok = dofile(foundname)
if type(ok) == "function" then
if trace_cld then
- commands.writestatus("cld","begin of file '%s' (function call)",filename)
+ trace_context("begin of file '%s' (function call)",foundname)
end
ok()
if trace_cld then
- commands.writestatus("cld","end of file '%s' (function call)",filename)
+ trace_context("end of file '%s' (function call)",foundname)
end
elseif ok then
- commands.writestatus("cld","file '%s' is processed and returns true",filename)
+ trace_context("file '%s' is processed and returns true",foundname)
else
- commands.writestatus("cld","file '%s' is processed and returns nothing",filename)
+ trace_context("file '%s' is processed and returns nothing",foundname)
end
else
- commands.writestatus("cld","unknown file '%s'",filename)
+ trace_context("unknown file '%s'",filename)
end
end
@@ -278,6 +327,24 @@ end)
function context.enabletrackers (str) trackers.enable (str) end
function context.disabletrackers(str) trackers.disable(str) end
+function context.direct(...)
+ return writer("",...)
+end
+
+function context.char(k)
+ if type(k) == "table" then
+ for i=1,#k do
+ context(format([[\char%s\relax]],k[i]))
+ end
+ elseif k then
+ context(format([[\char%s\relax]],k))
+ end
+end
+
+function context.par()
+ context([[\par]]) -- no need to add {} there
+end
+
-- see demo-cld.cld for an example
-- context.starttext(true)
@@ -304,7 +371,7 @@ function context.disabletrackers(str) trackers.disable(str) end
--~ Not that useful yet. Maybe something like this when the main loop
--~ is a coroutine. It also does not help taking care of nested calls.
---~ Even worse, it interferes with other mechanisms usign context calls.
+--~ Even worse, it interferes with other mechanisms using context calls.
--~
--~ local create, yield, resume = coroutine.create, coroutine.yield, coroutine.resume
--~ local getflush, setflush = context.getflush, context.setflush
@@ -354,12 +421,107 @@ function context.disabletrackers(str) trackers.disable(str) end
-- this might be generalized: register some primitives as: accepting this or that
-- we can also speed this up
-function context.char(k)
- if type(k) == "table" then
- for i=1,#k do
- context(format([[\char%s\relax]],k[i]))
+
+local delayed = { } context.delayed = delayed -- maybe also global
+
+local function indexer(t,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ return context[k](unpack(a))
end
- elseif k then
- context(format([[\char%s\relax]],k))
+ end
+ t[k] = f
+ return f
+end
+
+
+local function caller(t,...)
+ local a = { ... }
+ return function()
+ return context(unpack(a))
+ end
+end
+
+setmetatable(delayed, { __index = indexer, __call = caller } )
+
+--~ context.test("test 1",context.delayed(" test 2a "),"test 3")
+--~ context.test("test 1",context.delayed.test(" test 2b "),"test 3")
+
+-- experimental:
+
+local metafun = { } context.metafun = metafun
+
+local mpdrawing = "\\MPdrawing"
+
+local function caller(t,f,a,...)
+ if not t then
+ -- skip
+ elseif f then
+ local typ = type(f)
+ if typ == "string" then
+ if a then
+ flush(currentcatcodes,mpdrawing,"{",format(f,a,...),"}")
+ else
+ flush(currentcatcodes,mpdrawing,"{",f,"}")
+ end
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,mpdrawing,"{",f,a,...,"}")
+ else
+ flush(currentcatcodes,mpdrawing,"{",f,"}")
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,mpdrawing,"{\\mkivflush{",store_(f),"}}")
+ elseif typ == "boolean" then
+ -- ignored: a ...
+ if f then
+ flush(currentcatcodes,mpdrawing,"{^^M}")
+ else
+ trace_context("warning: 'metafun' gets argument 'false' which is currently unsupported")
+ end
+ else
+ trace_context("error: 'metafun' gets a weird argument '%s'",tostring(f))
+ end
+ end
+end
+
+setmetatable(metafun, { __call = caller } )
+
+function metafun.start()
+ context.resetMPdrawing()
+end
+
+function metafun.stop()
+ context.MPdrawingdonetrue()
+ context.getMPdrawing()
+end
+
+function metafun.color(name)
+ return format([[\MPcolor{%s}]],name)
+end
+
+
+local delayed = { } metafun.delayed = delayed
+
+local function indexer(t,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ return metafun[k](unpack(a))
+ end
+ end
+ t[k] = f
+ return f
+end
+
+
+local function caller(t,...)
+ local a = { ... }
+ return function()
+ return metafun(unpack(a))
end
end
+
+setmetatable(delayed, { __index = indexer, __call = caller } )