summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua
diff options
context:
space:
mode:
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.lua1151
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