diff options
author | Karl Berry <karl@freefriends.org> | 2015-04-18 22:52:45 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-04-18 22:52:45 +0000 |
commit | 16aa5a7c87f18a2483d0d61795899f886781b51c (patch) | |
tree | 1d72f00b2a4185425393598402fe055c61d1de58 /Master/texmf-dist/tex/context/base/mlib-run.lua | |
parent | e68dc4d5506d46bf72823234f902bc76d1f70352 (diff) |
context, from www.pragma-ade.com/context/beta/cont-tmf.zip (18apr15)
git-svn-id: svn://tug.org/texlive/trunk@36923 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mlib-run.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mlib-run.lua | 399 |
1 files changed, 156 insertions, 243 deletions
diff --git a/Master/texmf-dist/tex/context/base/mlib-run.lua b/Master/texmf-dist/tex/context/base/mlib-run.lua index 2a34f44d5c8..121c32ae95a 100644 --- a/Master/texmf-dist/tex/context/base/mlib-run.lua +++ b/Master/texmf-dist/tex/context/base/mlib-run.lua @@ -44,12 +44,12 @@ local texerrormessage = logs.texerrormessage local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming +local formatters = string.formatters + local mplib = mplib metapost = metapost or { } local metapost = metapost -local mplibone = tonumber(mplib.version()) <= 1.50 - metapost.showlog = false metapost.lastlog = "" metapost.collapse = true -- currently mplib cannot deal with begingroup/endgroup mismatch in stepwise processing @@ -84,77 +84,74 @@ local mpbasepath = lpeg.instringchecker(P("/metapost/") * (P("context") + P("bas -- mplib has no real io interface so we have a different mechanism than -- tex (as soon as we have more control, we will use the normal code) - -local finders = { } -mplib.finders = finders - +-- -- for some reason mp sometimes calls this function twice which is inefficient -- but we cannot catch this -local function preprocessed(name) - if not mpbasepath(name) then - -- we could use the via file but we don't have a complete io interface yet - local data, found, forced = metapost.checktexts(io.loaddata(name) or "") - if found then - local temp = luatex.registertempfile(name,true) - io.savedata(temp,data) - return temp +do + + local finders = { } + mplib.finders = finders -- also used in meta-lua.lua + + local new_instance = mplib.new + local resolved_file = resolvers.findfile + + local function preprocessed(name) + if not mpbasepath(name) then + -- we could use the via file but we don't have a complete io interface yet + local data, found, forced = metapost.checktexts(io.loaddata(name) or "") + if found then + local temp = luatex.registertempfile(name,true) + io.savedata(temp,data) + return temp + end end + return name end - return name -end -mplib.preprocessed = preprocessed -- helper + mplib.preprocessed = preprocessed -- helper -finders.file = function(specification,name,mode,ftype) - return preprocessed(resolvers.findfile(name,ftype)) -end + local function validftype(ftype) + if ftype == "" then + -- whatever + elseif ftype == 0 then + -- mplib bug + else + return ftype + end + end -local function i_finder(name,mode,ftype) -- fake message for mpost.map and metafun.mpvi - local specification = url.hashed(name) - local finder = finders[specification.scheme] or finders.file - return finder(specification,name,mode,ftype) -end + finders.file = function(specification,name,mode,ftype) + return preprocessed(resolvers.findfile(name,validftype(ftype))) + end -local function o_finder(name,mode,ftype) - -- report_metapost("output file %a, mode %a, ftype %a",name,mode,ftype) - return name -end + local function i_finder(name,mode,ftype) -- fake message for mpost.map and metafun.mpvi + local specification = url.hashed(name) + local finder = finders[specification.scheme] or finders.file + return finder(specification,name,mode,validftype(ftype)) + end -local function finder(name,mode,ftype) - if mode == "w" then - return o_finder(name,mode,ftype) - else - return i_finder(name,mode,ftype) + local function o_finder(name,mode,ftype) + return name end -end -local i_limited = false -local o_limited = false + o_finder = sandbox.register(o_finder,sandbox.filehandlerone,"mplib output finder") -directives.register("system.inputmode", function(v) - if not i_limited then - local i_limiter = io.i_limiter(v) - if i_limiter then - i_finder = i_limiter.protect(i_finder) - i_limited = true - end + local function finder(name,mode,ftype) + return (mode == "w" and o_finder or i_finder)(name,mode,validftype(ftype)) end -end) - -directives.register("system.outputmode", function(v) - if not o_limited then - local o_limiter = io.o_limiter(v) - if o_limiter then - o_finder = o_limiter.protect(o_finder) - o_limited = true - end + + function mplib.new(specification) + specification.find_file = finder -- so we block an overload + return new_instance(specification) end -end) --- -- -- + mplib.finder = finder + +end -metapost.finder = finder +local new_instance = mplib.new +local find_file = mplib.finder function metapost.reporterror(result) if not result then @@ -182,184 +179,93 @@ function metapost.reporterror(result) return true end -if mplibone then - - report_metapost("fatal error: mplib is too old") - - os.exit() - - -- local preamble = [[ - -- boolean mplib ; mplib := true ; - -- string mp_parent_version ; mp_parent_version := "%s" ; - -- input "%s" ; dump ; - -- ]] - -- - -- metapost.parameters = { - -- hash_size = 100000, - -- main_memory = 4000000, - -- max_in_open = 50, - -- param_size = 100000, - -- } - -- - -- function metapost.make(name, target, version) - -- starttiming(mplib) - -- target = file.replacesuffix(target or name, "mem") -- redundant - -- local mpx = mplib.new ( table.merged ( - -- metapost.parameters, - -- { - -- ini_version = true, - -- find_file = finder, - -- job_name = file.removesuffix(target), - -- } - -- ) ) - -- if mpx then - -- starttiming(metapost.exectime) - -- local result = mpx:execute(format(preamble,version or "unknown",name)) - -- stoptiming(metapost.exectime) - -- mpx:finish() - -- end - -- stoptiming(mplib) - -- end - -- - -- function metapost.load(name) - -- starttiming(mplib) - -- local mpx = mplib.new ( table.merged ( - -- metapost.parameters, - -- { - -- ini_version = false, - -- mem_name = file.replacesuffix(name,"mem"), - -- find_file = finder, - -- -- job_name = "mplib", - -- } - -- ) ) - -- local result - -- if not mpx then - -- result = { status = 99, error = "out of memory"} - -- end - -- stoptiming(mplib) - -- return mpx, result - -- end - -- - -- function metapost.checkformat(mpsinput) - -- local mpsversion = environment.version or "unset version" - -- local mpsinput = file.addsuffix(mpsinput or "metafun", "mp") - -- local mpsformat = file.removesuffix(file.basename(texconfig.formatname or (tex and tex.formatname) or mpsinput)) - -- local mpsbase = file.removesuffix(file.basename(mpsinput)) - -- if mpsbase ~= mpsformat then - -- mpsformat = mpsformat .. "-" .. mpsbase - -- end - -- mpsformat = file.addsuffix(mpsformat, "mem") - -- local mpsformatfullname = caches.getfirstreadablefile(mpsformat,"formats","metapost") or "" - -- if mpsformatfullname ~= "" then - -- report_metapost("loading %a from %a", mpsinput, mpsformatfullname) - -- local mpx, result = metapost.load(mpsformatfullname) - -- if mpx then - -- local result = mpx:execute("show mp_parent_version ;") - -- if not result.log then - -- metapost.reporterror(result) - -- else - -- local version = match(result.log,">> *(.-)[\n\r]") or "unknown" - -- version = gsub(version,"[\'\"]","") - -- if version ~= mpsversion then - -- report_metapost("version mismatch: %s <> %s", version or "unknown", mpsversion) - -- else - -- return mpx - -- end - -- end - -- else - -- report_metapost("error in loading %a from %a", mpsinput, mpsformatfullname) - -- metapost.reporterror(result) - -- end - -- end - -- local mpsformatfullname = caches.setfirstwritablefile(mpsformat,"formats") - -- report_metapost("making %a into %a", mpsinput, mpsformatfullname) - -- metapost.make(mpsinput,mpsformatfullname,mpsversion) -- somehow return ... fails here - -- if lfs.isfile(mpsformatfullname) then - -- report_metapost("loading %a from %a", mpsinput, mpsformatfullname) - -- return metapost.load(mpsformatfullname) - -- else - -- report_metapost("problems with %a from %a", mpsinput, mpsformatfullname) - -- end - -- end - -else - - -- let end = relax ; - - local preamble = [[ - boolean mplib ; mplib := true ; - let dump = endinput ; - input "%s" ; - ]] - - local methods = { - double = "double", - scaled = "scaled", - binary = "binary", - decimal = "decimal", - default = "scaled", - } +local f_preamble = formatters [ [[ + boolean mplib ; mplib := true ; + let dump = endinput ; + input "%s" ; +]] ] + +local methods = { + double = "double", + scaled = "scaled", + binary = "binary", + decimal = "decimal", + default = "scaled", +} - function metapost.runscript(code) - return code - end +function metapost.runscript(code) + return code +end - function metapost.scripterror(str) - report_metapost("script error: %s",str) +function metapost.scripterror(str) + report_metapost("script error: %s",str) +end + +-- todo: random_seed + +local f_textext = formatters[ [[rawtextext("%s")]] ] + +function metapost.maketext(s,mode) + if mode and mode == 1 then + -- report_metapost("ignoring verbatimtex: %s",s) + else + -- report_metapost("handling btex ... etex: %s",s) + s = gsub(s,'"','"&ditto&"') + return f_textext(s) end +end - function metapost.load(name,method) - starttiming(mplib) - method = method and methods[method] or "scaled" - local mpx = mplib.new { - ini_version = true, - find_file = finder, - math_mode = method, - run_script = metapost.runscript, - script_error = metapost.scripterror, - } - report_metapost("initializing number mode %a",method) - local result - if not mpx then - result = { status = 99, error = "out of memory"} - else - result = mpx:execute(format(preamble, file.addsuffix(name,"mp"))) -- addsuffix is redundant - end - stoptiming(mplib) - metapost.reporterror(result) - return mpx, result +function metapost.load(name,method) + starttiming(mplib) + method = method and methods[method] or "scaled" + local mpx = new_instance { + ini_version = true, + math_mode = method, + run_script = metapost.runscript, + script_error = metapost.scripterror, + make_text = metapost.maketext, + extensions = 1, + } + report_metapost("initializing number mode %a",method) + local result + if not mpx then + result = { status = 99, error = "out of memory"} + else + result = mpx:execute(f_preamble(file.addsuffix(name,"mp"))) -- addsuffix is redundant end + stoptiming(mplib) + metapost.reporterror(result) + return mpx, result +end - function metapost.checkformat(mpsinput,method) - local mpsversion = environment.version or "unset version" - local mpsinput = mpsinput or "metafun" - local foundfile = "" - if file.suffix(mpsinput) ~= "" then - foundfile = finder(mpsinput) or "" - end - if foundfile == "" then - foundfile = finder(file.replacesuffix(mpsinput,"mpvi")) or "" - end - if foundfile == "" then - foundfile = finder(file.replacesuffix(mpsinput,"mpiv")) or "" - end - if foundfile == "" then - foundfile = finder(file.replacesuffix(mpsinput,"mp")) or "" - end - if foundfile == "" then - report_metapost("loading %a fails, format not found",mpsinput) +function metapost.checkformat(mpsinput,method) + local mpsversion = environment.version or "unset version" + local mpsinput = mpsinput or "metafun" + local foundfile = "" + if file.suffix(mpsinput) ~= "" then + foundfile = find_file(mpsinput) or "" + end + if foundfile == "" then + foundfile = find_file(file.replacesuffix(mpsinput,"mpvi")) or "" + end + if foundfile == "" then + foundfile = find_file(file.replacesuffix(mpsinput,"mpiv")) or "" + end + if foundfile == "" then + foundfile = find_file(file.replacesuffix(mpsinput,"mp")) or "" + end + if foundfile == "" then + report_metapost("loading %a fails, format not found",mpsinput) + else + report_metapost("loading %a as %a using method %a",mpsinput,foundfile,method or "default") + local mpx, result = metapost.load(foundfile,method) + if mpx then + return mpx else - report_metapost("loading %a as %a using method %a",mpsinput,foundfile,method or "default") - local mpx, result = metapost.load(foundfile,method) - if mpx then - return mpx - else - report_metapost("error in loading %a",mpsinput) - metapost.reporterror(result) - end + report_metapost("error in loading %a",mpsinput) + metapost.reporterror(result) end end - end function metapost.unload(mpx) @@ -409,7 +315,8 @@ function metapost.reset(mpx) end end -local mp_inp, mp_log, mp_tag = { }, { }, 0 +local mp_tra = { } +local mp_tag = 0 -- key/values @@ -423,18 +330,24 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, mpx = metapost.format(mpx) -- goody end if mpx and data then + local tra = nil starttiming(metapost) metapost.initializescriptrunner(mpx,trialrun) if trace_graphics then - if not mp_inp[mpx] then + tra = mp_tra[mpx] + if not tra then mp_tag = mp_tag + 1 local jobname = tex.jobname - mp_inp[mpx] = io.open(format("%s-mplib-run-%03i.mp", jobname,mp_tag),"w") - mp_log[mpx] = io.open(format("%s-mplib-run-%03i.log",jobname,mp_tag),"w") + tra = { + inp = io.open(formatters["%s-mplib-run-%03i.mp"] (jobname,mp_tag),"w"), + log = io.open(formatters["%s-mplib-run-%03i.log"](jobname,mp_tag),"w"), + } + mp_tra[mpx] = tra end - local banner = format("%% begin graphic: n=%s, trialrun=%s, multipass=%s, isextrapass=%s\n\n", metapost.n, tostring(trialrun), tostring(multipass), tostring(isextrapass)) - mp_inp[mpx]:write(banner) - mp_log[mpx]:write(banner) + local banner = formatters["%% begin graphic: n=%s, trialrun=%s, multipass=%s, isextrapass=%s\n\n"]( + metapost.n, tostring(trialrun), tostring(multipass), tostring(isextrapass)) + tra.inp:write(banner) + tra.log:write(banner) end if type(data) == "table" then -- this hack is needed because the library currently barks on \n\n @@ -471,17 +384,17 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, -- d = string.gsub(d,"\r","") if d then if trace_graphics then - mp_inp[mpx]:write(format("\n%% begin snippet %s\n",i)) - mp_inp[mpx]:write(d) - mp_inp[mpx]:write(format("\n%% end snippet %s\n",i)) + tra.inp:write(formatters["\n%% begin snippet %s\n"](i)) + tra.inp:write(d) + tra.inp:write(formatters["\n%% end snippet %s\n"](i)) end starttiming(metapost.exectime) - result = mpx:execute(d) + result = mpx:execute(d) -- some day we wil use a coroutine with textexts stoptiming(metapost.exectime) if trace_graphics and result then local str = result.log or result.error if str and str ~= "" then - mp_log[mpx]:write(str) + tra.log:write(str) end end if not metapost.reporterror(result) then @@ -505,7 +418,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, data = "tracingall;" .. data end if trace_graphics then - mp_inp[mpx]:write(data) + tra.inp:write(data) end starttiming(metapost.exectime) result = mpx:execute(data) @@ -513,7 +426,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, if trace_graphics and result then local str = result.log or result.error if str and str ~= "" then - mp_log[mpx]:write(str) + tra.log:write(str) end end -- todo: error message @@ -533,8 +446,8 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end if trace_graphics then local banner = "\n% end graphic\n\n" - mp_inp[mpx]:write(banner) - mp_log[mpx]:write(banner) + tra.inp:write(banner) + tra.log:write(banner) end stoptiming(metapost) end @@ -596,7 +509,7 @@ function metapost.directrun(formatname,filename,outputformat,astable,mpdata) else output = figures[v]:svg() -- (3) for prologues end - local outname = format("%s-%s.%s",basename,v,outputformat) + local outname = formatters["%s-%s.%s"](basename,v,outputformat) report_metapost("saving %s bytes in %a",#output,outname) io.savedata(outname,output) end @@ -629,7 +542,7 @@ function metapost.quickanddirty(mpxformat,data) stopfigure = function() end } - local data = format("; beginfig(1) ;\n %s\n ; endfig ;",data) + local data = formatters["; beginfig(1) ;\n %s\n ; endfig ;"](data) metapost.process(mpxformat, { data }, false, flusher, false, false, "all") if code then return { |