diff options
Diffstat (limited to 'tex')
40 files changed, 994 insertions, 331 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index e19a3dfbb..ba4e48db1 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{2019.06.20 18:47} +\newcontextversion{2019.07.04 12:29} %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 4a72dae8b..0caeb26a7 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{2019.06.20 18:47} +\edef\contextversion{2019.07.04 12:29} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii index 902bd5445..23345c05c 100644 --- a/tex/context/base/mkii/mult-cs.mkii +++ b/tex/context/base/mkii/mult-cs.mkii @@ -731,6 +731,7 @@ \setinterfaceconstant{component}{component} \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{compress} +\setinterfaceconstant{compressdistance}{compressdistance} \setinterfaceconstant{compressseparator}{compressseparator} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 45a9ded24..d52003728 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -731,6 +731,7 @@ \setinterfaceconstant{component}{component} \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{compress} +\setinterfaceconstant{compressdistance}{compressdistance} \setinterfaceconstant{compressseparator}{compressseparator} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index fe387aa1a..2bbf93141 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -570,6 +570,7 @@ \setinterfacevariable{temporary}{temporaneo} \setinterfacevariable{test}{test} \setinterfacevariable{text}{testo} +\setinterfacevariable{textnote}{textnote} \setinterfacevariable{three}{tre} \setinterfacevariable{thursday}{giovedi} \setinterfacevariable{tight}{tight} @@ -730,6 +731,7 @@ \setinterfaceconstant{component}{component} \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{compress} +\setinterfaceconstant{compressdistance}{compressdistance} \setinterfaceconstant{compressseparator}{compressseparator} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index d2efcd7e9..0b121d288 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -731,6 +731,7 @@ \setinterfaceconstant{component}{مولفه} \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{فشردن} +\setinterfaceconstant{compressdistance}{compressdistance} \setinterfaceconstant{compressseparator}{compressseparator} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua index 0778ced4e..ff4f5e3b1 100644 --- a/tex/context/base/mkiv/cldf-ini.lua +++ b/tex/context/base/mkiv/cldf-ini.lua @@ -326,6 +326,39 @@ end setmetatablecall(knownfunctions,function(t,n) return knownfunctions[n](n) end) +-- some protection + +do + + local stub = { } + local done = false + local message = function() + -- one time message + if not done then + report_cld("") + report_cld("use : slot = context.functions.register(f)") + report_cld("and : context.functions.unregister(slot)") + report_cld("") + done = true + end + end + + setmetatable(stub, { + __index = message, + __newindex = message, + }) + + function lua.getfunctionstable() + message() + return stub + end + + lua.get_functions_table = lua.getfunctionstable + +end + +-- so far + -- The next hack is a convenient way to define scanners at the Lua end and -- get them available at the TeX end. There is some dirty magic needed to -- prevent overload during format loading. diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index dbf340dc5..428ff4f95 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2019.06.20 18:47} +\newcontextversion{2019.07.04 12:29} %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 2d0bf8881..26a46a8bc 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2019.06.20 18:47} +\edef\contextversion{2019.07.04 12:29} \edef\contextkind {beta} %D Kind of special: diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index 2d528728a..02cf6093c 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -3252,3 +3252,8 @@ function fonts.helpers.collectanchors(tfmdata) return anchors end + +if CONTEXTLMTXMODE > 0 then + fonts.constructors.addtounicode = false + fonts.constructors.autocleanup = false +end diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index b8be2ec75..2e7878d3d 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -836,8 +836,8 @@ local function inject_positions_only(head,where) if replace then -- error, we expect an empty one else ---KE setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern - replace = fontkern(rightkern) -- maybe also leftkern --KE + -- KE setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern + replace = fontkern(rightkern) -- maybe also leftkern done = true --KE end end diff --git a/tex/context/base/mkiv/l-string.lua b/tex/context/base/mkiv/l-string.lua index 8ae8d8d1d..1dee85e28 100644 --- a/tex/context/base/mkiv/l-string.lua +++ b/tex/context/base/mkiv/l-string.lua @@ -155,11 +155,13 @@ end --- needs checking local anything = patterns.anything -local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ? -local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ? -local matchescapes = Cc(".") * S("*?") -- wildcard and single match +local moreescapes = Cc("%") * S(".-+%?()[]*$^{}") +local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ? +local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ? +local matchescapes = Cc(".") * S("*?") -- wildcard and single match -local pattern_a = Cs ( ( allescapes + anything )^0 ) +local pattern_m = Cs ( ( moreescapes + anything )^0 ) +local pattern_a = Cs ( ( allescapes + anything )^0 ) local pattern_b = Cs ( ( someescapes + matchescapes + anything )^0 ) local pattern_c = Cs ( Cc("^") * ( someescapes + matchescapes + anything )^0 * Cc("$") ) @@ -170,6 +172,8 @@ end function string.topattern(str,lowercase,strict) if str == "" or type(str) ~= "string" then return ".*" + elseif strict == "all" then + str = lpegmatch(pattern_m,str) elseif strict then str = lpegmatch(pattern_c,str) else diff --git a/tex/context/base/mkiv/lpdf-emb.lua b/tex/context/base/mkiv/lpdf-emb.lua index 5255eb038..88b323a3f 100644 --- a/tex/context/base/mkiv/lpdf-emb.lua +++ b/tex/context/base/mkiv/lpdf-emb.lua @@ -1848,10 +1848,6 @@ statistics.register("font embedding time",function() end end) -updaters.register("backend.update.pdf",function() - fonts.constructors.addtounicode = false -end) - -- this is temporary local done = false diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua index 0c6f1f3e4..25a73fe67 100644 --- a/tex/context/base/mkiv/lpdf-lmt.lua +++ b/tex/context/base/mkiv/lpdf-lmt.lua @@ -2350,9 +2350,7 @@ do luatex.registerpageactions(1,function() lpdf.finalizepage(true) end) - -- - fonts.constructors.autocleanup = false - -- + -- -- lpdf.registerdocumentfinalizer(wrapup,nil,"wrapping up") end -- diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua index 112972d8f..29b5cbd7e 100644 --- a/tex/context/base/mkiv/math-noa.lua +++ b/tex/context/base/mkiv/math-noa.lua @@ -835,8 +835,8 @@ do if chr == dummyfencechar then chr = 0 end - setfield(d,"small_char",chr) - setfield(d,"small_fam",fam) + setchar(d,chr) + setfam(d,fam) flush_node(sym) end setattrlist(d,char) @@ -847,73 +847,61 @@ do return f end - -- will become +-- local function show(where,pointer) +-- print("") +-- local i = 0 +-- for n in nuts.traverse(pointer) do +-- i = i + 1 +-- print(i,where,nuts.tonode(n)) +-- end +-- print("") +-- end - -- local function makefence(what,char) - -- local d = new_delimiter() -- todo: attr - -- local f = new_fence() -- todo: attr - -- if char then - -- local sym = getnucleus(char) - -- local chr = getchar(sym) - -- local fam = getfam(sym) - -- if chr == dummyfencechar then - -- chr = 0 - -- end - -- setchar(d,chr) - -- setfam(d,fam) - -- flush_node(sym) - -- end - -- setsubtype(f,what) - -- setfield(f,"delim",d) - -- setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what] - -- return f - -- end - - local function makelist(noad,f_o,o_next,c_prev,f_c,middle) + local function makelist(middle, noad, f_o,o_next,c_prev,f_c) local list = new_submlist() - setlist(list,f_o) setsubtype(noad,innernoad_code) setnucleus(noad,list) - setlink(f_o,o_next) - setlink(c_prev,f_c) + setlist(list,f_o) + setlink(f_o,o_next) -- prev of list is nil + setlink(c_prev,f_c) -- next of list is nil if middle and next(middle) then local prev = f_o local current = o_next while current ~= f_c do - local m = middle[current] - if m then - local next = getnext(current) + local midl = middle[current] + local next = getnext(current) + if midl then local fence = makefence(middlefence_code,current) setnucleus(current) flush_node(current) middle[current] = nil -- replace_node setlink(prev,fence,next) - prev = fence - current = next + prev = fence else prev = current - current = getnext(current) end + current = next end end + return noad end + -- relinking is not somewhat overdone + local function convert_both(open,close,middle) local o_prev, o_next = getboth(open) - local c_prev, c_next = getboth(close) if o_next == close then return close else + local c_prev, c_next = getboth(close) local f_o = makefence(leftfence_code,open) local f_c = makefence(rightfence_code,close) - makelist(open,f_o,o_next,c_prev,f_c,middle) + makelist(middle, open, f_o,o_next,c_prev,f_c) setnucleus(close) flush_node(close) - if c_next then - setprev(c_next,open) - end - setnext(open,c_next) + -- open is now a list + setlink(open,c_next) return open end end @@ -923,24 +911,29 @@ do local f_c = makefence(rightfence_code) local o_prev, o_next = getboth(open) local l_prev, l_next = getboth(last) - makelist(open,f_o,o_next,last,f_c,middle) - if l_next then - setprev(l_next,open) - end - setnext(open,l_next) + makelist(middle, open, f_o,o_next,l_prev,f_c) + -- open is now a list + setlink(open,l_next) return open end - local function convert_close(close,first,middle) + local function convert_close(first,close,middle) local f_o = makefence(leftfence_code) local f_c = makefence(rightfence_code,close) - local c_prev = getprev(close) - makelist(close,f_o,first,c_prev,f_c,middle) + local c_prev, c_next = getboth(close) + local f_prev, f_next = getboth(first) + makelist(middle, close, f_o,f_next,c_prev,f_c) + -- close is now a list + if c_prev ~= first then + setlink(first,close) + end return close end local stacks = setmetatableindex("table") + -- 1=open 2=close 3=middle 4=both + local function processfences(pointer,n,parent) local current = pointer local last = pointer @@ -950,47 +943,75 @@ do local stack = nil local middle = nil -- todo: use properties while current do +-- show("before",pointer) local id = getid(current) if id == noad_code then local a = getattr(current,a_autofence) if a and a > 0 then local stack = stacks[n] - setattr(current,a_autofence,0) - if a == 1 or (a == 4 and (not stack or #stack == 0)) then + setattr(current,a_autofence,0) -- hm, better use a property + local level = #stack + if a == 1 then if trace_fences then - report_fences("%2i: pushing open on stack",n) + report_fences("%2i: level %i, handling %s, action %s",n,level,"open","open") end insert(stack,current) - elseif a == 2 or a == 4 then + elseif a == 2 then local open = remove(stack) if open then if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"both",#stack+1) + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","both") end current = convert_both(open,current,middle) elseif current == start then - -- skip + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","skip") + end else if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"close",#stack+1) + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","close") end - current = convert_close(current,initial,middle) + current = convert_close(initial,current,middle) if not parent then initial = current end end - if trace_fences then - report_fences("%2i: popping close from stack",n) - end elseif a == 3 then if trace_fences then - report_fences("%2i: registering middle",n) + report_fences("%2i: level %i, handling %s, action %s",n,level,"middle","middle") end if middle then middle[current] = last else middle = { [current] = last } end + elseif a == 4 then + if not stack or #stack == 0 then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","open") + end + insert(stack,current) + else + local open = remove(stack) + if open then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","both") + end + current = convert_both(open,current,middle) + elseif current == start then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","skip") + end + else + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","close") + end + current = convert_close(initial,current,middle) + if not parent then + initial = current + end + end + end end done = true else @@ -1000,6 +1021,7 @@ do -- next at current level processstep(current,processfences,n,id) end +-- show("after",pointer) last = current current = getnext(current) end @@ -1007,13 +1029,10 @@ do local stack = stacks[n] local s = #stack if s > 0 then - if trace_fences then - report_fences("%2i: handling %s stack levels",n,s) - end for i=1,s do local open = remove(stack) if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"open",#stack) + report_fences("%2i: level %i, handling %s, action %s",#stack,"flush","open") end last = convert_open(open,last,middle) end diff --git a/tex/context/base/mkiv/mlib-ctx.mkiv b/tex/context/base/mkiv/mlib-ctx.mkiv index 1f05b6ef8..21d211c1b 100644 --- a/tex/context/base/mkiv/mlib-ctx.mkiv +++ b/tex/context/base/mkiv/mlib-ctx.mkiv @@ -19,7 +19,15 @@ \registerctxluafile{mlib-run}{} \registerctxluafile{mlib-ctx}{} \registerctxluafile{mlib-lua}{} -\registerctxluafile{mlib-int}{} % here ? + +\doifelsefileexists{mlib-scn.lua} { + \registerctxluafile{mlib-scn}{} +} { + % experimental code for Alan and me +} + +\registerctxluafile{mlib-lmp}{} +\registerctxluafile{mlib-int}{} \unprotect diff --git a/tex/context/base/mkiv/mlib-lmp.lua b/tex/context/base/mkiv/mlib-lmp.lua new file mode 100644 index 000000000..292265be1 --- /dev/null +++ b/tex/context/base/mkiv/mlib-lmp.lua @@ -0,0 +1,137 @@ +if not modules then modules = { } end modules ['mlib-lmp'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local get = mp.get +local aux = mp.aux +local scan = mp.scan + +local mpnumeric = aux.numeric +local mppair = aux.pair +local mpquoted = aux.quoted + +local scannumber = scan.number +local scanpath = scan.path + +local registerscript = metapost.registerscript + +do + + -- todo: use a stack? + + local p = nil + local n = 0 + + local function mf_path_reset() + p = nil + n = 0 + end + + if CONTEXTLMTXMODE > 0 then + + local function mf_path_length() + p = scanpath() + n = p and #p or 1 + mpnumeric(n) + end + + local function mf_path_point() + local i = scannumber() + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[1],pi[2]) + end + end + + local function mf_path_left() + local i = scannumber() + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[5],pi[6]) + end + end + + local function mf_path_right() + local i = scannumber() + if i > 0 and i <= n then + local pn + if i == 1 then + pn = p[2] or p[1] + else + pn = p[i+1] or p[1] + end + mppair(pn[3],pn[4]) + end + end + + registerscript("pathreset", mf_path_reset) + registerscript("pathlengthof", mf_path_length) + registerscript("pathpointof", mf_path_point) + registerscript("pathleftof", mf_path_left) + registerscript("pathrightof", mf_path_right) + + else + + local mpgetpath = get.path + + local function mf_path_length(name) + p = mpgetpath(name) + n = p and #p or 0 + mpnumeric(n) + end + + local function mf_path_point(i) + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[1],pi[2]) + end + end + + local function mf_path_left(i) + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[5],pi[6]) + end + end + + local function mf_path_right(i) + if i > 0 and i <= n then + local pn + if i == 1 then + pn = p[2] or p[1] + else + pn = p[i+1] or p[1] + end + mppair(pn[3],pn[4]) + end + end + + mp.mf_path_length = mf_path_length mp.pathlength = mf_path_length + mp.mf_path_point = mf_path_point mp.pathpoint = mf_path_point + mp.mf_path_left = mf_path_left mp.pathleft = mf_path_left + mp.mf_path_right = mf_path_right mp.pathright = mf_path_right + mp.mf_path_reset = mf_path_reset mp.pathreset = mf_path_reset + + end + +end + +do + + -- if needed we can optimize the sub (cache last split) + + local utflen, utfsub = utf.len, utf.sub + + function mp.utflen(s) + mpnumeric(utflen(s)) + end + + function mp.utfsub(s,f,t) + mpquoted(utfsub(s,f,t or f)) + end + +end diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index b205946f9..3b08eb79a 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -21,6 +21,7 @@ local lpegpatterns = lpeg.patterns local P, S, Ct, Cs, Cc, C = lpeg.P, lpeg.S, lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.C local report_luarun = logs.reporter("metapost","lua") +local report_script = logs.reporter("metapost","script") local report_message = logs.reporter("metapost") local trace_luarun = false trackers.register("metapost.lua",function(v) trace_luarun = v end) @@ -28,12 +29,13 @@ local trace_enabled = true local be_tolerant = true directives.register("metapost.lua.tolerant", function(v) be_tolerant = v end) -local get, set, aux = { }, { }, { } +local get, set, aux, scan = { }, { }, { }, { } mp = mp or { -- system namespace - set = set, - get = get, - aux = aux, + set = set, + get = get, + aux = aux, + scan = scan, } MP = MP or { -- user namespace @@ -56,22 +58,50 @@ table.setmetatablecall(MP,function(t,k,...) return t[k](...) end) do - local currentmpx = nil - local stack = { } + local currentmpx = nil + local stack = { } local get_numeric = mplib.get_numeric local get_string = mplib.get_string local get_boolean = mplib.get_boolean local get_path = mplib.get_path - local set_path = mplib.set_path get.numeric = function(s) return get_numeric(currentmpx,s) end + get.number = 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.path = function(s) return get_path (currentmpx,s) end - get.number = function(s) return get_numeric(currentmpx,s) end - set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet + local set_path = mplib.set_path + + set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet + + local scan_next = mplib.scan_next + local scan_expression = mplib.scan_expression + local scan_token = mplib.scan_token + local scan_symbol = mplib.scan_symbol + local scan_numeric = mplib.scan_numeric + local scan_boolean = mplib.scan_boolean + local scan_string = mplib.scan_string + local scan_pair = mplib.scan_pair + local scan_color = mplib.scan_color + local scan_cmykcolor = mplib.scan_cmykcolor + local scan_transform = mplib.scan_transform + local scan_path = mplib.scan_path + + scan.next = function(k) return scan_next (currentmpx,k) end + scan.expression = function(k) return scan_expression(currentmpx,k) end + scan.token = function(k) return scan_token (currentmpx,k) end + scan.symbol = function(k) return scan_symbol (currentmpx,k) end + scan.numeric = function() return scan_numeric (currentmpx) end + scan.number = function() return scan_numeric (currentmpx) end + scan.boolean = function() return scan_boolean (currentmpx) end + scan.string = function() return scan_string (currentmpx) end + scan.pair = function(t) return scan_pair (currentmpx,t) end + scan.color = function(t) return scan_color (currentmpx,t) end + scan.cmykcolor = function(t) return scan_cmykcolor (currentmpx,t) end + scan.transform = function(t) return scan_transform (currentmpx,t) end + scan.path = function(t) return scan_path (currentmpx,t) end function metapost.pushscriptrunner(mpx) insert(stack,mpx) @@ -86,7 +116,6 @@ do return currentmpx end - end do @@ -101,14 +130,14 @@ do if trace_enabled and trace_luarun then local result = concat(buffer," ",1,n) if n > max then - buffer = { } + buffer = { } -- newtable(20,0) end n = 0 report_luarun("%i: data: %s",nesting,result) return result else if n == 0 then - return "" + return "" -- can be nil end local result if n == 1 then @@ -117,7 +146,7 @@ do result = concat(buffer," ",1,n) end if n > max then - buffer = { } + buffer = { } -- newtable(20,0) end n = 0 return result @@ -464,31 +493,67 @@ do local cache = table.makeweak() + local runscripts = { } + local runnames = { } + local nofscripts = 0 + + function metapost.registerscript(name,f) + nofscripts = nofscripts + 1 + if f then + runscripts[nofscripts] = f + runnames[name] = nofscripts + else + runscripts[nofscripts] = name + end + return nofscripts + end + + function metapost.scriptindex(name) + return runnames[name] or 0 + end + function metapost.runscript(code) nesting = nesting + 1 + local index = type(code) == "number" local trace = trace_enabled and trace_luarun - if trace then - report_luarun("%i: code: %s",nesting,code) - end runs = runs + 1 - local f = cache[code] - if not f then - f = loadstring(code .. " return mp._f_()") - if f then - cache[code] = f - elseif be_tolerant then - f = loadstring(code) + local f + if index then + f = runscripts[code] + if not f then + report_luarun("%i: bad index: %s",nesting,code) + elseif trace then + report_luarun("%i: index: %i",nesting,code) + end + else + if trace then + report_luarun("%i: code: %s",nesting,code) + end + f = cache[code] + if not f then + f = loadstring(code .. " return mp._f_()") if f then cache[code] = f + elseif be_tolerant then + f = loadstring(code) + if f then + cache[code] = f + end end end end + + -- returning nil is more efficient and a signel not to scan in mp + if f then local _buffer_ = buffer local _n_ = n buffer = { } n = 0 local result = f() + if index and not result then + result = _f_() + end if result then local t = type(result) if t == "number" then @@ -526,13 +591,45 @@ end do + -- Another experimental feature: + + local mpnumeric = mp.numeric + local scanstring = scan.string + local scriptindex = metapost.scriptindex + + function mp.mf_script_index(name) + local index = scriptindex(name) + -- report_script("method %i, name %a, index %i",1,name,index) + mpnumeric(index) + end + + -- once bootstrapped ... (needs pushed mpx instances) + + metapost.registerscript("scriptindex",function() + local name = scanstring() + local index = scriptindex(name) + -- report_script("method %i, name %a, index %i",2,name,index) + mpnumeric(index) + end) + +end + +-- the next will move to mlib-lmp.lua + +do + local mpnamedcolor = attributes.colors.mpnamedcolor local mpprint = aux.print + local scanstring = scan.string mp.mf_named_color = function(str) mpprint(mpnamedcolor(str)) end + metapost.registerscript("namedcolor",function() + mpprint(mpnamedcolor(scanstring())) + end) + end function mp.n(t) -- used ? @@ -978,76 +1075,3 @@ do end end - -do - - local mpnumeric = aux.numeric - local mppair = aux.pair - local mpgetpath = get.path - - local p = nil - local n = 0 - - local function mf_path_length(name) - p = mpgetpath(name) - n = p and #p or 0 - mpnumeric(n) - end - - local function mf_path_point(i) - if i > 0 and i <= n then - local pi = p[i] - mppair(pi[1],pi[2]) - end - end - - local function mf_path_left(i) - if i > 0 and i <= n then - local pi = p[i] - mppair(pi[5],pi[6]) - end - end - - local function mf_path_right(i) - if i > 0 and i <= n then - local pn - if i == 1 then - pn = p[2] or p[1] - else - pn = p[i+1] or p[1] - end - mppair(pn[3],pn[4]) - end - end - - local function mf_path_reset() - p = nil - n = 0 - end - - mp.mf_path_length = mf_path_length mp.pathlength = mf_path_length - mp.mf_path_point = mf_path_point mp.pathpoint = mf_path_point - mp.mf_path_left = mf_path_left mp.pathleft = mf_path_left - mp.mf_path_right = mf_path_right mp.pathright = mf_path_right - mp.mf_path_reset = mf_path_reset mp.pathreset = mf_path_reset - -end - -do - - -- if needed we can optimize the sub (cache last split) - - local utflen, utfsub = utf.len, utf.sub - - local mpnumeric = aux.numeric - local mpquoted = aux.quoted - - function mp.utflen(s) - mpnumeric(utflen(s)) - end - - function mp.utfsub(s,f,t) - mpquoted(utfsub(s,f,t or f)) - end - -end diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua index bd4818659..0118f6cbd 100644 --- a/tex/context/base/mkiv/mlib-run.lua +++ b/tex/context/base/mkiv/mlib-run.lua @@ -6,8 +6,6 @@ if not modules then modules = { } end modules ['mlib-run'] = { license = "see context related readme files", } --- todo mpx :execute -> mlib.execute(mpx,) - -- cmyk -> done, native -- spot -> done, but needs reworking (simpler) -- multitone -> @@ -32,7 +30,7 @@ nears zero.</p> --ldx]]-- local type, tostring, tonumber, next = type, tostring, tonumber, next -local striplines = utilities.strings.striplines +local find, striplines = string.find, utilities.strings.striplines local concat, insert, remove = table.concat, table.insert, table.remove local emptystring = string.is_empty @@ -40,8 +38,10 @@ local P = lpeg.P local trace_graphics = false trackers.register("metapost.graphics", function(v) trace_graphics = v end) local trace_tracingall = false trackers.register("metapost.tracingall", function(v) trace_tracingall = v end) +local trace_terminal = false trackers.register("metapost.terminal", function(v) trace_terminal = v end) local report_metapost = logs.reporter("metapost") +local report_terminal = logs.reporter("metapost","terminal") local texerrormessage = logs.texerrormessage local starttiming = statistics.starttiming @@ -55,11 +55,53 @@ local metapost = metapost metapost.showlog = false metapost.lastlog = "" -metapost.collapse = true -- currently mplib cannot deal with begingroup/endgroup mismatch in stepwise processing metapost.texerrors = false metapost.exectime = metapost.exectime or { } -- hack --- metapost.collapse = false +local mpxformats = { } +local mpxterminals = { } +local nofformats = 0 +local mpxpreambles = { } +local mpxextradata = { } + +-- The flatten hack is needed because the library currently barks on \n\n and the +-- collapse because mp cannot handle snippets due to grouping issues. + +-- todo: pass tables to executempx instead of preparing beforehand, +-- as it's more efficient for the terminal + +local function flatten(source,target) + for i=1,#source do + local d = source[i] + if type(d) == "table" then + flatten(d,target) + elseif d and d ~= "" then + target[#target+1] = d + end + end + return target +end + +local function prepareddata(data) + if data and data ~= "" then + if type(data) == "table" then + data = flatten(data,{ }) + data = #data > 1 and concat(data,"\n") or data[1] + end + return data + end +end + +local function executempx(mpx,data) + local terminal = mpxterminals[mpx] + if terminal then + terminal.writer(data) + data = "" + elseif type(data) == "table" then + data = prepareddata(data,collapse) + end + return mpx:execute(data) +end directives.register("mplib.texerrors", function(v) metapost.texerrors = v end) trackers.register ("metapost.showlog", function(v) metapost.showlog = v end) @@ -77,7 +119,7 @@ local mpbasepath = lpeg.instringchecker(P("/metapost/") * (P("context") + P("bas -- for some reason mp sometimes calls this function twice which is inefficient -- but we cannot catch this -do +local realtimelogging do local finders = { } mplib.finders = finders -- also used in meta-lua.lua @@ -85,12 +127,10 @@ do local new_instance = mplib.new local function validftype(ftype) - if ftype == "" then - -- whatever - elseif ftype == 0 then - -- mplib bug + if ftype == "mp" then + return "mp" else - return ftype + return nil end end @@ -98,6 +138,8 @@ do return resolvers.findfile(name,validftype(ftype)) end + -- this will be redone in lmtx + local function i_finder(name,mode,ftype) -- fake message for mpost.map and metafun.mpvi local specification = url.hashed(name) local finder = finders[specification.scheme] or finders.file @@ -115,9 +157,172 @@ do return (mode == "w" and o_finder or i_finder)(name,mode,validftype(ftype)) end - function mplib.new(specification) - specification.find_file = finder -- so we block an overload - return new_instance(specification) + local report_logger = logs.reporter("metapost log") + local report_error = logs.reporter("metapost error") + + local l, nl, dl = { }, 0, false + local t, nt, dt = { }, 0, false + local e, ne, de = { }, 0, false + + local function logger(target,str) + if target == 1 then + -- log + elseif target == 2 or target == 3 then + -- term + if str == "\n" then + realtimelogging = true + if nl > 0 then + report_logger(concat(l,"",1,nl)) + nl, dl = 0, false + elseif not dl then + report_logger("") + dl = true + end + else + nl = nl + 1 + l[nl] = str + end + elseif target == 4 then + report_error(str) + end + end + + -- experiment, todo: per instance, just a push / pop ? + + local findtexfile = resolvers.findtexfile + local opentexfile = resolvers.opentexfile + local splitlines = string.splitlines + + local function writetoterminal(terminaldata,maxterm,d) + local t = type(d) + local n = 0 + if t == "string" then + d = splitlines(d) + n = #d + for i=1,#d do + maxterm = maxterm + 1 + terminaldata[maxterm] = d[i] + end + elseif t == "table" then + for i=1,#d do + local l = d[i] + if find(l,"[\n\r]") then + local s = splitlines(l) + local m = #s + for i=1,m do + maxterm = maxterm + 1 + terminaldata[maxterm] = s[i] + end + n = n + m + else + maxterm = maxterm + 1 + terminaldata[maxterm] = d[i] + n = 1 + end + end + end + if trace_terminal then + report_metapost("writing %i lines, in cache %s",n,maxterm) + end + return maxterm + end + + local function readfromterminal(terminaldata,maxterm,nowterm) + if nowterm >= maxterm then + terminaldata[nowterm] = false + maxterm = 0 + nowterm = 0 + if trace_terminal then + report_metapost("resetting, maxcache %i",#terminaldata) + end + return maxterm, nowterm, nil + else + if nowterm > 0 then + terminaldata[nowterm] = false + end + nowterm = nowterm + 1 + local s = terminaldata[nowterm] + if trace_terminal then + report_metapost("reading line %i: %s",nowterm,s) + end + return maxterm, nowterm, s + end + end + + local function fileopener() + + -- these can go into the table itself + + local terminaldata = { } + local maxterm = 0 + local nowterm = 0 + + local terminal = { + name = "terminal", + close = function() + -- terminal = { } + -- maxterm = 0 + -- nowterm = 0 + end, + reader = function() + local line + maxterm, nowterm, line = readfromterminal(terminaldata,maxterm,nowterm) + return line + end, + writer = function(d) + maxterm = writetoterminal(terminaldata,maxterm,d) + end, + } + + return function(name,mode,kind) + if name == "terminal" then + -- report_metapost("opening terminal") + return terminal + elseif mode == "w" then + local f = io.open(name,"wb") + if f then + -- report_metapost("opening file %a for writing",full) + return { + name = full, + writer = function(s) return f:write(s) end, -- io.write(f,s) + close = function() f:close() end, + } + end + else + local full = findtexfile(name,validftype(ftype)) + if full then + -- report_metapost("opening file %a for reading",full) + return opentexfile(full) + end + end + end + + end + + -- end of experiment + + if CONTEXTLMTXMODE > 0 then + + function mplib.new(specification) + local openfile = fileopener() + specification.find_file = finder + specification.run_logger = logger + specification.open_file = openfile + specification.interaction = "silent" + specification.halt_on_error = true + local instance = new_instance(specification) + mpxterminals[instance] = openfile("terminal") + return instance + end + + else + + function mplib.new(specification) + specification.find_file = finder + specification.run_logger = logger + return new_instance(specification) + end + end mplib.finder = finder @@ -130,7 +335,12 @@ local find_file = mplib.finder function metapost.reporterror(result) if not result then report_metapost("error: no result object returned") - elseif result.status > 0 then + return true + elseif result.status == 0 then + return false + elseif realtimelogging then + return false -- we already reported + else local t = result.term local e = result.error local l = result.log @@ -150,10 +360,8 @@ function metapost.reporterror(result) else report_metapost("error: unknown, no error, terminal or log messages") end - else - return false + return true end - return true end local f_preamble = formatters [ [[ @@ -173,7 +381,7 @@ local methods = { } function metapost.runscript(code) - return code + return "" end function metapost.scripterror(str) @@ -210,7 +418,10 @@ function metapost.load(name,method) if not mpx then result = { status = 99, error = "out of memory"} else - result = mpx:execute(f_preamble(file.addsuffix(name,"mp"),seed)) -- addsuffix is redundant + -- pushing permits advanced features + metapost.pushscriptrunner(mpx) + result = executempx(mpx,f_preamble(file.addsuffix(name,"mp"),seed)) + metapost.popscriptrunner() end stoptiming(mplib) metapost.reporterror(result) @@ -254,42 +465,10 @@ function metapost.unload(mpx) stoptiming(mplib) end --- The flatten hack is needed because the library currently barks on \n\n and the --- collapse because mp cannot handle snippets due to grouping issues. - -local function flatten(source,target) - for i=1,#source do - local d = source[i] - if type(d) == "table" then - flatten(d,target) - elseif d and d ~= "" then - target[#target+1] = d - end - end - return target -end - -local function prepareddata(data,collapse) - if data and data ~= "" then - if type(data) == "table" then - data = flatten(data,{ }) - if collapse then - data = #data > 1 and concat(data,"\n") or data[1] - end - end - return data - end -end - metapost.defaultformat = "metafun" metapost.defaultinstance = "metafun" metapost.defaultmethod = "default" -local mpxformats = { } -local nofformats = 0 -local mpxpreambles = { } -local mpxextradata = { } - function metapost.getextradata(mpx) return mpxextradata[mpx] end @@ -332,24 +511,24 @@ function metapost.pushformat(specification,f,m) -- was: instance, name, method end nofformats = nofformats + 1 local usedinstance = instance .. ":" .. nofformats - local mpx = mpxformats[usedinstance] + local mpx = mpxformats [usedinstance] local mpp = mpxpreambles[instance] or "" if preamble then - preamble = prepareddata(preamble,true) + preamble = prepareddata(preamble) mpp = mpp .. "\n" .. preamble mpxpreambles[instance] = mpp end if not mpx then report_metapost("initializing instance %a using format %a and method %a",usedinstance,format,method) mpx = metapost.checkformat(format,method) - mpxformats[usedinstance] = mpx + mpxformats [usedinstance] = mpx mpxextradata[mpx] = { } if mpp ~= "" then preamble = mpp end end if preamble then - mpx:execute(preamble) + executempx(mpx,preamble) end specification.mpx = mpx return mpx @@ -370,16 +549,19 @@ function metapost.reset(mpx) -- nothing elseif type(mpx) == "string" then if mpxformats[mpx] then - mpxextradata[mpx] = nil - mpxformats[mpx] = nil - mpxformats[mpx]:finish() + local instance = mpxformats[mpx] + instance:finish() + mpxterminals[instance] = nil + mpxextradata[mpx] = nil + mpxformats [mpx] = nil end else for name, instance in next, mpxformats do if instance == mpx then - mpxextradata[mpx] = nil - mpxformats[mpx] = nil mpx:finish() + mpxextradata[mpx] = nil + mpxformats [mpx] = nil + mpxterminals[mpx] = nil break end end @@ -469,7 +651,7 @@ function metapost.run(specification) end if mpx and data then local tra = nil - starttiming(metapost) + starttiming(metapost) -- why not at the outer level ... metapost.variables = { } -- todo also push / pop metapost.pushscriptrunner(mpx) if trace_graphics then @@ -487,20 +669,25 @@ function metapost.run(specification) tra.inp:write(banner) tra.log:write(banner) end - local data = prepareddata(data,metapost.collapse) local function process(d,i) if d then if trace_graphics then if i then tra.inp:write(formatters["\n%% begin snippet %s\n"](i)) end - tra.inp:write(d) + if type(d) == "table" then + for i=1,#d do + tra.inp:write(d[i]) + end + else + tra.inp:write(d) + end if i then tra.inp:write(formatters["\n%% end snippet %s\n"](i)) end end starttiming(metapost.exectime) - result = mpx:execute(d) + result = executempx(mpx,d) stoptiming(metapost.exectime) if trace_graphics and result then local str = result.log or result.error @@ -510,6 +697,7 @@ function metapost.run(specification) end if not metapost.reporterror(result) then if metapost.showlog then + -- make function and overload in lmtx local str = result.term ~= "" and result.term or "no terminal output" if not emptystring(str) then metapost.lastlog = metapost.lastlog .. "\n" .. str @@ -527,14 +715,16 @@ function metapost.run(specification) end end +-- local data = prepareddata(data) if type(data) == "table" then if trace_tracingall then - mpx:execute("tracingall;") + executempx(mpx,"tracingall;") end - for i=1,#data do - process(data[i],i) - end - else + process(data) +-- for i=1,#data do +-- process(data[i],i) +-- end + else if trace_tracingall then data = "tracingall;" .. data end @@ -562,67 +752,71 @@ if not metapost.convert then end --- handy +-- This will be redone as we no longer output svg of ps! + +-- function metapost.directrun(formatname,filename,outputformat,astable,mpdata) +-- local fullname = file.addsuffix(filename,"mp") +-- local data = mpdata or io.loaddata(fullname) +-- if outputformat ~= "svg" then +-- outputformat = "mps" +-- end +-- if not data then +-- report_metapost("unknown file %a",filename) +-- else +-- local mpx = metapost.checkformat(formatname) +-- if not mpx then +-- report_metapost("unknown format %a",formatname) +-- else +-- report_metapost("processing %a",(mpdata and (filename or "data")) or fullname) +-- local result = executempx(mpx,data) +-- if not result then +-- report_metapost("error: no result object returned") +-- elseif result.status > 0 then +-- report_metapost("error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error")) +-- else +-- if metapost.showlog then +-- metapost.lastlog = metapost.lastlog .. "\n" .. result.term +-- report_metapost("info: %s",result.term or "no-term") +-- end +-- local figures = result.fig +-- if figures then +-- local sorted = table.sortedkeys(figures) +-- if astable then +-- local result = { } +-- report_metapost("storing %s figures in table",#sorted) +-- for k=1,#sorted do +-- local v = sorted[k] +-- if outputformat == "mps" then +-- result[v] = figures[v]:postscript() +-- else +-- result[v] = figures[v]:svg() -- (3) for prologues +-- end +-- end +-- return result +-- else +-- local basename = file.removesuffix(file.basename(filename)) +-- for k=1,#sorted do +-- local v = sorted[k] +-- local output +-- if outputformat == "mps" then +-- output = figures[v]:postscript() +-- else +-- output = figures[v]:svg() -- (3) for prologues +-- end +-- local outname = formatters["%s-%s.%s"](basename,v,outputformat) +-- report_metapost("saving %s bytes in %a",#output,outname) +-- io.savedata(outname,output) +-- end +-- return #sorted +-- end +-- end +-- end +-- end +-- end +-- end function metapost.directrun(formatname,filename,outputformat,astable,mpdata) - local fullname = file.addsuffix(filename,"mp") - local data = mpdata or io.loaddata(fullname) - if outputformat ~= "svg" then - outputformat = "mps" - end - if not data then - report_metapost("unknown file %a",filename) - else - local mpx = metapost.checkformat(formatname) - if not mpx then - report_metapost("unknown format %a",formatname) - else - report_metapost("processing %a",(mpdata and (filename or "data")) or fullname) - local result = mpx:execute(data) - if not result then - report_metapost("error: no result object returned") - elseif result.status > 0 then - report_metapost("error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error")) - else - if metapost.showlog then - metapost.lastlog = metapost.lastlog .. "\n" .. result.term - report_metapost("info: %s",result.term or "no-term") - end - local figures = result.fig - if figures then - local sorted = table.sortedkeys(figures) - if astable then - local result = { } - report_metapost("storing %s figures in table",#sorted) - for k=1,#sorted do - local v = sorted[k] - if outputformat == "mps" then - result[v] = figures[v]:postscript() - else - result[v] = figures[v]:svg() -- (3) for prologues - end - end - return result - else - local basename = file.removesuffix(file.basename(filename)) - for k=1,#sorted do - local v = sorted[k] - local output - if outputformat == "mps" then - output = figures[v]:postscript() - else - output = figures[v]:svg() -- (3) for prologues - end - local outname = formatters["%s-%s.%s"](basename,v,outputformat) - report_metapost("saving %s bytes in %a",#output,outname) - io.savedata(outname,output) - end - return #sorted - end - end - end - end - end + report_metapost("producing postscript and svg is no longer supported") end -- goodie diff --git a/tex/context/base/mkiv/mtx-context-listing.tex b/tex/context/base/mkiv/mtx-context-listing.tex index 285113850..1053e80b9 100644 --- a/tex/context/base/mkiv/mtx-context-listing.tex +++ b/tex/context/base/mkiv/mtx-context-listing.tex @@ -116,10 +116,10 @@ -- forced end context.page() --- context.setupfootertexts( -- return true: we need to keep this entry --- { function() context.detokenize(pattern and filename or file.basename(filename)) return true end }, --- { function() context.pagenumber() return true end } --- ) + context.setupfootertexts( -- return true: we need to keep this entry + { function() context.detokenize(pattern and filename or file.basename(filename)) return true end }, + { function() context.pagenumber() return true end } + ) if scite then context.scitefile { filename } -- here { } elseif pretty then diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index 57cf4778a..eb5cc4f08 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -17,6 +17,7 @@ return { "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption", + "contextlmtxmode", }, commands = { "loadfile", "loadimage", "loadmodule", @@ -174,5 +175,7 @@ return { "comment", "report", "lua", "mp", "MP", "luacall", -- "mirrored", "mirroredabout", + -- + "scriptindex", }, } diff --git a/tex/context/base/mkiv/mult-mps.lua b/tex/context/base/mkiv/mult-mps.lua index 1d7252c29..b42beb2b8 100644 --- a/tex/context/base/mkiv/mult-mps.lua +++ b/tex/context/base/mkiv/mult-mps.lua @@ -15,7 +15,7 @@ return { "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", - "hex", "infont", "intersectiontimes", "known", "length", "llcorner", + "hex", "infont", "intersectiontimes", "known", "void", "length", "llcorner", "lrcorner", "makepath", "makepen", "mexp", "mlog", "normaldeviate", "not", "numeric", "oct", "odd", "or", "path", "pair", "pen", "penoffset", "picture", "point", "postcontrol", "precontrol", "reverse", "rotated", "scaled", @@ -49,7 +49,7 @@ return { "extra_beginfig", "extra_endfig", "mpxbreak", "endinput", "message", "delimiters", "turningnumber", "errmessage", - "readstring", "scantokens", "end", "outer", "inner", "write", "to", "readfrom", + "scantokens", "end", "outer", "inner", "write", "to", "readfrom", "closefrom", "withprescript", "withpostscript", "top", "bot", "lft", "rt", "ulft", "urt", "llft", "lrt", -- diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index ebccab04c..b097fb8b1 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -147,8 +147,9 @@ local nuts = nodes.nuts nuts.check_discretionaries = direct.check_discretionaries nuts.copy = direct.copy -nuts.copy_list = direct.copy_list nuts.copy_node = direct.copy +nuts.copy_only = direct.copy_only or direct.copy +nuts.copy_list = direct.copy_list nuts.count = direct.count nuts.current_attr = direct.current_attr nuts.delete = direct.delete @@ -367,7 +368,7 @@ local d_setlink = direct.setlink local d_setboth = direct.setboth local d_getboth = direct.getboth -local function remove(head,current,free_too) +local remove = (CONTEXTLMTXMODE > 0 and LUATEXFUNCTIONALITY >= 20190704) and d_remove_node or function(head,current,free_too) if current then local h, c = d_remove_node(head,current) if free_too then diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index 4b8187fa3..5012e771a 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -99,7 +99,7 @@ local setdata = nuts.setdata local setruledata = nuts.setruledata local setvalue = nuts.setvalue -local copy_nut = nuts.copy +local copy_nut = nuts.copy_only or nuts.copy local new_nut = nuts.new local flush_nut = nuts.flush diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua index 5a8fdc48a..1b86c9716 100644 --- a/tex/context/base/mkiv/node-rul.lua +++ b/tex/context/base/mkiv/node-rul.lua @@ -543,8 +543,8 @@ local function find_attr(head,attr) end function linefillers.handler(head) - for current, subtype, list in nexthlist, head do - if list and subtype == linelist_code then + for current, subtype in nexthlist, head do + if current and subtype == linelist_code then -- why doesn't leftskip take the attributes -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) local a = getattr(current,a_linefiller) @@ -568,6 +568,8 @@ function linefillers.handler(head) rightlocal = true end -- + local list = getlist(current) + -- if location == v_left or location == v_both then local lskip = nil -- leftskip local iskip = nil -- indentation diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua index bb2eba780..9f333315b 100644 --- a/tex/context/base/mkiv/node-syn.lua +++ b/tex/context/base/mkiv/node-syn.lua @@ -168,7 +168,7 @@ local getdimensions = nuts.dimensions local getrangedimensions = nuts.rangedimensions local get_synctex_fields = nuts.get_synctex_fields -local set_synctex_fields = nuts.set_synctex_fields +----- set_synctex_fields = nuts.set_synctex_fields local set_synctex_line = tex.set_synctex_line local set_synctex_tag = tex.set_synctex_tag local force_synctex_tag = tex.force_synctex_tag diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex c171029ad..472dee79a 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 0f13f1cb4..4b9db0b9a 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi index a1289bf1d..5daf2b44d 100644 --- a/tex/context/base/mkiv/strc-flt.mkvi +++ b/tex/context/base/mkiv/strc-flt.mkvi @@ -1068,8 +1068,9 @@ \def\floatcaptionattribute {\iflocation - %\ifnofloatnumber - %\else + \ifx\currentfloatattribute\empty + % safeguard, can be samepage too + \else \ifnofloatcaption \else \ifinsidesplitfloat @@ -1081,7 +1082,7 @@ attr \destinationattribute \currentfloatattribute \fi \fi - %\fi + \fi \fi} \newconditional\usesamefloatnumber @@ -1144,7 +1145,7 @@ \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize \fi % - \global\setfalse\usesamefloatnumber % one shot + \iftrialtypesetting\else\global\setfalse\usesamefloatnumber\fi % one shot % check float box \strc_floats_set_natural_dimensions\nextbox \global\setbox\floatbox\vbox{\floatparameter\c!command{\box\nextbox}}% can be anything so no pack @@ -1170,6 +1171,7 @@ \strc_floats_get_box \global\insidefloatfalse} + \newdimen\availablefloatwidth \newdimen\availablefloatheight diff --git a/tex/context/base/mkiv/tabl-tsp.mkiv b/tex/context/base/mkiv/tabl-tsp.mkiv index e0ddce38a..9395f4039 100644 --- a/tex/context/base/mkiv/tabl-tsp.mkiv +++ b/tex/context/base/mkiv/tabl-tsp.mkiv @@ -187,7 +187,9 @@ \bgroup \forcelocalfloats \setuplocalfloats[\c!before=,\c!after=,\c!inbetween=]% + \settrialtypesetting % this controls samepage resetting too \splitfloatcommand{\hbox to #1{\strut}}% dummy line + \resettrialtypesetting \setbox\scratchbox\vbox{\flushlocalfloats}% \vpack ? \getnoflines{\ht\scratchbox}% \resetlocalfloats diff --git a/tex/context/base/mkiv/typo-wrp.lua b/tex/context/base/mkiv/typo-wrp.lua index 9fb544152..f2ca43b56 100644 --- a/tex/context/base/mkiv/typo-wrp.lua +++ b/tex/context/base/mkiv/typo-wrp.lua @@ -32,7 +32,7 @@ local getprev = nuts.getprev local getid = nuts.getid local getsubtype = nuts.getsubtype local getpenalty = nuts.getpenalty -local remove = nuts.remove +local remove_node = nuts.remove local enableaction = nodes.tasks.enableaction @@ -66,7 +66,7 @@ local function remove_dangling_crlf(head,tail) if trace_wrappers then report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno) end - remove(head,tail,true) + remove_node(head,tail,true) return head, tail end end diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml index 1b8ce2fa6..bb4800900 100644 --- a/tex/context/interface/mkii/keys-cs.xml +++ b/tex/context/interface/mkii/keys-cs.xml @@ -737,6 +737,7 @@ <cd:constant name='component' value='component'/> <cd:constant name='compoundhyphen' value='compoundhyphen'/> <cd:constant name='compress' value='compress'/> + <cd:constant name='compressdistance' value='compressdistance'/> <cd:constant name='compressseparator' value='compressseparator'/> <cd:constant name='concerns' value='concerns'/> <cd:constant name='connector' value='connector'/> diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index 97a18d711..2ab5c9c12 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -737,6 +737,7 @@ <cd:constant name='component' value='component'/> <cd:constant name='compoundhyphen' value='compoundhyphen'/> <cd:constant name='compress' value='compress'/> + <cd:constant name='compressdistance' value='compressdistance'/> <cd:constant name='compressseparator' value='compressseparator'/> <cd:constant name='concerns' value='concerns'/> <cd:constant name='connector' value='connector'/> diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index 0c1d450ec..c852ae515 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -573,6 +573,7 @@ <cd:variable name='temporary' value='temporaneo'/> <cd:variable name='test' value='test'/> <cd:variable name='text' value='testo'/> + <cd:variable name='textnote' value='textnote'/> <cd:variable name='three' value='tre'/> <cd:variable name='thursday' value='giovedi'/> <cd:variable name='tight' value='tight'/> @@ -736,6 +737,7 @@ <cd:constant name='component' value='component'/> <cd:constant name='compoundhyphen' value='compoundhyphen'/> <cd:constant name='compress' value='compress'/> + <cd:constant name='compressdistance' value='compressdistance'/> <cd:constant name='compressseparator' value='compressseparator'/> <cd:constant name='concerns' value='concerns'/> <cd:constant name='connector' value='connector'/> diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 8532d9894..710f9d74b 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -737,6 +737,7 @@ <cd:constant name='component' value='مولفه'/> <cd:constant name='compoundhyphen' value='compoundhyphen'/> <cd:constant name='compress' value='فشردن'/> + <cd:constant name='compressdistance' value='compressdistance'/> <cd:constant name='compressseparator' value='compressseparator'/> <cd:constant name='concerns' value='concerns'/> <cd:constant name='connector' value='connector'/> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 51806d7e1..97b13f0d0 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 97206e852..9f90949bb 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-simulate.mkiv b/tex/context/modules/mkiv/m-simulate.mkiv new file mode 100644 index 000000000..dc4448903 --- /dev/null +++ b/tex/context/modules/mkiv/m-simulate.mkiv @@ -0,0 +1,222 @@ +%D \module +%D [ file=m-simulate, +%D version=2016.02.18, % follow up on m-visual of 2000.01.10 +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Visualization and Faking Redone, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\definepalet + [fakerule] + [fr1c=darkred, + fr2c=darkgreen, + fr3c=darkblue, + fr4c=darkyellow, + fr5c=darkgray, + fr6c=darkred, + fr7c=darkgreen, + fr8c=darkblue, + fr9c=darkyellow, + fr0c=darkgray] + +\installcorenamespace {simulatewords} + +\installcommandhandler \??simulatewords {simulatewords} \??simulatewords + +\setupsimulatewords + [\c!n =\plusten, + \c!m =40, + \c!min =\plusone, + \c!max =\plusfive, + \c!minwidth=0.50\emwidth, + \c!maxwidth=1.25\emwidth, + \c!color =\empty, + \c!hyphen =\v!yes, + \c!distance=-.2\onebasepoint] + +\unexpanded\def\dosimulatedword + {\clf_fakeword + factor \exheight + name {\p_line} + min \scratchdimenone + max \scratchdimentwo + \relax} + +\def\simulatedhyphen + {\kern.2\points-\kern.2\points} + +\unexpanded\def\simulatewords + {\dodoubleempty\dosimulatewords} + +\unexpanded\def\dosimulatewords[#1][#2]% + {\dontleavehmode + \begingroup + \begstrut + \ifsecondargument + \edef\currentsimulatewords{#1}% + \setupcurrentsimulatewords[#2]% + \else + \doifassignmentelse{#1} + {\let\currentsimulatewords\empty + \setupcurrentsimulatewords[#1]} + {\edef\currentsimulatewords{#1}% + \setupcurrentsimulatewords[#2]}% + \fi + \scratchcounterone\simulatewordsparameter\c!n + \scratchcountertwo\simulatewordsparameter\c!m + \scratchmin \simulatewordsparameter\c!min + \scratchmax \simulatewordsparameter\c!max + \scratchdimenone \simulatewordsparameter\c!minwidth + \scratchdimentwo \simulatewordsparameter\c!maxwidth + \scratchdimenthree\simulatewordsparameter\c!distance + \edef\p_random{\simulatewordsparameter\c!random}% + \edef\p_color {\simulatewordsparameter\c!color}% + \edef\p_line {\simulatewordsparameter\c!line}% + \edef\p_hyphen{\simulatewordsparameter\c!hyphen}% + \edef\p_line {fake:\ifx\p_line\v!yes word\else rule\fi}% + \ifx\p_color\v!text + % no need + \else + \setuppalet[fakerule]% + \ifx\p_color\empty + \directcolored[fakerulecolor]% + \else\ifx\p_color\v!auto + % different + \else + \directcolored[\p_color]% + \fi\fi + \fi + \edef\p_hyphen + {\ifx\p_hyphen\v!yes + \discretionary{\bf\simulatedhyphen}{}{\kern\scratchdimenthree}% + \else\ifx\p_hyphen\v!margin + \discretionary{\hpack to \zeropoint{\bf\simulatedhyphen\hss}}{}{\kern\scratchdimenthree}% + \else\ifx\p_hyphen\v!none + \allowbreak\kern\scratchdimenthree + \else\ifx\p_hyphen\v!no + \allowbreak\kern\scratchdimenthree + \else\ifx\p_hyphen\v!both + \discretionary{\bf\simulatedhyphen}{\bf\simulatedhyphen}{\kern\scratchdimenthree}% + \else\ifx\p_hyphen\empty + \allowbreak\kern\scratchdimenthree + \else + \discretionary{\p_hyphen}{}{\kern\scratchdimenthree}% + \fi\fi\fi\fi\fi\fi}% + \edef\truncated##1##2\relax{##1}% + % trialtypesetting: tricky + \ifx\p_random\empty \else + \pushrandomseed + \setrandomseed\p_random + \fi + \dorecurse{\randomnumber\scratchcounterone\scratchcountertwo} {% + \let\dosimulatedhyphen\relax + \dorecurse{\randomnumber\scratchmin\scratchmax} {% + \dosimulatedhyphen + \begingroup + \ifx\p_color\v!auto + \directcolored[fr\truncated####1\relax c]% + \fi + \dosimulatedword + \endgroup + \let\dosimulatedhyphen\p_hyphen + }% + \relax + \space + }% + \ifx\p_random\empty \else + \poprandomseed + \fi + \removeunwantedspaces + \endstrut + \endgroup} + +%D For old times sake: + +\unexpanded\def\fakewords#1#2% + {\simulatewords[\c!n=#1,\c!m=#2,\c!min=1,\c!max=5,\c!hyphen=\v!none,\c!color=\v!text,\c!line=\v!yes]} + +%D Lines + +\unexpanded\def\fakeline + {\dosingleempty\dofakeline} + +\unexpanded\def\dofakeline[#1]% + {\par + \dontleavehmode + \hpack\bgroup + \scratchwidth \availablehsize + \scratchheight.8\strutht + \scratchdepth .8\strutdp + \iffirstargument + \letsimulatewordsparameter\c!width \scratchwidth + \letsimulatewordsparameter\c!height\scratchheight + \letsimulatewordsparameter\c!depth \scratchdepth + \getcurrentsimulatewords[#1]% + \scratchwidth \simulatewordsparameter\c!width + \scratchheight\simulatewordsparameter\c!height + \scratchdepth \simulatewordsparameter\c!depth + \fi + \edef\p_color{\simulatewordsparameter\c!color}% + \begingroup + \ifx\p_color\empty + \directcolored[fakerulecolor]% + \else\ifx\p_color\v!auto + % text color + \else + \directcolored[\p_color]% + \fi\fi + \vrule + \s!width \scratchwidth + \s!height\scratchheight + \s!depth \scratchdepth + \endgroup + \hskip-\scratchwidth + \directcolored[\s!white]% + \scratchdimen.5\onepoint + \vrule + \s!width \scratchwidth + \s!height\scratchdimen + \s!depth \scratchdimen + \egroup + \par} + +\protect + +\continueifinputfile{m-simulate.mkiv} + +\starttext + + \simulatewords[n=50,m=100,min=1,max=5,color=auto,hyphen=margin,line=yes]\par + \simulatewords[n=50,m=100,min=3,max=9,color=auto,hyphen=margin,line=yes]\par + \simulatewords[n=50,m=100,min=3,max=9,color=auto,hyphen=margin,line=yes]\par + \page + \simulatewords[n=50,m=100,min=2,max=6,hyphen=yes]\par + \simulatewords[n=50,m=100,min=2,max=6,hyphen=both]\par + \simulatewords[n=50,m=100,min=2,max=6,hyphen=both]\par + + \startcolor[red] + \simulatewords[n=50,m=100,min=2,max=6,color=text]\par + \stopcolor + + \definesimulatewords[foo][n=50,m=100,min=2,max=6,color=text] + + \startcolor[green] + \simulatewords[foo][color=darkyellow,random=1234] + \stopcolor + + \page + + \fakeline + + \startnarrower + \fakeline + \stopnarrower + +\stoptext diff --git a/tex/generic/context/luatex/luatex-basics-chr.lua b/tex/generic/context/luatex/luatex-basics-chr.lua index 9036b2977..0ac0eab14 100644 --- a/tex/generic/context/luatex/luatex-basics-chr.lua +++ b/tex/generic/context/luatex/luatex-basics-chr.lua @@ -3614,6 +3614,6 @@ characters.indicgroups={ }, } --- done +-- done, uncomment for testing: -return characters.indicgroups +-- return characters.indicgroups diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index b72b1a888..6bd9bbd59 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/20/19 18:47:00 +-- merge date : 07/04/19 12:29:22 do -- begin closure to overcome local limits and interference @@ -977,9 +977,11 @@ function string.is_empty(str) end end local anything=patterns.anything -local allescapes=Cc("%")*S(".-+%?()[]*") -local someescapes=Cc("%")*S(".-+%()[]") -local matchescapes=Cc(".")*S("*?") +local moreescapes=Cc("%")*S(".-+%?()[]*$^{}") +local allescapes=Cc("%")*S(".-+%?()[]*") +local someescapes=Cc("%")*S(".-+%()[]") +local matchescapes=Cc(".")*S("*?") +local pattern_m=Cs ((moreescapes+anything )^0 ) local pattern_a=Cs ((allescapes+anything )^0 ) local pattern_b=Cs ((someescapes+matchescapes+anything )^0 ) local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") ) @@ -989,6 +991,8 @@ end function string.topattern(str,lowercase,strict) if str=="" or type(str)~="string" then return ".*" + elseif strict=="all" then + str=lpegmatch(pattern_m,str) elseif strict then str=lpegmatch(pattern_c,str) else @@ -8591,7 +8595,6 @@ characters.indicgroups={ [43249]=true, }, } -return characters.indicgroups end -- closure |