diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua | 1151 |
1 files changed, 635 insertions, 516 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua index 5708577fea6..bb5ce31e5e5 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua @@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['mlib-pps'] = { license = "see context related readme files", } -local format, gmatch, match, split, gsub = string.format, string.gmatch, string.match, string.split, string.gsub -local tonumber, type, unpack, next, select = tonumber, type, unpack, next, select +local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split +local tonumber, type, unpack, next = tonumber, type, unpack, next local round, sqrt, min, max = math.round, math.sqrt, math.min, math.max local insert, remove, concat = table.insert, table.remove, table.concat local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg @@ -23,6 +23,7 @@ local context = context local implement = interfaces.implement local setmacro = interfaces.setmacro +----- texgetbox = tex.getbox local texsetbox = tex.setbox local textakebox = tex.takebox -- or: nodes.takebox local copy_list = node.copy_list @@ -36,7 +37,6 @@ local stoptiming = statistics.stoptiming local trace_runs = false trackers.register("metapost.runs", function(v) trace_runs = v end) local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end) local trace_scripts = false trackers.register("metapost.scripts", function(v) trace_scripts = v end) -local trace_btexetex = false trackers.register("metapost.btexetex", function(v) trace_btexetex = v end) local report_metapost = logs.reporter("metapost") local report_textexts = logs.reporter("metapost","textexts") @@ -57,6 +57,9 @@ local cmyktorgb = colors.cmyktorgb -- or function() return 0,0,0 e local rgbtogray = colors.rgbtogray -- or function() return 0 end local cmyktogray = colors.cmyktogray -- or function() return 0 end +metapost.makempy = metapost.makempy or { nofconverted = 0 } +local makempy = metapost.makempy + local nooutercolor = "0 g 0 G" local nooutertransparency = "/Tr0 gs" -- only when set local outercolormode = 0 @@ -94,25 +97,14 @@ end local f_f = formatters["%F"] local f_f3 = formatters["%.3F"] + local f_gray = formatters["%.3F g %.3F G"] local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"] local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] -local f_cm_b = formatters["q %.6F %.6F %.6F %.6F %.6F %.6F cm"] -local f_scn = formatters["%.3F"] - +local f_cm = formatters["q %F %F %F %F %F %F cm"] local f_shade = formatters["MpSh%s"] + local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] -local s_cm_e = "Q" - -directives.register("metapost.stripzeros",function() - f_f = formatters["%N"] - f_f3 = formatters["%.3N"] - f_gray = formatters["%.3N g %.3N G"] - f_rgb = formatters["%.3N %.3N %.3N rg %.3N %.3N %.3N RG"] - f_cmyk = formatters["%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K"] - f_cm_b = formatters["q %.6N %.6N %.6N %.6N %.6N %.6N cm"] - f_scn = formatters["%.3N"] -end) local function checked_color_pair(color,...) if not color then @@ -202,8 +194,7 @@ local function checkandconvert(ca,cb,model) ca = { cmyktorgb(ca[1],ca[2],ca[3],ca[4]) } cb = { cmyktorgb(cb[1],cb[2],cb[3],cb[4]) } elseif #ca == 1 then - local a = 1 - ca[1] - local b = 1 - cb[1] + local a, b = 1-ca[1], 1-cb[1] ca = { a, a, a } cb = { b, b, b } end @@ -253,18 +244,16 @@ local function preset(t,k) return v end -local function startjob(plugmode,kind) - insert(stack,top) +local function startjob(plugmode) top = { - textexts = { }, -- all boxes, optionally with a different color - texstrings = { }, - texlast = 0, - texdata = setmetatableindex({},preset), -- references to textexts in order or usage - plugmode = plugmode, -- some day we can then skip all pre/postscripts + textexts = { }, -- all boxes, optionally with a different color + texlast = 0, + texdata = setmetatableindex({},preset), -- references to textexts in order or usage + plugmode = plugmode, -- some day we can then skip all pre/postscripts } + insert(stack,top) if trace_runs then - report_metapost("starting %s run at level %i in %s mode", - kind,#stack+1,plugmode and "plug" or "normal") + report_metapost("starting run at level %i",#stack) end return top end @@ -272,17 +261,16 @@ end local function stopjob() if top then for slot, content in next, top.textexts do - if content then - flush_list(content) - if trace_textexts then - report_textexts("freeing text %s",slot) - end + flush_list(content) + if trace_textexts then + report_textexts("freeing text %s",slot) end end if trace_runs then - report_metapost("stopping run at level %i",#stack+1) + report_metapost("stopping run at level %i",#stack) end - top = remove(stack) + remove(stack) + top = stack[#stack] return top end end @@ -293,7 +281,7 @@ end -- end of new -local settext = function(box,slot,str) +local function settext(box,slot) if top then -- if trace_textexts then -- report_textexts("getting text %s from box %s",slot,box) @@ -302,10 +290,10 @@ local settext = function(box,slot,str) end end -local gettext = function(box,slot) +local function gettext(box,slot) if top then - texsetbox(box,top.textexts[slot]) - top.textexts[slot] = false + -- maybe check how often referenced + texsetbox(box,copy_list(top.textexts[slot])) -- if trace_textexts then -- report_textexts("putting text %s in box %s",slot,box) -- end @@ -335,19 +323,14 @@ function models.all(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r = cr[1] - local g = cr[2] - local b = cr[3] + local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else return checked_color_pair(f_rgb,r,g,b,r,g,b) end else - local c = cr[1] - local m = cr[2] - local y = cr[3] - local k = cr[4] + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then k = 1 - k return checked_color_pair(f_gray,k,k) @@ -359,15 +342,10 @@ function models.all(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r = cr[1] - local g = cr[2] - local b = cr[3] + local r, g, b = cr[1], cr[2], cr[3] return checked_color_pair(f_rgb,r,g,b,r,g,b) else - local c = cr[1] - local m = cr[2] - local y = cr[3] - local k = cr[4] + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end @@ -381,19 +359,14 @@ function models.rgb(cr) local s = cr[1] checked_color_pair(f_gray,s,s) elseif n == 3 then - local r = cr[1] - local g = cr[2] - local b = cr[3] + local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else return checked_color_pair(f_rgb,r,g,b,r,g,b) end else - local c = cr[1] - local m = cr[2] - local y = cr[3] - local k = cr[4] + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then k = 1 - k return checked_color_pair(f_gray,k,k) @@ -406,12 +379,11 @@ function models.rgb(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) else - local r = cr[1] - local g = cr[2] - local b = cr[3] local r, g, b if n == 3 then - r, g, b = cmyktorgb(r,g,b,cr[4]) + r, g, b = cmyktorgb(cr[1],cr[2],cr[3],cr[4]) + else + r, g, b = cr[1], cr[2], cr[3] end return checked_color_pair(f_rgb,r,g,b,r,g,b) end @@ -426,9 +398,7 @@ function models.cmyk(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r = cr[1] - local g = cr[2] - local b = cr[3] + local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else @@ -436,10 +406,7 @@ function models.cmyk(cr) return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end else - local c = cr[1] - local m = cr[2] - local y = cr[3] - local k = cr[4] + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then k = k - 1 return checked_color_pair(f_gray,k,k) @@ -451,20 +418,18 @@ function models.cmyk(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) else - local c = cr[1] - local m = cr[2] - local y = cr[3] - local k = cr[4] + local c, m, y, k if n == 3 then - c, m, y, k = rgbtocmyk(c,m,y) + c, m, y, k = rgbtocmyk(cr[1],cr[2],cr[3]) + else + c, m, y, k = cr[1], cr[2], cr[3], cr[4] end return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end function models.gray(cr) - local n = #cr - local s = 0 + local n, s = #cr, 0 if n == 0 then return checked_color_pair() elseif n == 4 then @@ -489,9 +454,76 @@ setmetatableindex(models, function(t,k) end) local function colorconverter(cs) + -- return models[colors.currentmodel()](cs) return models[outercolormodel](cs) end +local btex = P("btex") +local etex = P(" etex") +local vtex = P("verbatimtex") +local ttex = P("textext") +local gtex = P("graphictext") +local multipass = P("forcemultipass") +local spacing = S(" \n\r\t\v")^0 +local dquote = P('"') + +local found, forced = false, false + +local function convert(str) + found = true + return "rawtextext(\"" .. str .. "\")" -- centered +end +local function ditto(str) + return "\" & ditto & \"" +end +local function register() + found = true +end +local function force() + forced = true +end + +local texmess = (dquote/ditto + (1 - etex))^0 + +local function ignore(s) + report_metapost("ignoring verbatim tex: %s",s) + return "" +end + +-- local parser = P { +-- [1] = Cs((V(2)/register + V(4)/ignore + V(3)/convert + V(5)/force + 1)^0), +-- [2] = ttex + gtex, +-- [3] = btex * spacing * Cs(texmess) * etex, +-- [4] = vtex * spacing * Cs(texmess) * etex, +-- [5] = multipass, -- experimental, only for testing +-- } + +-- currently a a one-liner produces less code + +-- textext.*(".*") can have "'s but tricky parsing as we can have concatenated strings +-- so this is something for a boring plane or train trip and we might assume proper mp +-- input anyway + +local parser = Cs(( + (ttex + gtex)/register + + (btex * spacing * Cs(texmess) * etex)/convert + + (vtex * spacing * Cs(texmess) * etex)/ignore + + 1 +)^0) + +local checking_enabled = false directives.register("metapost.checktexts",function(v) checking_enabled = v end) + +local function checktexts(str) + if checking_enabled then + found, forced = false, false + return lpegmatch(parser,str), found, forced + else + return str + end +end + +metapost.checktexts = checktexts + local factor = 65536*(7227/7200) implement { @@ -509,15 +541,42 @@ local function sxsy(wd,ht,dp) -- helper for text return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0 end -metapost.sxsy = sxsy - -- for stock mp we need to declare the booleans first +local no_first_run = "boolean mfun_first_run ; mfun_first_run := false ;" +local do_first_run = "boolean mfun_first_run ; mfun_first_run := true ;" +local no_trial_run = "boolean mfun_trial_run ; mfun_trial_run := false ;" +local do_trial_run = "boolean mfun_trial_run ; mfun_trial_run := true ;" local do_begin_fig = "; beginfig(1) ; " local do_end_fig = "; endfig ;" local do_safeguard = ";" -function metapost.preparetextextsdata() +-- local f_text_data = formatters["mfun_tt_w[%i] := %f ; mfun_tt_h[%i] := %f ; mfun_tt_d[%i] := %f ;"] +-- +-- function metapost.textextsdata() +-- local textexts = top.textexts +-- local collected = { } +-- local nofcollected = 0 +-- for k, data in sortedhash(top.texdata) do -- sort is nicer in trace +-- local texorder = data.texorder +-- for n=1,#texorder do +-- local box = textexts[texorder[n]] +-- if box then +-- local wd, ht, dp = box.width/factor, box.height/factor, box.depth/factor +-- if trace_textexts then +-- report_textexts("passed data item %s:%s > (%p,%p,%p)",k,n,wd,ht,dp) +-- end +-- nofcollected = nofcollected + 1 +-- collected[nofcollected] = f_text_data(n,wd,n,ht,n,dp) +-- else +-- break +-- end +-- end +-- end +-- return collected +-- end + +function metapost.textextsdata() local textexts = top.textexts local collected = { } for k, data in sortedhash(top.texdata) do -- sort is nicer in trace @@ -531,10 +590,18 @@ function metapost.preparetextextsdata() end end end - mp.mf_tt_initialize(collected) + mp.tt_initialize(collected) end -local runmetapost = metapost.run + +metapost.intermediate = metapost.intermediate or { } +metapost.intermediate.actions = metapost.intermediate.actions or { } + +metapost.method = 1 -- 1:dumb 2:clever + +-- maybe we can latelua the texts some day + +local processmetapost = metapost.process local function checkaskedfig(askedfig) -- return askedfig, wrappit if not askedfig then @@ -557,98 +624,231 @@ local function extrapass() if trace_runs then report_metapost("second run of job %s, asked figure %a",top.nofruns,top.askedfig) end - metapost.preparetextextsdata() - runmetapost { - mpx = top.mpx, - askedfig = top.askedfig, - incontext = true, - data = { - top.wrappit and do_begin_fig or "", - no_trial_run, - top.initializations, - do_safeguard, - top.data, - top.wrappit and do_end_fig or "", - }, - } + local textexts = metapost.textextsdata() + processmetapost(top.mpx, { + top.wrappit and do_begin_fig or "", + no_trial_run, + textexts and concat(textexts," ;\n") or "", + top.initializations, + do_safeguard, + top.data, + top.wrappit and do_end_fig or "", + }, false, nil, false, true, top.askedfig) end --- This one is called from the \TEX\ end so the specification is different --- from the specification to metapost,run cum suis! The definitions and --- extension used to be handled here but are now delegated to the format --- initializers because we need to accumulate them for nested instances (a --- side effect of going single pass). - -function metapost.graphic_base_pass(specification) - local top = startjob(true,"base") +function metapost.graphic_base_pass(specification) -- name will change (see mlib-ctx.lua) + local top = startjob(true) + -- local mpx = specification.mpx -- mandate local data = specification.data or "" + local definitions = specification.definitions or "" + -- local extensions = metapost.getextensions(specification.instance,specification.useextensions) + local extensions = specification.extensions or "" local inclusions = specification.inclusions or "" local initializations = specification.initializations or "" - local askedfig, - wrappit = checkaskedfig(specification.figure) - nofruns = nofruns + 1 - top.askedfig = askedfig - top.wrappit = wrappit - top.nofruns = nofruns + local askedfig = specification.figure -- no default else no wrapper metapost.namespace = specification.namespace or "" - top.mpx = mpx - top.data = data - top.initializations = initializations + -- + local askedfig, wrappit = checkaskedfig(askedfig) + -- + nofruns = nofruns + 1 + -- + top.askedfig = askedfig + top.wrappit = wrappit + top.nofruns = nofruns + -- + local done_1, done_2, done_3, forced_1, forced_2, forced_3 + if checking_enabled then + data, done_1, forced_1 = checktexts(data) + if extensions == "" then + extensions, done_2, forced_2 = "", false, false + else + extensions, done_2, forced_2 = checktexts(extensions) + end + if inclusions == "" then + inclusions, done_3, forced_3 = "", false, false + else + inclusions, done_3, forced_3 = checktexts(inclusions) + end + end + top.intermediate = false + top.multipass = false -- no needed here + top.mpx = mpx + top.data = data + top.initializations = initializations + local method = metapost.method if trace_runs then - report_metapost("running job %s, asked figure %a",nofruns,askedfig) + if method == 1 then + report_metapost("forcing two runs due to library configuration") + elseif method ~= 2 then + report_metapost("ignoring run due to library configuration") + elseif not (done_1 or done_2 or done_3) then + report_metapost("forcing one run only due to analysis") + elseif done_1 then + report_metapost("forcing at max two runs due to main code") + elseif done_2 then + report_metapost("forcing at max two runs due to extensions") + else + report_metapost("forcing at max two runs due to inclusions") + end end - runmetapost { - mpx = mpx, - askedfig = askedfig, - incontext = true, - data = { + if method == 1 or (method == 2 and (done_1 or done_2 or done_3)) then + if trace_runs then + report_metapost("first run of job %s, asked figure %a",nofruns,askedfig) + end + -- first true means: trialrun, second true means: avoid extra run if no multipass + local flushed = processmetapost(mpx, { + definitions, + extensions, inclusions, wrappit and do_begin_fig or "", + do_first_run, + do_trial_run, initializations, do_safeguard, data, wrappit and do_end_fig or "", - }, - } + }, true, nil, not (forced_1 or forced_2 or forced_3), false, askedfig) + if top.intermediate then + for _, action in next, metapost.intermediate.actions do + action() + end + end + if not flushed or not metapost.optimize then + -- tricky, we can only ask once for objects and therefore + -- we really need a second run when not optimized + -- context.MPLIBextrapass(askedfig) + context(extrapass) + end + else + if trace_runs then + report_metapost("running job %s, asked figure %a",nofruns,askedfig) + end + processmetapost(mpx, { + definitions, + extensions, + inclusions, + wrappit and do_begin_fig or "", + do_first_run, + no_trial_run, + initializations, + do_safeguard, + data, + wrappit and do_end_fig or "", + }, false, nil, false, false, askedfig) + end context(stopjob) end -local function oldschool(mpx, data, trial_run, flusher, was_multi_pass, is_extra_pass, askedfig, incontext) - metapost.process { - mpx = mpx, - flusher = flusher, - askedfig = askedfig, - useplugins = incontext, - incontext = incontext, - data = data, - } +-- we overload metapost.process here + +function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, plugmode) -- overloads + startjob(plugmode) + processmetapost(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) + stopjob() end -function metapost.process(specification,...) - if type(specification) ~= "table" then - oldschool(specification,...) - else - startjob(specification.incontext or specification.useplugins,"process") - runmetapost(specification) - stopjob() +local start = [[\starttext]] +local preamble = [[\def\MPLIBgraphictext#1{\startTEXpage[scale=10000]#1\stopTEXpage}]] +local stop = [[\stoptext]] + +local mpyfilename = nil + +function makempy.registerfile(filename) + mpyfilename = filename +end + +implement { + name = "registermpyfile", + actions = makempy.registerfile, + arguments = "string" +} + +local pdftompy = sandbox.registerrunner { + name = "mpy:pstoedit", + program = "pstoedit", + template = "-ssp -dt -f mpost %pdffile% %mpyfile%", + checkers = { + pdffile = "writable", + mpyfile = "readable", + }, + reporter = report_metapost, +} + +local textopdf = sandbox.registerrunner { + name = "mpy:context", + program = "context", + template = "--once %runmode% %texfile%", + checkers = { + runmode = "string", + texfile = "readable", + }, + reporter = report_metapost, +} + +function makempy.processgraphics(graphics) + if #graphics == 0 then + return + end + if mpyfilename and exists(mpyfilename) then + report_metapost("using file: %s",mpyfilename) + return + end + makempy.nofconverted = makempy.nofconverted + 1 + starttiming(makempy) + local mpofile = tex.jobname .. "-mpgraph" + local mpyfile = file.replacesuffix(mpofile,"mpy") + local pdffile = file.replacesuffix(mpofile,"pdf") + local texfile = file.replacesuffix(mpofile,"tex") + savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n") + textopdf { + runmode = tex.interactionmode == 0 and "--batchmode" or "", + texfile = texfile, + } + if exists(pdffile) then + pdftompy { + pdffile = pdffile, + mpyfile = mpyfile, + } + if exists(mpyfile) then + local result, r = { }, 0 + local data = io.loaddata(mpyfile) + if data and #data > 0 then + for figure in gmatch(data,"beginfig(.-)endfig") do + r = r + 1 + result[r] = formatters["begingraphictextfig%sendgraphictextfig ;\n"](figure) + end + savedata(mpyfile,concat(result,"")) + end + end end + stoptiming(makempy) end -- -- the new plugin handler -- -- -local sequencers = utilities.sequencers -local appendgroup = sequencers.appendgroup -local appendaction = sequencers.appendaction +local sequencers = utilities.sequencers +local appendgroup = sequencers.appendgroup +local appendaction = sequencers.appendaction -local resetteractions = sequencers.new { arguments = "t" } -local processoractions = sequencers.new { arguments = "object,prescript,before,after" } +local resetter = nil +local analyzer = nil +local processor = nil + +local resetteractions = sequencers.new { arguments = "t" } +local analyzeractions = sequencers.new { arguments = "object,prescript" } +local processoractions = sequencers.new { arguments = "object,prescript,before,after" } appendgroup(resetteractions, "system") +appendgroup(analyzeractions, "system") appendgroup(processoractions,"system") -- later entries come first +--~ local scriptsplitter = Cf(Ct("") * ( +--~ Cg(C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0) +--~ )^0, rawset) + local scriptsplitter = Ct ( Ct ( C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0 )^0 ) @@ -657,24 +857,22 @@ local function splitprescript(script) local hash = lpegmatch(scriptsplitter,script) for i=#hash,1,-1 do local h = hash[i] - if h == "reset" then - for k, v in next, hash do - if type(k) ~= "number" then - hash[k] = nil - end - end - else - hash[h[1]] = h[2] +if h == "reset" then + for k, v in next, hash do + if type(k) ~= "number" then + hash[k] = nil end end +else + hash[h[1]] = h[2] +end + end if trace_scripts then report_scripts(table.serialize(hash,"prescript")) end return hash end -metapost.splitprescript = splitprescript - -- -- not used: -- -- local function splitpostscript(script) @@ -708,9 +906,27 @@ end function metapost.resetplugins(t) -- intialize plugins, before figure if top.plugmode then + outercolormodel = colors.currentmodel() -- currently overloads the one set at the tex end - resetteractions.runner(t) + + -- plugins can have been added + resetter = resetteractions.runner + analyzer = analyzeractions.runner + processor = processoractions.runner + -- let's apply one runner + resetter(t) + end +end + +function metapost.analyzeplugins(object) -- each object (first pass) + if top.plugmode then + local prescript = object.prescript -- specifications + if prescript and #prescript > 0 then + analyzer(object,splitprescript(prescript) or {}) + return top.multipass + end end + return false end function metapost.processplugins(object) -- each object (second pass) @@ -719,7 +935,7 @@ function metapost.processplugins(object) -- each object (second pass) if prescript and #prescript > 0 then local before = { } local after = { } - processoractions.runner(object,splitprescript(prescript) or {},before,after) + processor(object,splitprescript(prescript) or {},before,after) return #before > 0 and before, #after > 0 and after else local c = object.color @@ -738,16 +954,11 @@ local basepoints = number.dimenfactors["bp"] local function cm(object) local op = object.path if op then - local first = op[1] - local second = op[2] - local fourth = op[4] + local first, second, fourth = op[1], op[2], op[4] if fourth then - local tx = first.x_coord - local ty = first.y_coord - local sx = second.x_coord - tx - local sy = fourth.y_coord - ty - local rx = second.y_coord - ty - local ry = fourth.x_coord - tx + local tx, ty = first.x_coord , first.y_coord + local sx, sy = second.x_coord - tx, fourth.y_coord - ty + local rx, ry = second.y_coord - ty, fourth.x_coord - tx if sx == 0 then sx = 0.00001 end if sy == 0 then sy = 0.00001 end return sx, rx, ry, sy, tx, ty @@ -756,8 +967,6 @@ local function cm(object) return 1, 0, 0, 1, 0, 0 -- weird case end -metapost.cm = cm - -- color local function cl_reset(t) @@ -766,195 +975,157 @@ end -- text -local tx_reset, tx_process do - - local eol = S("\n\r")^1 - local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) - local splitter = Ct( - ( ( - P("s:") * C((1-eol)^1) - + P("n:") * ((1-eol)^1/tonumber) - + P("b:") * ((1-eol)^1/toboolean) - ) * eol^0 )^0) - - local function applyformat(s) - local t = lpegmatch(splitter,s) - if #t == 1 then - return s - else - local f = lpegmatch(cleaner,t[1]) - return formatters[f](unpack(t,2)) - end +local function tx_reset() + if top then + -- why ? + top.texhash = { } + top.texlast = 0 end +end - local fmt = formatters["%s %s %s % t"] - ----- pat = tsplitat(":") - local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work - - local f_gray_yes = formatters["s=%.3F,a=%i,t=%.3F"] - local f_gray_nop = formatters["s=%.3F"] - local f_rgb_yes = formatters["r=%.3F,g=%.3F,b=%.3F,a=%.3F,t=%.3F"] - local f_rgb_nop = formatters["r=%.3F,g=%.3F,b=%.3F"] - local f_cmyk_yes = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F,a=%.3F,t=%.3F"] - local f_cmyk_nop = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F"] - - directives.register("metapost.stripzeros",function() - f_gray_yes = formatters["s=%.3N,a=%i,t=%.3N"] - f_gray_nop = formatters["s=%.3N"] - f_rgb_yes = formatters["r=%.3N,g=%.3N,b=%.3N,a=%.3N,t=%.3N"] - f_rgb_nop = formatters["r=%.3N,g=%.3N,b=%.3N"] - f_cmyk_yes = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N,a=%.3N,t=%.3N"] - f_cmyk_nop = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N"] - end) - - local ctx_MPLIBsetNtext = context.MPLIBsetNtextX - local ctx_MPLIBsetCtext = context.MPLIBsetCtextX - local ctx_MPLIBsettext = context.MPLIBsettextX - - local bp = number.dimenfactors.bp - - local mp_index = 0 - local mp_target = 0 - local mp_c = nil - local mp_a = nil - local mp_t = nil - - local function processtext() - local mp_text = top.texstrings[mp_index] - if not mp_text then - report_textexts("missing text for index %a",mp_index) - elseif not mp_c then - ctx_MPLIBsetNtext(mp_target,mp_text) - elseif #mp_c == 1 then - if mp_a and mp_t then - ctx_MPLIBsetCtext(mp_target,f_gray_yes(mp_c[1],mp_a,mp_t),mp_text) - else - ctx_MPLIBsetCtext(mp_target,f_gray_nop(mp_c[1]),mp_text) +local fmt = formatters["%s %s %s % t"] +----- pat = tsplitat(":") +local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work + +local f_gray_yes = formatters["s=%F,a=%F,t=%F"] +local f_gray_nop = formatters["s=%F"] +local f_rgb_yes = formatters["r=%F,g=%F,b=%F,a=%F,t=%F"] +local f_rgb_nop = formatters["r=%F,g=%F,b=%F"] +local f_cmyk_yes = formatters["c=%F,m=%F,y=%F,k=%F,a=%F,t=%F"] +local f_cmyk_nop = formatters["c=%F,m=%F,y=%F,k=%F"] + +local ctx_MPLIBsetNtext = context.MPLIBsetNtext +local ctx_MPLIBsetCtext = context.MPLIBsetCtext +local ctx_MPLIBsettext = context.MPLIBsettext + +-- we reuse content when possible +-- we always create at least one instance (for dimensions) +-- we make sure we don't do that when we use one (else counter issues with e.g. \definelabel) + +local eol = S("\n\r")^1 +local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) +local splitter = Ct( + ( ( + P("s:") * C((1-eol)^1) + + P("n:") * ((1-eol)^1/tonumber) + + P("b:") * ((1-eol)^1/toboolean) + ) * eol^0 )^0) + +local function applyformat(s) + local t = lpegmatch(splitter,s) + if #t == 1 then + return s + else + local f = lpegmatch(cleaner,t[1]) + return formatters[f](unpack(t,2)) + end +end + +local function tx_analyze(object,prescript) + local data = top.texdata[metapost.properties.number] + local tx_stage = prescript.tx_stage + if tx_stage == "trial" then + local tx_trial = data.textrial + 1 + data.textrial = tx_trial + local tx_number = tonumber(prescript.tx_number) + local s = object.postscript or "" + local c = object.color -- only simple ones, no transparency + if #c == 0 then + local txc = prescript.tx_color + if txc then + c = lpegmatch(pat,txc) end - elseif #mp_c == 3 then - if mp_a and mp_t then - ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3],mp_a,mp_t),mp_text) - else - ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3]),mp_text) + end + if prescript.tx_type == "format" then + s = applyformat(s) + end + local a = tonumber(prescript.tr_alternative) + local t = tonumber(prescript.tr_transparency) + local h = fmt(tx_number,a or "-",t or "-",c or "-") + local n = data.texhash[h] -- todo: hashed variant with s (nicer for similar labels) + if n then + data.texslots[tx_trial] = n + if trace_textexts then + report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"old",n,h,s) end - elseif #mp_c == 4 then - if mp_a and mp_t then - ctx_MPLIBsetCtext(mp_target,f_cmyk_yes(mp_c[1],mp_c[2],mp_c[3],mp_c[4],mp_a,mp_t),mp_text) - else - ctx_MPLIBsetCtext(mp_target,f_cmyk_nop(mp_c[1],mp_c[2],mp_c[3],mp_c[4]),mp_text) + elseif prescript.tx_global == "yes" and data.texorder[tx_number] then + -- we already have one flush and don't want it redone .. this needs checking + if trace_textexts then + report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"ignored",tx_last,h,s) end else - -- can't happen - ctx_MPLIBsetNtext(mp_target,mp_text) - end - end - - function mp.mf_some_text(index,str) - mp_target = index - mp_index = index - mp_c = nil - mp_a = nil - mp_t = nil - top.texstrings[mp_index] = str - tex.runtoks("mptexttoks") - local box = textakebox("mptextbox") - top.textexts[mp_target] = box - mp.triplet(bp*box.width,bp*box.height,bp*box.depth) - madetext = nil - end - - local madetext = nil - - function mp.mf_made_text(index) - mp.mf_some_text(index,madetext) - end - - function metapost.maketext(s,mode) - if mode and mode == 1 then - if trace_btexetex then - report_metapost("ignoring verbatimtex: [[%s]]",s) + local tx_last = top.texlast + 1 + top.texlast = tx_last + -- report_textexts("tex string: %s",s) + if not c then + ctx_MPLIBsetNtext(tx_last,s) + elseif #c == 1 then + if a and t then + ctx_MPLIBsetCtext(tx_last,f_gray_yes(c[1],a,t),s) + else + ctx_MPLIBsetCtext(tx_last,f_gray_nop(c[1]),s) + end + elseif #c == 3 then + if a and t then + ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3],a,t),s) + else + ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3]),s) + end + elseif #c == 4 then + if a and t then + ctx_MPLIBsetCtext(tx_last,f_cmyk_yes(c[1],c[2],c[3],c[4],a,t),s) + else + ctx_MPLIBsetCtext(tx_last,f_cmyk_nop(c[1],c[2],c[3],c[4]),s) + end + else + ctx_MPLIBsetNtext(tx_last,s) end - else - if trace_btexetex then - report_metapost("handling btex ... etex: [[%s]]",s) + top.multipass = true + data.texhash [h] = tx_last + -- data.texhash [tx_number] = tx_last + data.texslots[tx_trial] = tx_last + data.texorder[tx_number] = tx_last + if trace_textexts then + report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"new",tx_last,h,s) end - -- madetext = utilities.strings.collapse(s) - madetext = s - return "rawmadetext" end - end - - function mp.mf_formatted_text(index,fmt,...) - local t = { } - for i=1,select("#",...) do - local ti = select(i,...) - if type(ti) ~= "table" then - t[#t+1] = ti + elseif tx_stage == "extra" then + local tx_trial = data.textrial + 1 + data.textrial = tx_trial + local tx_number = tonumber(prescript.tx_number) + if not data.texorder[tx_number] then + local s = object.postscript or "" + local tx_last = top.texlast + 1 + top.texlast = tx_last + ctx_MPLIBsettext(tx_last,s) + top.multipass = true + data.texslots[tx_trial] = tx_last + data.texorder[tx_number] = tx_last + if trace_textexts then + report_textexts("stage %a, usage %a, number %a, extra %a, text %a",tx_stage,tx_trial,tx_number,tx_last,s) end end - local f = lpegmatch(cleaner,fmt) - local s = formatters[f](unpack(t)) or "" - mp.mf_some_text(index,s) - end - - interfaces.implement { - name = "mptexttoks", - actions = processtext, - } - - tx_reset = function() - if top then - top.texhash = { } - top.texlast = 0 - end end +end - tx_process = function(object,prescript,before,after) - local data = top.texdata[metapost.properties.number] - local index = tonumber(prescript.tx_index) - if index then +local function tx_process(object,prescript,before,after) + local data = top.texdata[metapost.properties.number] + local tx_number = tonumber(prescript.tx_number) + if tx_number then + local tx_stage = prescript.tx_stage + if tx_stage == "final" then + local tx_final = data.texfinal + 1 + data.texfinal = tx_final + local n = data.texslots[tx_final] if trace_textexts then - report_textexts("using index %a",index) - end - -- - mp_c = object.color - if #mp_c == 0 then - local txc = prescript.tx_color - if txc then - mp_c = lpegmatch(pat,txc) - end - end - mp_a = tonumber(prescript.tr_alternative) - mp_t = tonumber(prescript.tr_transparency) - -- - mp_index = index - mp_target = top.texlast - 1 - top.texlast = mp_target - -- - local mp_text = top.texstrings[mp_index] - local box - if prescript.tx_cache == "no" then - tex.runtoks("mptexttoks") - box = textakebox("mptextbox") - else - local hash = fmt(mp_text,mp_a or "-",mp_t or "-",mp_c or "-") - box = data.texhash[hash] - if box then - box = copy_list(box) - else - tex.runtoks("mptexttoks") - box = textakebox("mptextbox") - data.texhash[hash] = box - end + report_textexts("stage %a, usage %a, number %a, use %a",tx_stage,tx_final,tx_number,n) end - top.textexts[mp_target] = box - -- + local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function + local box = top.textexts[n] if box then - -- we need to freeze the variables outside the function - local sx, rx, ry, sy, tx, ty = cm(object) - local target = mp_target before[#before+1] = function() - context.MPLIBgettextscaledcm(target, + -- flush always happens, we can have a special flush function injected before + context.MPLIBgettextscaledcm(n, f_f(sx), -- bah ... %s no longer checks f_f(rx), -- bah ... %s no longer checks f_f(ry), -- bah ... %s no longer checks @@ -965,7 +1136,7 @@ local tx_reset, tx_process do end else before[#before+1] = function() - report_textexts("unknown %s",index) + report_textexts("unknown %s",tx_number) end end if not trace_textexts then @@ -976,7 +1147,6 @@ local tx_reset, tx_process do object.istext = true end end - end -- we could probably redo normal textexts in the next way but as it's rather optimized @@ -1012,32 +1182,31 @@ end -- graphics (we use the given index because pictures can be reused) +local graphics = { } -local gt_reset, gt_process do - - local graphics = { } - - - local mp_index = 0 - local mp_str = "" - - function mp.mf_graphic_text(index,str) - if not graphics[index] then - mp_index = index - mp_str = str - tex.runtoks("mpgraphictexttoks") - end +function metapost.intermediate.actions.makempy() + if #graphics > 0 then + makempy.processgraphics(graphics) + graphics = { } -- ? could be gt_reset end +end - interfaces.implement { - name = "mpgraphictexttoks", - actions = function() - context.MPLIBgraphictext(mp_index,mp_str) - end, - } - +local function gt_analyze(object,prescript) + local gt_stage = prescript.gt_stage + local gt_index = tonumber(prescript.gt_index) + if gt_stage == "trial" and not graphics[gt_index] then + graphics[gt_index] = formatters["\\MPLIBgraphictext{%s}"](object.postscript or "") + top.intermediate = true + top.multipass = true + end end +-- local function gt_process(object,prescript,before,after) +-- local gt_stage = prescript.gt_stage +-- if gt_stage == "final" then +-- end +-- end + -- shades local function sh_process(object,prescript,before,after) @@ -1173,7 +1342,7 @@ end local function bm_process(object,prescript,before,after) local bm_xresolution = prescript.bm_xresolution if bm_xresolution then - before[#before+1] = f_cm_b(cm(object)) + before[#before+1] = f_cm(cm(object)) before[#before+1] = function() figures.bitmapimage { xresolution = tonumber(bm_xresolution), @@ -1183,7 +1352,7 @@ local function bm_process(object,prescript,before,after) data = object.postscript } end - before[#before+1] = s_cm_e + before[#before+1] = "Q" object.path = false object.color = false object.grouped = true @@ -1195,13 +1364,10 @@ end local function ps_process(object,prescript,before,after) local ps_label = prescript.ps_label if ps_label then - local op = object.path - local first = op[1] - local third = op[3] - local x = first.x_coord - local y = first.y_coord - local w = third.x_coord - x - local h = third.y_coord - y + local op = object.path + local first, third = op[1], op[3] + local x, y = first.x_coord, first.y_coord + local w, h = third.x_coord - x, third.y_coord - y local properties = metapost.properties x = x - properties.llx y = properties.ury - y @@ -1214,33 +1380,14 @@ end -- figures --- local sx, rx, ry, sy, tx, ty = cm(object) --- sxsy(box.width,box.height,box.depth)) - -function mp.mf_external_figure(filename) - local f = figures.getinfo(filename) - local w = 0 - local h = 0 - if f then - local u = f.used - if u and u.fullname then - w = u.width or 0 - h = u.height or 0 - end - else - report_metapost("external figure %a not found",filename) - end - mp.triplet(w/65536,h/65536,0) -end - local function fg_process(object,prescript,before,after) local fg_name = prescript.fg_name if fg_name then - before[#before+1] = f_cm_b(cm(object)) -- beware: does not use the cm stack + before[#before+1] = f_cm(cm(object)) -- beware: does not use the cm stack before[#before+1] = function() context.MPLIBfigure(fg_name,prescript.fg_mask or "") end - before[#before+1] = s_cm_e + before[#before+1] = "Q" object.path = false object.grouped = true end @@ -1264,27 +1411,14 @@ local remappers = { [4] = formatters["c=%s,m=%s,y=%s,k=%s"], } -local processlast = 0 -local processhash = setmetatableindex(function(t,k) - processlast = processlast + 1 - local v = formatters["mp_%s"](processlast) - defineprocesscolor(v,k,true,true) - t[k] = v - return v -end) - -local function checked_transparency(alternative,transparency,before,after) - alternative = tonumber(alternative) or 1 - transparency = tonumber(transparency) or 0 - before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,alternative,transparency,true)) - after [#after +1] = "/Tr0 gs" -- outertransparency -end - local function tr_process(object,prescript,before,after) -- before can be shortcut to t local tr_alternative = prescript.tr_alternative if tr_alternative then - checked_transparency(tr_alternative,prescript.tr_transparency,before,after) + tr_alternative = tonumber(tr_alternative) + local tr_transparency = tonumber(prescript.tr_transparency) + before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,tr_alternative,tr_transparency,true)) + after[#after+1] = "/Tr0 gs" -- outertransparency end local cs = object.color if cs and #cs > 0 then @@ -1295,35 +1429,29 @@ local function tr_process(object,prescript,before,after) else local sp_name = prescript.sp_name or "black" if sp_type == "spot" then - local sp_value = prescript.sp_value or "1" - local components = split(sp_value,":") - local specification = remappers[#components] - if specification then - specification = specification(unpack(components)) - else - specification = "s=0" - end - local sp_spec = processhash[specification] - definespotcolor(sp_name,sp_spec,"p=1",true) + local sp_value = prescript.sp_value or "s:1" + local sp_temp = formatters["mp:%s"](sp_value) + local s = split(sp_value,":") + local r = remappers[#s] + defineprocesscolor(sp_temp,r and r(unpack(s)) or "s=0",true,true) + definespotcolor(sp_name,sp_temp,"p=1",true) sp_type = "named" elseif sp_type == "multitone" then -- (fractions of a multitone) don't work well in mupdf - local sp_value = prescript.sp_value or "1" - local sp_specs = { } + local sp_value = prescript.sp_value or "s:1" + local sp_spec = { } local sp_list = split(sp_value," ") for i=1,#sp_list do - local sp_value = sp_list[i] - local components = split(sp_value,":") - local specification = remappers[#components] - if specification then - specification = specification(unpack(components)) - else - specification = "s=0" - end - local sp_spec = processhash[specification] - sp_specs[i] = formatters["%s=1"](sp_spec) + local v = sp_list[i] + local t = formatters["mp:%s"](v) + local s = split(v,":") + local r = remappers[#s] + defineprocesscolor(t,r and r(unpack(s)) or "s=0",true,true) + local tt = formatters["ms:%s"](v) + definespotcolor(tt,t,"p=1",true) + sp_spec[#sp_spec+1] = formatters["%s=1"](t) end - sp_specs = concat(sp_specs,",") - definemultitonecolor(sp_name,sp_specs,"","") + sp_spec = concat(sp_spec,",") + definemultitonecolor(sp_name,sp_spec,"","",true) sp_type = "named" end if sp_type == "named" then @@ -1335,7 +1463,8 @@ local function tr_process(object,prescript,before,after) local t = t_list[sp_name] -- string or attribute local v = t and transparencyvalue(t) if v then - checked_transparency(v[1],v[2],before,after) + before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,v[1],v[2],true)) + after[#after+1] = "/Tr0 gs" -- outertransparency end end local c = c_list[sp_name] -- string or attribute @@ -1343,34 +1472,29 @@ local function tr_process(object,prescript,before,after) if v then -- all=1 gray=2 rgb=3 cmyk=4 local colorspace = v[1] - local factor = cs[1] + local f = cs[1] if colorspace == 2 then - local s = factor * v[2] + local s = f*v[2] c_b, c_a = checked_color_pair(f_gray,s,s) elseif colorspace == 3 then - local r = factor * v[3] - local g = factor * v[4] - local b = factor * v[5] + local r, g, b = f*v[3], f*v[4], f*v[5] c_b, c_a = checked_color_pair(f_rgb,r,g,b,r,g,b) elseif colorspace == 4 or colorspace == 1 then - local c = factor * v[6] - local m = factor * v[7] - local y = factor * v[8] - local k = factor * v[9] + local c, m, y, k = f*v[6], f*v[7], f*v[8], f*v[9] c_b, c_a = checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) elseif colorspace == 5 then -- not all viewers show the fractions ok local name = v[10] local value = split(v[13],",") - if factor ~= 1 then + if f ~= 1 then for i=1,#value do - value[i] = f_scn(factor * (tonumber(value[i]) or 1)) + value[i] = f * (tonumber(value[i]) or 1) end end value = concat(value," ") c_b, c_a = checked_color_pair(f_spot,name,name,value,value) else - local s = factor *v[2] + local s = f*v[2] c_b, c_a = checked_color_pair(f_gray,s,s) end end @@ -1395,6 +1519,10 @@ end -- groups +local types = { + isolated +} + local function gr_process(object,prescript,before,after) local gr_state = prescript.gr_state if not gr_state then @@ -1402,10 +1530,7 @@ local function gr_process(object,prescript,before,after) elseif gr_state == "start" then local gr_type = utilities.parsers.settings_to_set(prescript.gr_type) local path = object.path - local p1 = path[1] - local p2 = path[2] - local p3 = path[3] - local p4 = path[4] + local p1, p2, p3, p4 = path[1], path[2], path[3], path[4] local llx = min(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) local lly = min(p1.y_coord,p2.y_coord,p3.y_coord,p4.y_coord) local urx = max(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) @@ -1429,88 +1554,82 @@ end -- outlines -local ot_reset, ot_process do +local outlinetexts = { } - local outlinetexts = { } -- also in top data +local function ot_reset() + outlinetexts = { } +end - ot_reset = function () - outlinetexts = { } +local function ot_analyze(object,prescript) + local ot_stage = prescript.ot_stage + local ot_index = tonumber(prescript.ot_index) + if ot_index and ot_stage == "trial" and not outlinetexts[ot_index] then + local ot_kind = prescript.ot_kind or "" + top.intermediate = true + top.multipass = true + context.MPLIBoutlinetext(ot_index,ot_kind,object.postscript) end +end - local mp_index = 0 - local mp_kind = "" - local mp_str = "" +local function ot_process(object,prescript,before,after) +end - function mp.mf_outline_text(index,str,kind) - if not outlinetexts[index] then - mp_index = index - mp_kind = kind - mp_str = str - tex.runtoks("mpoutlinetoks") +implement { + name = "MPLIBconvertoutlinetext", + arguments = { "integer", "string", "integer" }, + actions = function(index,kind,box) + local boxtomp = fonts.metapost.boxtomp + if boxtomp then + outlinetexts[index] = boxtomp(box,kind) + else + outlinetexts[index] = "" end end +} - interfaces.implement { - name = "mpoutlinetoks", - actions = function() - context.MPLIBoutlinetext(mp_index,mp_kind,mp_str) - end, - } +function mp.get_outline_text(index) -- maybe we need a more private namespace + mp.print(outlinetexts[index] or "draw origin;") +end - implement { - name = "MPLIBconvertoutlinetext", - arguments = { "integer", "string", "integer" }, - actions = function(index,kind,box) - local boxtomp = fonts.metapost.boxtomp - if boxtomp then - outlinetexts[index] = boxtomp(box,kind) - else - outlinetexts[index] = "" - end - end - } - function mp.mf_get_outline_text(index) -- maybe we need a more private namespace - mp.print(outlinetexts[index] or "draw origin;") - end +-- definitions -end +appendaction(resetteractions, "system",ot_reset) +appendaction(resetteractions, "system",cl_reset) +appendaction(resetteractions, "system",tx_reset) --- mf_object=<string> +appendaction(processoractions,"system",ot_process) +appendaction(processoractions,"system",gr_process) -local p1 = P("mf_object=") -local p2 = lpeg.patterns.eol * p1 -local pattern = (1-p2)^0 * p2 + p1 +appendaction(analyzeractions, "system",ot_analyze) +appendaction(analyzeractions, "system",tx_analyze) +appendaction(analyzeractions, "system",gt_analyze) -function metapost.isobject(str) - return pattern and str ~= "" and lpegmatch(p,str) and true or false -end +appendaction(processoractions,"system",sh_process) +-- (processoractions,"system",gt_process) +appendaction(processoractions,"system",bm_process) +appendaction(processoractions,"system",tx_process) +appendaction(processoractions,"system",bx_process) +appendaction(processoractions,"system",ps_process) +appendaction(processoractions,"system",fg_process) +appendaction(processoractions,"system",tr_process) -- last, as color can be reset -local function installplugin(specification) - local reset = specification.reset - local process = specification.process - local object = specification.object - if reset then - appendaction(resetteractions,"system",reset) - end - if process then - appendaction(processoractions,"system",process) - end -end +appendaction(processoractions,"system",la_process) -metapost.installplugin = installplugin +-- function metapost.installplugin(reset,analyze,process) +-- if reset then +-- appendaction(resetteractions,"system",reset) +-- end +-- if analyze then +-- appendaction(analyzeractions,"system",analyze) +-- end +-- if process then +-- appendaction(processoractions,"system",process) +-- end +-- end --- definitions +-- we're nice and set them already -installplugin { name = "outline", reset = ot_reset, process = ot_process } -installplugin { name = "color", reset = cl_reset, process = cl_process } -installplugin { name = "text", reset = tx_reset, process = tx_process } -installplugin { name = "group", reset = gr_reset, process = gr_process } -installplugin { name = "graphictext", reset = gt_reset, process = gt_process } -installplugin { name = "shade", reset = sh_reset, process = sh_process } -installplugin { name = "bitmap", reset = bm_reset, process = bm_process } -installplugin { name = "box", reset = bx_reset, process = bx_process } -installplugin { name = "position", reset = ps_reset, process = ps_process } -installplugin { name = "figure", reset = fg_reset, process = fg_process } -installplugin { name = "layer", reset = la_reset, process = la_process } -installplugin { name = "transparency", reset = tr_reset, process = tr_process } +resetter = resetteractions .runner +analyzer = analyzeractions .runner +processor = processoractions.runner |