summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/mlib-fio.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/mlib-fio.lmt')
-rw-r--r--tex/context/base/mkiv/mlib-fio.lmt191
1 files changed, 191 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/mlib-fio.lmt b/tex/context/base/mkiv/mlib-fio.lmt
new file mode 100644
index 000000000..4290537dd
--- /dev/null
+++ b/tex/context/base/mkiv/mlib-fio.lmt
@@ -0,0 +1,191 @@
+if not modules then modules = { } end modules ['mlib-run'] = {
+ version = 1.001,
+ comment = "companion to mlib-ctx.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+local type = type
+local find = string.find
+local concat = table.concat
+
+local trace_terminal = false trackers.register("metapost.terminal", function(v) trace_terminal = v end)
+
+local report_metapost = logs.reporter("metapost")
+local report_terminal = logs.reporter("metapost","terminal")
+local report_logger = logs.reporter("metapost","log")
+local report_error = logs.reporter("metapost","error")
+
+mplib.realtimelogging = false
+
+local l, nl, dl = { }, 0, false
+local t, nt, dt = { }, 0, false
+local e, ne, de = { }, 0, false
+
+local function logger(target,str)
+ if target == 1 then
+ -- log
+ elseif target == 2 or target == 3 then
+ -- term
+ if str == "\n" then
+ mplib.realtimelogging = true
+ if nl > 0 then
+ report_logger(concat(l,"",1,nl))
+ nl, dl = 0, false
+ elseif not dl then
+ report_logger("")
+ dl = true
+ end
+ else
+ nl = nl + 1
+ l[nl] = str
+ end
+ elseif target == 4 then
+ report_error(str)
+ end
+end
+
+local finders = { }
+mplib.finders = finders -- also used in meta-lua.lua
+
+local new_instance = mplib.new
+
+local function validftype(ftype)
+ if ftype == "mp" then
+ return "mp"
+ else
+ return nil
+ end
+end
+
+finders.file = function(specification,name,mode,ftype)
+ return resolvers.findfile(name,validftype(ftype))
+end
+
+local findtexfile = resolvers.findtexfile
+local opentexfile = resolvers.opentexfile
+local splitlines = string.splitlines
+
+local function writetoterminal(terminaldata,maxterm,d)
+ local t = type(d)
+ local n = 0
+ if t == "string" then
+ d = splitlines(d)
+ n = #d
+ for i=1,#d do
+ maxterm = maxterm + 1
+ terminaldata[maxterm] = d[i]
+ end
+ elseif t == "table" then
+ for i=1,#d do
+ local l = d[i]
+ if find(l,"[\n\r]") then
+ local s = splitlines(l)
+ local m = #s
+ for i=1,m do
+ maxterm = maxterm + 1
+ terminaldata[maxterm] = s[i]
+ end
+ n = n + m
+ else
+ maxterm = maxterm + 1
+ terminaldata[maxterm] = d[i]
+ n = 1
+ end
+ end
+ end
+ if trace_terminal then
+ report_metapost("writing %i lines, in cache %s",n,maxterm)
+ end
+ return maxterm
+end
+
+local function readfromterminal(terminaldata,maxterm,nowterm)
+ if nowterm >= maxterm then
+ terminaldata[nowterm] = false
+ maxterm = 0
+ nowterm = 0
+ if trace_terminal then
+ report_metapost("resetting, maxcache %i",#terminaldata)
+ end
+ return maxterm, nowterm, nil
+ else
+ if nowterm > 0 then
+ terminaldata[nowterm] = false
+ end
+ nowterm = nowterm + 1
+ local s = terminaldata[nowterm]
+ if trace_terminal then
+ report_metapost("reading line %i: %s",nowterm,s)
+ end
+ return maxterm, nowterm, s
+ end
+end
+
+local function fileopener()
+
+ -- these can go into the table itself
+
+ local terminaldata = { }
+ local maxterm = 0
+ local nowterm = 0
+
+ local terminal = {
+ name = "terminal",
+ close = function()
+ -- terminal = { }
+ -- maxterm = 0
+ -- nowterm = 0
+ end,
+ reader = function()
+ local line
+ maxterm, nowterm, line = readfromterminal(terminaldata,maxterm,nowterm)
+ return line
+ end,
+ writer = function(d)
+ maxterm = writetoterminal(terminaldata,maxterm,d)
+ end,
+ }
+
+ return function(name,mode,kind)
+ if name == "terminal" then
+ -- report_metapost("opening terminal")
+ return terminal
+ elseif mode == "w" then
+ local f = io.open(name,"wb")
+ if f then
+ -- report_metapost("opening file %a for writing",full)
+ return {
+ name = full,
+ writer = function(s) return f:write(s) end, -- io.write(f,s)
+ close = function() f:close() end,
+ }
+ end
+ else
+ local full = findtexfile(name,validftype(ftype))
+ if full then
+ -- report_metapost("opening file %a for reading",full)
+ return opentexfile(full)
+ end
+ end
+ end
+
+end
+
+local function finder(name,mode,kind)
+ return findtexfile(name,kind)
+end
+
+function mplib.new(specification)
+ local openfile = fileopener()
+ specification.find_file = finder
+ specification.run_logger = logger
+ specification.open_file = openfile
+ specification.interaction = "silent"
+ specification.halt_on_error = true
+ local instance = new_instance(specification)
+ return instance, openfile("terminal")
+end
+
+mplib.finder = finder