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