diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-06-08 10:23:49 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2018-06-08 10:23:49 +0200 |
commit | 86bfea5faac983d15c47eec27f43ec56e75c69ef (patch) | |
tree | 69a37851a9b8beeb625110f4fc51ff1ef188d7e4 /tex | |
parent | c2d2236242c95f4753e7b197d576102c6fc20446 (diff) | |
download | context-86bfea5faac983d15c47eec27f43ec56e75c69ef.tar.gz |
2018-06-08 09:38:00
Diffstat (limited to 'tex')
31 files changed, 1185 insertions, 710 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index af2120f0b..970f0e887 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.06.04 12:18} +\newcontextversion{2018.06.08 09:31} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 4e05eedc2..0ffedca85 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2018.06.04 12:18} +\edef\contextversion{2018.06.08 09:31} %D For those who want to use this: diff --git a/tex/context/base/mkiv/chem-str.lua b/tex/context/base/mkiv/chem-str.lua index 7581a61d1..9f0738fc5 100644 --- a/tex/context/base/mkiv/chem-str.lua +++ b/tex/context/base/mkiv/chem-str.lua @@ -766,9 +766,6 @@ function chemistry.stop() if trace_metapost then report_chemistry("metapost code:\n%s", mpcode) end - if metapost.instance(chemistry.instance) then - f_initialize = nil - end metapost.graphic { instance = chemistry.instance, format = chemistry.format, @@ -776,7 +773,6 @@ function chemistry.stop() data = mpcode, definitions = f_initialize, } - t_initialize = "" metacode = nil end end diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index f423346b4..f8b9cff7f 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -1092,7 +1092,7 @@ implement { implement { name = "defineprocesscolordummy", actions = defineprocesscolor, - arguments = { "'d_u_m_m_y'", "string", false, false } + arguments = { "'c_o_l_o_r'", "string", false, false } } implement { diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv index 57cecfcad..7079322f7 100644 --- a/tex/context/base/mkiv/colo-ini.mkiv +++ b/tex/context/base/mkiv/colo-ini.mkiv @@ -782,7 +782,12 @@ % Since we couple definitions, we could stick to one test. Todo. Same for mpcolor. -\def\v_colo_dummy_name{d_u_m_m_y} +\def\v_colo_dummy_name{c_o_l_o_r} + +\letvalue{\??colorattribute \v_colo_dummy_name}\empty +\letvalue{\??transparencyattribute\v_colo_dummy_name}\empty +\letvalue{\??colorsetter \v_colo_dummy_name}\empty +\letvalue{\??transparencysetter \v_colo_dummy_name}\empty \letvalue{\??colorsetter -}\empty % used? \letvalue{\??transparencysetter-}\empty % used? @@ -942,7 +947,7 @@ \def\colo_basics_defined_and_activated#1% {\clf_defineprocesscolordummy{#1}% we could pass dummy here too - \colo_basics_synchronize{d_u_m_m_y}% + \colo_basics_synchronize{\v_colo_dummy_name}% \colo_helpers_activate_dummy} \def\colo_basics_define_process diff --git a/tex/context/base/mkiv/colo-run.lua b/tex/context/base/mkiv/colo-run.lua index 2e4cca5ab..2e7ae08e3 100644 --- a/tex/context/base/mkiv/colo-run.lua +++ b/tex/context/base/mkiv/colo-run.lua @@ -14,7 +14,7 @@ local commands = commands local context = context local colors = attributes.colors -local private = table.tohash { "d_u_m_m_y", "maintextcolor", "themaintextcolor" } +local private = table.tohash { "c_o_l_o_r", "maintextcolor", "themaintextcolor" } function commands.showcolorset(name) local set = colors.setlist(name) diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index a3c78b6ee..feb54e9ca 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.06.04 12:18} +\newcontextversion{2018.06.08 09:31} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 1ca9fd731..5202268c3 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,7 +42,7 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.06.04 12:18} +\edef\contextversion{2018.06.08 09:31} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index e875991e1..1fe4289b2 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -2583,7 +2583,7 @@ function readers.gdef(f,fontdata,specification) local format = readushort(f) if format == 1 then local nofsets = readushort(f) - local sets = readcardinal(f,nofsets,ulong) + local sets = readcardinaltable(f,nofsets,ulong) for i=1,nofsets do local offset = sets[i] if offset ~= 0 then diff --git a/tex/context/base/mkiv/meta-blb.lua b/tex/context/base/mkiv/meta-blb.lua index 202c2850b..957af16ca 100644 --- a/tex/context/base/mkiv/meta-blb.lua +++ b/tex/context/base/mkiv/meta-blb.lua @@ -178,6 +178,7 @@ interfaces.implement { -- the plug: + local function reset() blob_raw_reset() end @@ -187,12 +188,12 @@ local function analyze(object,prescript) end local function process(object,prescript,before,after) - if prescript.tb_stage == "inject" then +-- if prescript.tb_stage == "inject" then local tb_blob = tonumber(prescript.tb_blob) if tb_blob then before[#before+1] = injectblob(object,tb_blob) end - end +-- end end metapost.installplugin(reset,analyze,process) @@ -278,28 +279,64 @@ interfaces.implement { actions = initialize, } -local function reset() - -- nothing -end +local tb_reset, tb_analyze, tb_process do -local function analyze(object,prescript) - if prescript.ft_stage == "trial" then - local ft_category = tonumber(prescript.ft_category) - if ft_category then - newblob(ft_category,object.postscript) -- only for tracing - context.MPLIBfollowtext(ft_category,object.postscript) - metapost.getjobdata().multipass = true + if metapost.use_one_pass then + + local mp_category = 0 + local mp_str = "" + + function mp.InjectBlobB(category,str) + newblob(category,str) -- only for tracing + mp_category = category + mp_str = str + tex.runtoks("mpblobtext") end - end -end -local function process(object,prescript,before,after) - if prescript.ft_stage == "final" then - object.path = false - object.color = false - object.grouped = true - object.istext = true + interfaces.implement { + name = "mpblobtext", + actions = function() + context.MPLIBfollowtext(mp_category,mp_str) + end + } + + tb_process = function(object,prescript,before,after) + object.path = false + object.color = false + object.grouped = true + object.istext = true + end + + + else + + tb_reset = function() + -- nothing + end + + tb_analyze = function(object,prescript) + if prescript.ft_stage == "trial" then + local ft_category = tonumber(prescript.ft_category) + if ft_category then + newblob(ft_category,object.postscript) -- only for tracing + context.MPLIBfollowtext(ft_category,object.postscript) + metapost.getjobdata().multipass = true + end + end + end + + tb_process = function(object,prescript,before,after) + if prescript.ft_stage == "final" then + object.path = false + object.color = false + object.grouped = true + object.istext = true + end + end + + end + end -metapost.installplugin(reset,analyze,process) +metapost.installplugin(tb_reset,tb_analyze,tb_process) diff --git a/tex/context/base/mkiv/meta-blb.mkiv b/tex/context/base/mkiv/meta-blb.mkiv index 78e2dde3e..4a5381dfc 100644 --- a/tex/context/base/mkiv/meta-blb.mkiv +++ b/tex/context/base/mkiv/meta-blb.mkiv @@ -47,4 +47,10 @@ % \def\reversedtext#1% % {\cldcontext{table.concat(table.reverse(utf.totable(\!!bs#1\!!es)))}} +%D New: + +\newtoks\mpblobtext + +\mpblobtext{\global\setbox\mptextbox\vbox{\clf_mpblobtext}} + \protect \endinput diff --git a/tex/context/base/mkiv/meta-imp-dum.mkiv b/tex/context/base/mkiv/meta-imp-dum.mkiv index e6ccc234c..481afe82a 100644 --- a/tex/context/base/mkiv/meta-imp-dum.mkiv +++ b/tex/context/base/mkiv/meta-imp-dum.mkiv @@ -59,7 +59,7 @@ % clip currentpicture to p ; % \stopuseMPgraphic -\startuseMPgraphic{figure:placeholder}{width,height,reduction,color} +\startuseMPgraphic{minifun::figure:placeholder}{width,height,reduction,color} begingroup ; save w, h, d, r, p, c, b ; numeric w, h, d, r ; path p ; @@ -88,7 +88,7 @@ \defineoverlay [figure:placeholder:graphic] [\useMPgraphic - {figure:placeholder}% + {minifun::figure:placeholder}% {width=\figurewidth,% height=\figureheight,% reduction=\externalfigureparameter\c!reduction,% diff --git a/tex/context/base/mkiv/meta-imp-txt.mkiv b/tex/context/base/mkiv/meta-imp-txt.mkiv index 34e36ae54..2e950d5c8 100644 --- a/tex/context/base/mkiv/meta-imp-txt.mkiv +++ b/tex/context/base/mkiv/meta-imp-txt.mkiv @@ -202,6 +202,8 @@ \stopMPdefinitions \startluacode + local context = context + local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes @@ -217,10 +219,19 @@ local c_userkern = kerncodes.userkern local a_fontkern = attributes.private("fontkern") + local copynode = nodes.copy + local freenode = nodes.free + + local topoints = number.topoints + local mpprint = mp.print + local n = nil local s = 0 function mp.follow_reset() + for i=1,#n do + freenode(n[i]) + end n = nil s = 0 end @@ -251,19 +262,19 @@ end function mp.follow_size() - mp.print(s) + mpprint(s) end function mp.follow_slot(i) - mp.print('textext("\\getfollowtoken{' .. i .. '}")') + mpprint('textext("\\getfollowtoken{' .. i .. '}")') end function mp.follow_text(s) - context(n[s]) + context(copynode(n[s])) end function mp.follow_width(i) - mp.print(number.topoints(n[i].width)) + mpprint(topoints(n[i].width)) end \stopluacode diff --git a/tex/context/base/mkiv/meta-ini.mkiv b/tex/context/base/mkiv/meta-ini.mkiv index 00010f52a..63e9542b8 100644 --- a/tex/context/base/mkiv/meta-ini.mkiv +++ b/tex/context/base/mkiv/meta-ini.mkiv @@ -211,6 +211,7 @@ \def\currentMPformat {\currentMPinstance} \defineMPinstance[metafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] +\defineMPinstance[minifun] [\s!format=minifun] \defineMPinstance[extrafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] \defineMPinstance[lessfun] [\s!format=metafun] \defineMPinstance[doublefun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double] @@ -275,11 +276,13 @@ \endgroup} \def\meta_process_graphic_start - {\setbox\b_meta_graphic\hpack\bgroup} + {\pushMPboundingbox + \setbox\b_meta_graphic\hpack\bgroup} \def\meta_process_graphic_stop {\egroup - \meta_place_graphic} + \meta_place_graphic + \popMPboundingbox} \unexpanded\def\meta_process_graphic_instance#1% {\edef\currentMPinstance{#1}% @@ -785,11 +788,28 @@ \unexpanded\def\useMPgraphic {\dodoublegroupempty\meta_use_graphic} +% \def\meta_use_graphic#1#2% +% {\meta_begin_graphic_group{#1}% +% %\doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% +% \doifsomething{#2}{\setupMPvariables[#1][#2]}% +% \csname\??mpgraphic#1\endcsname\empty +% \meta_end_graphic_group} + \def\meta_use_graphic#1#2% {\meta_begin_graphic_group{#1}% -% \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% - \doifsomething{#2}{\setupMPvariables[#1][#2]}% - \csname\??mpgraphic#1\endcsname\empty + \ifcsname\??mpgraphic#1\endcsname + \edef\usedMPgraphicname{#1}% + \else\ifcsname\??mpgraphic\currentMPgraphicname\endcsname + \let\usedMPgraphicname\currentMPgraphicname + \else + \let\usedMPgraphicname\empty + \fi\fi + \ifx\usedMPgraphicname\empty + % message + \else + \doifsomething{#2}{\setupMPvariables[\usedMPgraphicname][#2]}% + \csname\??mpgraphic\usedMPgraphicname\endcsname + \fi \meta_end_graphic_group} \let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed diff --git a/tex/context/base/mkiv/mlib-ctx.lua b/tex/context/base/mkiv/mlib-ctx.lua index b51c4fd9d..74601cc8c 100644 --- a/tex/context/base/mkiv/mlib-ctx.lua +++ b/tex/context/base/mkiv/mlib-ctx.lua @@ -11,46 +11,29 @@ local format, concat = string.format, table.concat local settings_to_hash = utilities.parsers.settings_to_hash local formatters = string.formatters -local report_metapost = logs.reporter("metapost") +local report_metapost = logs.reporter ("metapost") +local status_metapost = logs.messenger("metapost") -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming -local mplib = mplib +local trace_graphic = false -metapost = metapost or { } -local metapost = metapost -local context = context +trackers.register("metapost.graphics", + function(v) trace_graphic = v end +); -local setters = tokens.setters -local setmacro = setters.macro -local implement = interfaces.implement +local mplib = mplib -local v_no = interfaces.variables.no +metapost = metapost or { } +local metapost = metapost +local context = context -metapost.defaultformat = "metafun" -metapost.defaultinstance = "metafun" -metapost.defaultmethod = "default" +local setters = tokens.setters +local setmacro = setters.macro +local implement = interfaces.implement -local function setmpsformat(specification) - local instance = specification.instance - local format = specification.format - local method = specification.method - if not instance or instance == "" then - instance = metapost.defaultinstance - specification.instance = instance - end - if not format or format == "" then - format = metapost.defaultformat - specification.format = format - end - if not method or method == "" then - method = metapost.defaultmethod - specification.method = method - end - specification.mpx = metapost.format(instance,format,method) - return specification -end +local v_no = interfaces.variables.no local extensiondata = metapost.extensiondata or storage.allocate { } metapost.extensiondata = extensiondata @@ -96,9 +79,6 @@ implement { arguments = "string" } -local report_metapost = logs.reporter ("metapost") -local status_metapost = logs.messenger("metapost") - local patterns = { "meta-imp-%s.mkiv", "meta-imp-%s.tex", @@ -192,7 +172,9 @@ implement { -- or just move the scanners to pps function metapost.graphic(specification) - metapost.graphic_base_pass(setmpsformat(specification)) + metapost.pushformat(specification) + metapost.graphic_base_pass(specification) + metapost.popformat() end function metapost.startgraphic(t) @@ -218,8 +200,10 @@ end function metapost.stopgraphic(t) if t then t.data = concat(t.data or { },"\n") + if trace_graphic then + report_metapost("\n"..t.data.."\n") + end metapost.graphic(t) - t.data = "" end end @@ -265,8 +249,7 @@ implement { } function metapost.getclippath(specification) -- why not a special instance for this - setmpsformat(specification) - local mpx = specification.mpx + local mpx = metapost.pushformat(specification) local data = specification.data or "" if mpx and data ~= "" then starttiming(metapost) @@ -285,7 +268,10 @@ function metapost.getclippath(specification) -- why not a special instance for t result = metapost.filterclippath(result) end stoptiming(metapost) + metapost.pushformat() return result + else + metapost.pushformat() end end diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index 60ad9477b..1faefa68e 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -12,9 +12,9 @@ if not modules then modules = { } end modules ['mlib-lua'] = { local type, tostring, select, loadstring = type, tostring, select, loadstring local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch +local concat, insert, remove = table.concat, table.insert, table.remove local formatters = string.formatters -local concat = table.concat local lpegmatch = lpeg.match local lpegpatterns = lpeg.patterns @@ -31,7 +31,10 @@ local be_tolerant = true directives.register("metapost.lua.tolerant",functi mp = mp or { } -- system namespace MP = MP or { } -- user namespace -local buffer, n, max = { }, 0, 10 -- we reuse upto max +local buffer = { } +local n = 0 +local max = 10 -- we reuse upto max +local nesting = 0 function mp._f_() if trace_enabled and trace_luarun then @@ -40,7 +43,7 @@ function mp._f_() buffer = { } end n = 0 - report_luarun("data: %s",result) + report_luarun("%i: data: %s",nesting,result) return result else if n == 0 then @@ -62,11 +65,17 @@ end local f_code = formatters["%s return mp._f_()"] -local f_numeric = formatters["%.16f"] local f_integer = formatters["%i"] -local f_pair = formatters["(%.16f,%.16f)"] -local f_triplet = formatters["(%.16f,%.16f,%.16f)"] -local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"] + +-- local f_numeric = formatters["%.16f"] +-- local f_pair = formatters["(%.16f,%.16f)"] +-- local f_triplet = formatters["(%.16f,%.16f,%.16f)"] +-- local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"] + +local f_numeric = formatters["%n"] +local f_pair = formatters["(%n,%n)"] +local f_triplet = formatters["(%n,%n,%n)"] +local f_quadruple = formatters["(%n,%n,%n,%n)"] local f_points = formatters["%p"] local f_pair_pt = formatters["(%p,%p)"] @@ -383,9 +392,11 @@ end -- end function metapost.runscript(code) + nesting = nesting + 1 + local trace = trace_enabled and trace_luarun if trace then - report_luarun("code: %s",code) + report_luarun("%i: code: %s",nesting,code) end runs = runs + 1 local f = loadstring(f_code(code)) @@ -393,6 +404,8 @@ function metapost.runscript(code) f = loadstring(code) end if f then + local _buffer_, _n_ = buffer, n + buffer, n = { }, 0 local result = f() if result then local t = type(result) @@ -402,53 +415,54 @@ function metapost.runscript(code) result = tostring(result) end if trace then - report_luarun("result: %s",result) + if #result == 0 then + report_luarun("%i: no result",nesting) + else + report_luarun("%i: result: %s",nesting,result) + end end + buffer, n = _buffer_, _n_ + nesting = nesting - 1 return result elseif trace then - report_luarun("no result") + report_luarun("%i: no result",nesting) end + buffer, n = _buffer_, _n_ else - report_luarun("no result, invalid code: %s",code) + report_luarun("%i: no result, invalid code: %s",nesting,code) end + + nesting = nesting - 1 return "" end --- function metapost.initializescriptrunner(mpx) --- mp.numeric = function(s) return mpx:get_numeric(s) end --- mp.string = function(s) return mpx:get_string (s) end --- mp.boolean = function(s) return mpx:get_boolean(s) end --- mp.number = mp.numeric --- end - -local get_numeric = mplib.get_numeric -local get_string = mplib.get_string -local get_boolean = mplib.get_boolean -local get_number = get_numeric +do --- function metapost.initializescriptrunner(mpx) --- mp.numeric = function(s) return get_numeric(mpx,s) end --- mp.string = function(s) return get_string (mpx,s) end --- mp.boolean = function(s) return get_boolean(mpx,s) end --- mp.number = mp.numeric --- end + local get_numeric = mplib.get_numeric + local get_string = mplib.get_string + local get_boolean = mplib.get_boolean + local get_number = get_numeric -local currentmpx = nil + local currentmpx = nil + local stack = { } + local getters = { } -local get = { } -mp.get = get + getters.numeric = function(s) return get_numeric(currentmpx,s) end + getters.string = function(s) return get_string (currentmpx,s) end + getters.boolean = function(s) return get_boolean(currentmpx,s) end + getters.number = mp.numeric -get.numeric = function(s) return get_numeric(currentmpx,s) end -get.string = function(s) return get_string (currentmpx,s) end -get.boolean = function(s) return get_boolean(currentmpx,s) end -get.number = mp.numeric + function metapost.pushscriptrunner(mpx) + insert(stack,mpx) + currentmpx = mpx + end -function metapost.initializescriptrunner(mpx,trialrun) - currentmpx = mpx - if trace_luarun then - report_luarun("type of run: %s", trialrun and "trial" or "final") + function metapost.popscriptrunner() + currentmpx = remove(stack,mpx) end - -- trace_enabled = not trialrun blocks too much + + mp.get = getters + end -- texts: diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua index 453d00aef..d93e1b879 100644 --- a/tex/context/base/mkiv/mlib-pdf.lua +++ b/tex/context/base/mkiv/mlib-pdf.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['mlib-pdf'] = { -- maybe %s is better than %f -local format, concat, gsub = string.format, table.concat, string.gsub +local gsub = string.gsub +local concat, insert, remove = table.concat, table.insert, table.remove local abs, sqrt, round = math.abs, math.sqrt, math.round local setmetatable, rawset, tostring, tonumber, type = setmetatable, rawset, tostring, tonumber, type local P, S, C, Ct, Cc, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Carg @@ -102,14 +103,14 @@ local function getobjects(result,figure,index) end end -function metapost.convert(result, trialrun, flusher, multipass, askedfig) +function metapost.convert(result, trialrun, flusher, multipass, askedfig, incontext) if trialrun then local multipassindeed = metapost.parse(result,askedfig) if multipass and not multipassindeed and metapost.optimize then if save_table then table.save(save_table,metapost.totable(result,1)) -- direct end - metapost.flush(result,flusher,askedfig) -- saves a run + metapost.flush(result,flusher,askedfig,incontext) -- saves a run else return false end @@ -117,7 +118,7 @@ function metapost.convert(result, trialrun, flusher, multipass, askedfig) if save_table then table.save(save_table,metapost.totable(result,1)) -- direct end - metapost.flush(result,flusher,askedfig) + metapost.flush(result,flusher,askedfig,incontext) end return true -- done end @@ -374,7 +375,9 @@ function metapost.processspecial(str) end end -local function setproperties(figure) +local stack = { } + +local function pushproperties(figure) local boundingbox = figure:boundingbox() local properties = { llx = boundingbox[1], @@ -388,15 +391,20 @@ local function setproperties(figure) italic = figure:italcorr(), number = figure:charcode() or 0, } + insert(stack,properties) metapost.properties = properties return properties end +local function popproperties() + metapost.properties = remove(stack) +end + local function nocomment() end metapost.comment = nocomment -function metapost.flush(result,flusher,askedfig) +function metapost.flush(result,flusher,askedfig,incontext) if result then local figures = result.fig if figures then @@ -413,7 +421,7 @@ function metapost.flush(result,flusher,askedfig) metapost.comment = flusher.comment or nocomment for index=1,#figures do local figure = figures[index] - local properties = setproperties(figure) + local properties = pushproperties(figure) if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then local objects = getobjects(result,figure,index) local result = { } @@ -427,217 +435,229 @@ function metapost.flush(result,flusher,askedfig) startfigure(properties.number,0,0,0,0,"invalid",figure) stopfigure() else - startfigure(properties.number,llx,lly,urx,ury,"begin",figure) - result[#result+1] = "q" - if objects then --- resetplugins(result) -- we should move the colorinitializer here - local savedpath = nil - local savedhtap = nil - for o=1,#objects do - local object = objects[o] - local objecttype = object.type - if objecttype == "text" then - result[#result+1] = "q" - local ot = object.transform -- 3,4,5,6,1,2 - result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot)) - flushfigure(result) -- flush accumulated literals - result = { } - textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) - result[#result+1] = "Q" - elseif objecttype == "special" then - if processspecial then - processspecial(object.prescript) - end - elseif objecttype == "start_clip" then - local evenodd = not object.istext and object.postscript == "evenodd" - result[#result+1] = "q" - flushnormalpath(object.path,result,false) - result[#result+1] = evenodd and "W* n" or "W n" - elseif objecttype == "stop_clip" then - result[#result+1] = "Q" - miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false - elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then - -- skip - else - -- we use an indirect table as we want to overload - -- entries but this is not possible in userdata - -- - -- can be optimized if no path - -- - local original = object - local object = { } - setmetatable(object, { - __index = original - }) - -- first we analyze - local before, after = processplugins(object) - local evenodd, collect, both = false, false, false - local postscript = object.postscript - if not object.istext then - if postscript == "evenodd" then - evenodd = true - elseif postscript == "collect" then - collect = true - elseif postscript == "both" then - both = true - elseif postscript == "eoboth" then - evenodd = true - both = true - end - end - -- - if collect then - if not savedpath then - savedpath = { object.path or false } - savedhtap = { object.htap or false } - else - savedpath[#savedpath+1] = object.path or false - savedhtap[#savedhtap+1] = object.htap or false + + -- we need to be indirect if we want the one-pass solution + + local function processfigure() + result[#result+1] = "q" + if objects then + -- resetplugins(result) -- we should move the colorinitializer here + local savedpath = nil + local savedhtap = nil + for o=1,#objects do + local object = objects[o] + local objecttype = object.type + if objecttype == "text" then + result[#result+1] = "q" + local ot = object.transform -- 3,4,5,6,1,2 + result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) + flushfigure(result) -- flush accumulated literals + result = { } + textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + result[#result+1] = "Q" + elseif objecttype == "special" then + if processspecial then + processspecial(object.prescript) end + elseif objecttype == "start_clip" then + local evenodd = not object.istext and object.postscript == "evenodd" + result[#result+1] = "q" + flushnormalpath(object.path,result,false) + result[#result+1] = evenodd and "W* n" or "W n" + elseif objecttype == "stop_clip" then + result[#result+1] = "Q" + miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false + elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then + -- skip else - local objecttype = object.type -- can have changed - if before then - result = pluginactions(before,result,flushfigure) - end - local ml = object.miterlimit - if ml and ml ~= miterlimit then - miterlimit = ml - result[#result+1] = f_M(ml) - end - local lj = object.linejoin - if lj and lj ~= linejoin then - linejoin = lj - result[#result+1] = f_j(lj) - end - local lc = object.linecap - if lc and lc ~= linecap then - linecap = lc - result[#result+1] = f_J(lc) + -- we use an indirect table as we want to overload + -- entries but this is not possible in userdata + -- + -- can be optimized if no path + -- + local original = object + local object = { } + setmetatable(object, { + __index = original + }) + -- first we analyze + local before, after = processplugins(object) + local evenodd, collect, both = false, false, false + local postscript = object.postscript + if not object.istext then + if postscript == "evenodd" then + evenodd = true + elseif postscript == "collect" then + collect = true + elseif postscript == "both" then + both = true + elseif postscript == "eoboth" then + evenodd = true + both = true + end end - if both then - if dashed ~= false then -- was just dashed test - result[#result+1] = "[] 0 d" - dashed = false + -- + if collect then + if not savedpath then + savedpath = { object.path or false } + savedhtap = { object.htap or false } + else + savedpath[#savedpath+1] = object.path or false + savedhtap[#savedhtap+1] = object.htap or false end else - local dl = object.dash - if dl then - local d = f_d(concat(dl.dashes or {}," "),dl.offset) - if d ~= dashed then - dashed = d - result[#result+1] = d - end - elseif dashed ~= false then -- was just dashed test - result[#result+1] = "[] 0 d" - dashed = false + local objecttype = object.type -- can have changed + if before then + result = pluginactions(before,result,flushfigure) end - end - local path = object.path -- newpath - local transformed, penwidth = false, 1 - local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" - local pen = object.pen - if pen then - if pen.type == 'elliptical' then - transformed, penwidth = pen_characteristics(original) -- boolean, value - result[#result+1] = f_w(penwidth) -- todo: only if changed - if objecttype == 'fill' then - objecttype = 'both' + local ml = object.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + result[#result+1] = f_M(ml) + end + local lj = object.linejoin + if lj and lj ~= linejoin then + linejoin = lj + result[#result+1] = f_j(lj) + end + local lc = object.linecap + if lc and lc ~= linecap then + linecap = lc + result[#result+1] = f_J(lc) + end + if both then + if dashed ~= false then -- was just dashed test + result[#result+1] = "[] 0 d" + dashed = false end - else -- calculated by mplib itself - objecttype = 'fill' - end - end - if transformed then - result[#result+1] = "q" - end - if path then - if savedpath then - for i=1,#savedpath do - local path = savedpath[i] - if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) + else + local dl = object.dash + if dl then + local d = f_d(concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + result[#result+1] = d end + elseif dashed ~= false then -- was just dashed test + result[#result+1] = "[] 0 d" + dashed = false end - savedpath = nil end - if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) - end - if force_stroke then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "fill" then - result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo - elseif objecttype == "outline" then - if both then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo - else - result[#result+1] = open and "S" or "h S" - end - elseif objecttype == "both" then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + local path = object.path -- newpath + local transformed, penwidth = false, 1 + local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" + local pen = object.pen + if pen then + if pen.type == 'elliptical' then + transformed, penwidth = pen_characteristics(original) -- boolean, value + result[#result+1] = f_w(penwidth) -- todo: only if changed + if objecttype == 'fill' then + objecttype = 'both' + end + else -- calculated by mplib itself + objecttype = 'fill' + end end - end - if transformed then - result[#result+1] = "Q" - end - local path = object.htap - if path then if transformed then result[#result+1] = "q" end - if savedhtap then - for i=1,#savedhtap do - local path = savedhtap[i] - if transformed then - flushconcatpath(path,result,open) + if path then + if savedpath then + for i=1,#savedpath do + local path = savedpath[i] + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + end + savedpath = nil + end + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then + result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo + elseif objecttype == "outline" then + if both then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo else - flushnormalpath(path,result,open) + result[#result+1] = open and "S" or "h S" end + elseif objecttype == "both" then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath end - savedhtap = nil - evenodd = true end if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) + result[#result+1] = "Q" end - if force_stroke then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "fill" then - result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo - elseif objecttype == "outline" then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "both" then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + local path = object.htap + if path then + if transformed then + result[#result+1] = "q" + end + if savedhtap then + for i=1,#savedhtap do + local path = savedhtap[i] + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + end + savedhtap = nil + evenodd = true + end + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then + result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo + elseif objecttype == "outline" then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "both" then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + end + if transformed then + result[#result+1] = "Q" + end end - if transformed then - result[#result+1] = "Q" + if after then + result = pluginactions(after,result,flushfigure) end end - if after then - result = pluginactions(after,result,flushfigure) + if object.grouped then + -- can be qQ'd so changes can end up in groups + miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false end end - if object.grouped then - -- can be qQ'd so changes can end up in groups - miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false - end end end + result[#result+1] = "Q" + flushfigure(result) + end + startfigure(properties.number,llx,lly,urx,ury,"begin",figure) + if incontext then + context(function() processfigure() end) + else + processfigure() end - result[#result+1] = "Q" - flushfigure(result) stopfigure("end") + end if askedfig ~= "all" then break end end + popproperties() end metapost.comment = nocomment resetplugins(result) -- we should move the colorinitializer here @@ -653,7 +673,7 @@ function metapost.parse(result,askedfig) local analyzeplugins = metapost.analyzeplugins -- each object for index=1,#figures do local figure = figures[index] - local properties = setproperties(figure) + local properties = pushproperties(figure) if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then local objects = getobjects(result,figure,index) if objects then @@ -667,6 +687,7 @@ function metapost.parse(result,askedfig) break end end + popproperties() end return multipass end diff --git a/tex/context/base/mkiv/mlib-pdf.mkiv b/tex/context/base/mkiv/mlib-pdf.mkiv index 147b67f74..6dc73a153 100644 --- a/tex/context/base/mkiv/mlib-pdf.mkiv +++ b/tex/context/base/mkiv/mlib-pdf.mkiv @@ -47,6 +47,18 @@ \global\MPurx \zeropoint \global\MPury \zeropoint} +\let\popMPboundingbox\relax + +\unexpanded\def\pushMPboundingbox + {\edef\popMPboundingbox + {\global\MPwidth \the\MPwidth + \global\MPheight\the\MPheight + \global\MPllx \the\MPllx + \global\MPlly \the\MPlly + \global\MPurx \the\MPurx + \global\MPury \the\MPury + \relax}} + \unexpanded\def\repositionMPboxindeed {\setbox\MPbox\hpack\bgroup \kern-\MPllx @@ -76,15 +88,15 @@ \wd\MPbox\MPwidth \ht\MPbox\MPheight} -\unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps) - {\begingroup - \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text - \MPllx-#4\onebasepoint - \MPlly-#5\onebasepoint - \repositionMPbox - \smashbox\MPbox - \box\MPbox - \endgroup} +% \unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps) +% {\begingroup +% \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text +% \MPllx-#4\onebasepoint +% \MPlly-#5\onebasepoint +% \repositionMPbox +% \smashbox\MPbox +% \box\MPbox +% \endgroup} % MPLIB specific: diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index 1a6aa5e86..db07cd7e4 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['mlib-pps'] = { } local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split -local tonumber, type, unpack, next = tonumber, type, unpack, next +local tonumber, type, unpack, next, select = tonumber, type, unpack, next, select 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 @@ -244,16 +244,18 @@ local function preset(t,k) return v end -local function startjob(plugmode) +local function startjob(plugmode,kind) + insert(stack,top) top = { - 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 + 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 } - insert(stack,top) if trace_runs then - report_metapost("starting run at level %i",#stack) + report_metapost("starting %s run at level %i in %s mode", + kind,#stack+1,plugmode and "plug" or "normal") end return top end @@ -261,16 +263,17 @@ end local function stopjob() if top then for slot, content in next, top.textexts do - flush_list(content) - if trace_textexts then - report_textexts("freeing text %s",slot) + if content then + flush_list(content) + if trace_textexts then + report_textexts("freeing text %s",slot) + end end end if trace_runs then - report_metapost("stopping run at level %i",#stack) + report_metapost("stopping run at level %i",#stack+1) end - remove(stack) - top = stack[#stack] + top = remove(stack) return top end end @@ -281,23 +284,49 @@ end -- end of new -local function settext(box,slot) - if top then - -- if trace_textexts then - -- report_textexts("getting text %s from box %s",slot,box) - -- end - top.textexts[slot] = textakebox(box) +local settext, gettext + +if metapost.use_one_pass then + + settext = function(box,slot,str) + if top then + -- if trace_textexts then + -- report_textexts("getting text %s from box %s",slot,box) + -- end + top.textexts[slot] = textakebox(box) + end end -end -local function gettext(box,slot) - if top then - -- 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 + gettext = function(box,slot) + if top then + texsetbox(box,top.textexts[slot]) + top.textexts[slot] = false + -- if trace_textexts then + -- report_textexts("putting text %s in box %s",slot,box) + -- end + end + end + +else + + settext = function(box,slot,str) + if top then + -- if trace_textexts then + -- report_textexts("getting text %s from box %s",slot,box) + -- end + top.textexts[slot] = textakebox(box) + end + end + + gettext = function(box,slot) + if top then + texsetbox(box,copy_list(top.textexts[slot])) + -- if trace_textexts then + -- report_textexts("putting text %s in box %s",slot,box) + -- end + end end + end metapost.settext = settext @@ -553,32 +582,7 @@ local do_begin_fig = "; beginfig(1) ; " local do_end_fig = "; endfig ;" local do_safeguard = ";" --- 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() +function metapost.preparetextextsdata() local textexts = top.textexts local collected = { } for k, data in sortedhash(top.texdata) do -- sort is nicer in trace @@ -595,11 +599,17 @@ function metapost.textextsdata() mp.tt_initialize(collected) end - metapost.intermediate = metapost.intermediate or { } metapost.intermediate.actions = metapost.intermediate.actions or { } -metapost.method = 1 -- 1:dumb 2:clever +metapost.method = 1 -- 1:dumb 2:clever 3:nothing + +if metapost.use_one_pass then + + metapost.method = 3 + checking_enabled = false + +end -- maybe we can latelua the texts some day @@ -626,11 +636,10 @@ local function extrapass() if trace_runs then report_metapost("second run of job %s, asked figure %a",top.nofruns,top.askedfig) end - local textexts = metapost.textextsdata() + metapost.preparetextextsdata() 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, @@ -639,7 +648,7 @@ local function extrapass() end function metapost.graphic_base_pass(specification) -- name will change (see mlib-ctx.lua) - local top = startjob(true) + local top = startjob(true,"base") -- local mpx = specification.mpx -- mandate local data = specification.data or "" @@ -683,7 +692,7 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib 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") + report_metapost("ignoring extra 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 @@ -710,7 +719,7 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib do_safeguard, data, wrappit and do_end_fig or "", - }, true, nil, not (forced_1 or forced_2 or forced_3), false, askedfig) + }, true, nil, not (forced_1 or forced_2 or forced_3), false, askedfig, true) if top.intermediate then for _, action in next, metapost.intermediate.actions do action() @@ -737,7 +746,7 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib do_safeguard, data, wrappit and do_end_fig or "", - }, false, nil, false, false, askedfig) + }, false, nil, false, false, askedfig, true) end context(stopjob) end @@ -745,7 +754,7 @@ end -- we overload metapost.process here function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, plugmode) -- overloads - startjob(plugmode) + startjob(plugmode,"process") processmetapost(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) stopjob() end @@ -829,17 +838,17 @@ 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 resetter = nil -local analyzer = nil -local processor = nil +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" } +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") @@ -847,10 +856,6 @@ 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 ) @@ -859,16 +864,16 @@ 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 + 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 -else - hash[h[1]] = h[2] -end - end if trace_scripts then report_scripts(table.serialize(hash,"prescript")) end @@ -972,178 +977,335 @@ end -- text -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=%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)) +local tx_reset, tx_analyze, 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 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) + 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 f_gray_yes = formatters["s=%n,a=%n,t=%n"] + local f_gray_nop = formatters["s=%n"] + local f_rgb_yes = formatters["r=%n,g=%n,b=%n,a=%n,t=%n"] + local f_rgb_nop = formatters["r=%n,g=%n,b=%n"] + local f_cmyk_yes = formatters["c=%n,m=%n,y=%n,k=%n,a=%n,t=%n"] + local f_cmyk_nop = formatters["c=%n,m=%n,y=%n,k=%n"] + + if metapost.use_one_pass then + + 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) + 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 + 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) + end + else + -- can't happen + ctx_MPLIBsetNtext(mp_target,mp_text) end end - if prescript.tx_type == "format" then - s = applyformat(s) + + function mp.SomeText(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) 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) + + function mp.SomeFormattedText(index,fmt,...) + local t = { } + for i=1,select("#",...) do + local ti = select(i,...) + if type(ti) ~= "table" then + t[#t+1] = ti + end end - 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) + local f = lpegmatch(cleaner,fmt) + local s = formatters[f](unpack(t)) or "" + mp.SomeText(index,s) + end + + interfaces.implement { + name = "mptexttoks", + actions = processtext, + } + + tx_reset = function() + if top then + top.texhash = { } + top.texlast = 0 end - else - 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 + + tx_process = function(object,prescript,before,after) + local data = top.texdata[metapost.properties.number] + local index = tonumber(prescript.tx_index) + if index then + 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 - 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) + mp_a = tonumber(prescript.tr_alternative) + mp_t = tonumber(prescript.tr_transparency) + -- + local mp_text = top.texstrings[mp_index] + local hash = fmt(mp_text,mp_a or "-",mp_t or "-",mp_c or "-") + local box = data.texhash[hash] + mp_index = index + mp_target = top.texlast - 1 + top.texlast = mp_target + if box then + box = copy_list(box) else - ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3]),s) + tex.runtoks("mptexttoks") + box = textakebox("mptextbox") + data.texhash[hash] = box 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) + top.textexts[mp_target] = box + -- + 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, + f_f(sx), -- bah ... %s no longer checks + f_f(rx), -- bah ... %s no longer checks + f_f(ry), -- bah ... %s no longer checks + f_f(sy), -- bah ... %s no longer checks + f_f(tx), -- bah ... %s no longer checks + f_f(ty), -- bah ... %s no longer checks + sxsy(box.width,box.height,box.depth)) + end else - ctx_MPLIBsetCtext(tx_last,f_cmyk_nop(c[1],c[2],c[3],c[4]),s) + before[#before+1] = function() + report_textexts("unknown %s",index) + end end - else - ctx_MPLIBsetNtext(tx_last,s) - end - 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) + if not trace_textexts then + object.path = false -- else: keep it + end + object.color = false + object.grouped = true + object.istext = true end end - 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) + + else + + local ctx_MPLIBsetNtext = context.MPLIBsetNtext + local ctx_MPLIBsetCtext = context.MPLIBsetCtext + local ctx_MPLIBsettext = context.MPLIBsettext + + tx_reset = function() + if top then + top.texhash = { } + top.texlast = 0 end end - end -end -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("stage %a, usage %a, number %a, use %a",tx_stage,tx_final,tx_number,n) - end - local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function - local box = top.textexts[n] - if box then - before[#before+1] = function() - -- 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 - f_f(sy), -- bah ... %s no longer checks - f_f(tx), -- bah ... %s no longer checks - f_f(ty), -- bah ... %s no longer checks - sxsy(box.width,box.height,box.depth)) + -- 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) + + tx_analyze = function(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 end - else - before[#before+1] = function() - report_textexts("unknown %s",tx_number) + 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 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 + 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 + 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 + end + 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 end - if not trace_textexts then - object.path = false -- else: keep it + end + + tx_process = function(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("stage %a, usage %a, number %a, use %a",tx_stage,tx_final,tx_number,n) + end + local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function + local box = top.textexts[n] + if box then + before[#before+1] = function() + -- 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 + f_f(sy), -- bah ... %s no longer checks + f_f(tx), -- bah ... %s no longer checks + f_f(ty), -- bah ... %s no longer checks + sxsy(box.width,box.height,box.depth)) + end + else + before[#before+1] = function() + report_textexts("unknown %s",tx_number) + end + end + if not trace_textexts then + object.path = false -- else: keep it + end + object.color = false + object.grouped = true + object.istext = true + end end - object.color = false - object.grouped = true - object.istext = true end + end + end -- we could probably redo normal textexts in the next way but as it's rather optimized @@ -1179,30 +1341,63 @@ end -- graphics (we use the given index because pictures can be reused) -local graphics = { } -function metapost.intermediate.actions.makempy() - if #graphics > 0 then - makempy.processgraphics(graphics) - graphics = { } -- ? could be gt_reset - end -end +local gt_reset, gt_analyze, gt_process do + + local graphics = { } + + if metapost.use_one_pass then + + local mp_index = 0 + local mp_str = "" + + function metapost.intermediate.actions.makempy() + end + + function mp.GraphicText(index,str) + if not graphics[index] then + mp_index = index + mp_str = str + tex.runtoks("mpgraphictexttoks") + end + end + + interfaces.implement { + name = "mpgraphictexttoks", + actions = function() + context.MPLIBgraphictext(mp_index,mp_str) + end, + } + + + else + + function metapost.intermediate.actions.makempy() + if #graphics > 0 then + makempy.processgraphics(graphics) + graphics = { } -- ? could be gt_reset + end + 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 -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 +end -- shades @@ -1516,10 +1711,6 @@ end -- groups -local types = { - isolated -} - local function gr_process(object,prescript,before,after) local gr_state = prescript.gr_state if not gr_state then @@ -1551,41 +1742,68 @@ end -- outlines -local outlinetexts = { } +local ot_reset, ot_analyze, ot_process do -local function ot_reset() - outlinetexts = { } -end + local outlinetexts = { } -- also in top data -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) + local function ot_reset() + outlinetexts = { } end -end -local function ot_process(object,prescript,before,after) -end + if metapost.use_one_pass then -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] = "" + local mp_index = 0 + local mp_kind = "" + local mp_str = "" + + function mp.OutlineText(index,str,kind) + if not outlinetexts[index] then + mp_index = index + mp_kind = kind + mp_str = str + tex.runtoks("mpoutlinetoks") + end + end + + interfaces.implement { + name = "mpoutlinetoks", + actions = function() + context.MPLIBoutlinetext(mp_index,mp_kind,mp_str) + end, + } + + else + + 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 + + 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.get_outline_text(index) -- maybe we need a more private namespace + mp.print(outlinetexts[index] or "draw origin;") end -} -function mp.get_outline_text(index) -- maybe we need a more private namespace - mp.print(outlinetexts[index] or "draw origin;") end -- definitions diff --git a/tex/context/base/mkiv/mlib-pps.mkiv b/tex/context/base/mkiv/mlib-pps.mkiv index c9d181bf9..bc4ce5a04 100644 --- a/tex/context/base/mkiv/mlib-pps.mkiv +++ b/tex/context/base/mkiv/mlib-pps.mkiv @@ -57,6 +57,23 @@ \let\MPLIBsettext\MPLIBsetNtext +\unexpanded\def\MPLIBsetNtextX#1% #2% box text + {\MPLIBflushenvironment + \hbox\bgroup % text + \meta_set_current_color + \let\MPLIBflushenvironment\doMPLIBflushenvironment + \let\next} + +\unexpanded\def\MPLIBsetCtextX#1#2% #3% box colorspec text + {\MPLIBflushenvironment + \hbox\bgroup % text + \directcolored[#2]% + \meta_set_current_color % so, textcolor wins ! + \let\MPLIBflushenvironment\doMPLIBflushenvironment + \let\next} + +\let\MPLIBsettextX\MPLIBsetNtextX + \unexpanded\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often {\clf_mpgettext\MPtextbox #1% \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}} @@ -185,4 +202,15 @@ \setbox\scratchbox\hpack\bgroup \unexpanded\def\MPLIBstopgroup{\doMPLIBstopgroup{#1}{#2}{#3}{#4}{#5}{#6}}} +% For now here ... will be cleaned up: + +\newtoks\mptexttoks +\newbox \mptextbox +\newtoks\mpoutlinetoks +\newtoks\mpgraphictexttoks + +\mptexttoks {\global\setbox\mptextbox\hbox{\clf_mptexttoks}} +\mpoutlinetoks {\global\setbox\mptextbox\vbox{\clf_mpoutlinetoks}} +\mpgraphictexttoks{\global\setbox\mptextbox\vbox{\clf_mpgraphictexttoks}} + \protect \endinput diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua index d1d76eb36..ae1c589e8 100644 --- a/tex/context/base/mkiv/mlib-run.lua +++ b/tex/context/base/mkiv/mlib-run.lua @@ -296,24 +296,52 @@ function metapost.unload(mpx) stoptiming(mplib) end -local mpxformats = { } +metapost.use_one_pass = LUATEXFUNCTIONALITY >= 6789 -- for a while + +metapost.defaultformat = "metafun" +metapost.defaultinstance = "metafun" +metapost.defaultmethod = "default" -function metapost.format(instance,name,method) +local mpxformats = { } +local nofformats = 0 + +function metapost.pushformat(specification,f,m) -- was: instance, name, method + if type(specification) ~= "table" then + specification = { + instance = specification, + format = f, + method = m, + } + end + local instance = specification.instance + local format = specification.format + local method = specification.method if not instance or instance == "" then - instance = "metafun" -- brrr + instance = metapost.defaultinstance + specification.instance = instance + end + if not format or format == "" then + format = metapost.defaultformat + specification.format = format end - name = name or instance + if not method or method == "" then + method = metapost.defaultmethod + specification.method = method + end + nofformats = nofformats + 1 + instance = instance .. ":" .. nofformats local mpx = mpxformats[instance] if not mpx then - report_metapost("initializing instance %a using format %a",instance,name) - mpx = metapost.checkformat(name,method) + report_metapost("initializing instance %a using format %a and method %a",instance,format,method) + mpx = metapost.checkformat(format,method) mpxformats[instance] = mpx end + specification.mpx = mpx return mpx end -function metapost.instance(instance) - return mpxformats[instance] +function metapost.popformat() + nofformats = nofformats - 1 end function metapost.reset(mpx) @@ -340,10 +368,6 @@ local mp_tag = 0 -- key/values -if not metapost.initializescriptrunner then - function metapost.initializescriptrunner() end -end - do local stack, top = { }, nil @@ -384,16 +408,18 @@ do end -function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) - local converted, result = false, { } - if type(mpx) == "string" then - mpx = metapost.format(mpx) -- goody +function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, incontext) + local converted = false + local result = { } + local mpxdone = type(mpx) == "string" + if mpxdone then + mpx = metapost.pushformat { instance = mpx, format = mpx } end if mpx and data then local tra = nil starttiming(metapost) - metapost.variables = { } - metapost.initializescriptrunner(mpx,trialrun) + metapost.variables = { } -- todo also push / pop + metapost.pushscriptrunner(mpx) if trace_graphics then tra = mp_tra[mpx] if not tra then @@ -466,7 +492,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end end if result.fig then - converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) + converted = metapost.convert(result, trialrun, flusher, multipass, askedfig, incontext) end end elseif i then @@ -496,6 +522,10 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, tra.log:write(banner) end stoptiming(metapost) + metapost.popscriptrunner(mpx) + end + if mpxdone then + metapost.popformat() end return converted, result end @@ -643,12 +673,13 @@ do } function metapost.simple(format,code) -- even less than metapost.quickcanddirty - local mpx = metapost.format(format or "metafun","metafun") + local mpx = metapost.pushformat { } -- takes defaults -- metapost.setoutercolor(2) metapost.process(mpx, { "beginfig(1);", code, "endfig;" }, false, flusher, false, false, 1, true -- last true is plugmode ! ) + metapost.popformat() if result then local stream = concat(result," ") result = nil -- cleanup diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 4455a50c6..c5a2850f3 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 6ddf8980f..ae98a0339 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/typo-dir.lua b/tex/context/base/mkiv/typo-dir.lua index e405a39e8..78b95117f 100644 --- a/tex/context/base/mkiv/typo-dir.lua +++ b/tex/context/base/mkiv/typo-dir.lua @@ -45,8 +45,9 @@ local band = bit32.band local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue -local getnext = nodes.getnext -local getattr = nodes.getattr +local nuts = nodes.nuts +local getnext = nuts.getnext +local getattr = nuts.getattr local enableaction = nodes.tasks.enableaction local tracers = nodes.tracers diff --git a/tex/context/base/mkiv/util-seq.lua b/tex/context/base/mkiv/util-seq.lua index 08f762b6a..4f4cd4a4d 100644 --- a/tex/context/base/mkiv/util-seq.lua +++ b/tex/context/base/mkiv/util-seq.lua @@ -99,120 +99,142 @@ function sequencers.new(t) -- was reset end function sequencers.prependgroup(t,group,where) - t = known[t] - if t then - local order = t.order - removevalue(order,group) - insertbeforevalue(order,where,group) - t.list[group] = { } - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + local order = t.order + removevalue(order,group) + insertbeforevalue(order,where,group) + t.list[group] = { } + t.dirty = true + t.runner = nil + end end end function sequencers.appendgroup(t,group,where) - t = known[t] - if t then - local order = t.order - removevalue(order,group) - insertaftervalue(order,where,group) - t.list[group] = { } - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + local order = t.order + removevalue(order,group) + insertaftervalue(order,where,group) + t.list[group] = { } + t.dirty = true + t.runner = nil + end end end function sequencers.prependaction(t,group,action,where,kind,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - insertbeforevalue(g,where,action) - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + insertbeforevalue(g,where,action) + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end end function sequencers.appendaction(t,group,action,where,kind,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - insertaftervalue(g,where,action) - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + insertaftervalue(g,where,action) + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end end function sequencers.enableaction(t,action) - t = known[t] - if t then - t.askip[action] = false - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.askip[action] = false + t.dirty = true + t.runner = nil + end end end function sequencers.disableaction(t,action) - t = known[t] - if t then - t.askip[action] = true - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.askip[action] = true + t.dirty = true + t.runner = nil + end end end function sequencers.enablegroup(t,group) - t = known[t] - if t then - t.gskip[action] = false - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + t.gskip[group] = false + t.dirty = true + t.runner = nil + end end end function sequencers.disablegroup(t,group) - t = known[t] - if t then - t.gskip[action] = true - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + t.gskip[group] = true + t.dirty = true + t.runner = nil + end end end function sequencers.setkind(t,action,kind) - t = known[t] - if t then - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end function sequencers.removeaction(t,group,action,force) - t = known[t] - local g = t and t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + local g = t and t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + t.dirty = true + t.runner = nil + end end end function sequencers.replaceaction(t,group,oldaction,newaction,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(oldaction)) then - replacevalue(g,oldaction,newaction) - t.dirty = true - t.runner = nil + if t and group and oldaction and newaction then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(oldaction)) then + replacevalue(g,oldaction,newaction) + t.dirty = true + t.runner = nil + end end end end diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua index 42f126687..5317da423 100644 --- a/tex/context/base/mkiv/util-str.lua +++ b/tex/context/base/mkiv/util-str.lua @@ -54,14 +54,47 @@ local whitespace = patterns.whitespace local spacer = patterns.spacer local spaceortab = patterns.spaceortab +-- local function points(n) +-- n = tonumber(n) +-- return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +-- end + +-- local function basepoints(n) +-- n = tonumber(n) +-- return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) +-- end + +local ptf = 1 / 65536 +local bpf = (7200/7227) / 65536 + local function points(n) + if n == 0 then + return "0pt" + end n = tonumber(n) - return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) + if not n or n == 0 then + return "0pt" + end + n = n * ptf + if n % 1 == 0 then + return format("%ipt",n) + end + return lpegmatch(stripper,format("%.5fpt",n)) end local function basepoints(n) + if n == 0 then + return "0pt" + end n = tonumber(n) - return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) + if not n or n == 0 then + return "0pt" + end + n = n * bpf + if n % 1 == 0 then + return format("%ibp",n) + end + return lpegmatch(stripper,format("%.5fbp",n)) end number.points = points @@ -874,7 +907,7 @@ local format_n = function() -- strips leading and trailing zeros and removes .0 return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end -local format_N = function() -- strips leading and trailing zeros (also accepst string) +local format_N = function() -- strips leading and trailing zeros (also accepts string) n = n + 1 return format("tostring(tonumber(a%s) or a%s)",n,n) end diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex ce9625ff7..6ddabb994 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 3d8a2a06f..d7c05d1c8 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/modules/mkiv/m-chart.lua b/tex/context/modules/mkiv/m-chart.lua index bcf80bdfc..cde563fb3 100644 --- a/tex/context/modules/mkiv/m-chart.lua +++ b/tex/context/modules/mkiv/m-chart.lua @@ -926,18 +926,16 @@ local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny) return chart end -local function makechart(chart) +local function makechart_indeed(chart) local settings = chart.settings local chartsettings = settings.chart -- - context.begingroup() - context.forgetall() - -- local g = ctx_startgraphic { instance = "metafun", format = "metafun", method = "scaled", definitions = "", + wrapped = true, } -- ctx_tographic(g,"if unknown context_flow : input mp-char.mpiv ; fi ;") @@ -1012,7 +1010,16 @@ local function makechart(chart) ctx_tographic(g,"flow_end_chart ;") ctx_stopgraphic(g) -- - context.endgroup() +end + +-- We need to wrap because of tex.runtoks! + +local function makechart(chart) + context.hbox() + context.bgroup() + context.forgetall() + context(function() makechart_indeed(chart) end) + context.egroup() end local function splitchart(chart) diff --git a/tex/context/modules/mkiv/m-chart.mkvi b/tex/context/modules/mkiv/m-chart.mkvi index 0463e4acd..4c5ea7e02 100644 --- a/tex/context/modules/mkiv/m-chart.mkvi +++ b/tex/context/modules/mkiv/m-chart.mkvi @@ -185,11 +185,14 @@ {\dodoubleempty\module_charts_process} \def\module_charts_process[#name][#settings]% - {\bgroup % \vbox removed +% {\hpack\bgroup % \vbox removed, \hpack prevents issues with tex.runtoks + {\bgroup % \vbox removed, \hpack prevents issues with tex.runtoks \insidefloattrue \dontcomplain \setupFLOWchart[#settings]% \usebodyfontparameter\FLOWchartparameter +% \meta_process_graphic_start +% \meta_start_current_graphic \clf_flow_make_chart chart { name {#name} @@ -248,6 +251,8 @@ after {} } \relax +% \meta_stop_current_graphic +% \meta_process_graphic_stop \egroup} \unexpanded\def\FLOWcharts diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 05acd5ede..0889d7777 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 06/04/18 12:18:30 +-- merge date : 06/08/18 09:31:24 do -- begin closure to overcome local limits and interference @@ -3814,13 +3814,35 @@ local endofstring=patterns.endofstring local whitespace=patterns.whitespace local spacer=patterns.spacer local spaceortab=patterns.spaceortab +local ptf=1/65536 +local bpf=(7200/7227)/65536 local function points(n) + if n==0 then + return "0pt" + end n=tonumber(n) - return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) + if not n or n==0 then + return "0pt" + end + n=n*ptf + if n%1==0 then + return format("%ipt",n) + end + return lpegmatch(stripper,format("%.5fpt",n)) end local function basepoints(n) + if n==0 then + return "0pt" + end n=tonumber(n) - return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536)) + if not n or n==0 then + return "0pt" + end + n=n*bpf + if n%1==0 then + return format("%ibp",n) + end + return lpegmatch(stripper,format("%.5fbp",n)) end number.points=points number.basepoints=basepoints @@ -18254,7 +18276,7 @@ function readers.gdef(f,fontdata,specification) local format=readushort(f) if format==1 then local nofsets=readushort(f) - local sets=readcardinal(f,nofsets,ulong) + local sets=readcardinaltable(f,nofsets,ulong) for i=1,nofsets do local offset=sets[i] if offset~=0 then |