From 84aae20fa32c9a50ae1c63576573f52d010de43b Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 17 Feb 2021 14:13:46 +0100 Subject: 2021-02-17 13:33:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-it.mkii | 3 + tex/context/base/mkiv/anch-pgr.lua | 7 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/luat-ini.lua | 18 +- tex/context/base/mkiv/mult-low.lua | 10 +- tex/context/base/mkiv/mult-mes.lua | 3 + tex/context/base/mkiv/status-files.pdf | Bin 25354 -> 25358 bytes tex/context/base/mkiv/status-lua.pdf | Bin 255883 -> 256060 bytes tex/context/base/mkiv/syst-ini.mkiv | 3 + tex/context/base/mkxl/anch-bck.mklx | 2 + tex/context/base/mkxl/anch-pgr.lmt | 1318 ++++++++++++++++++++ tex/context/base/mkxl/anch-pgr.mkxl | 2 +- tex/context/base/mkxl/back-ext.mkxl | 8 + tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/core-ini.mkxl | 2 +- tex/context/base/mkxl/file-job.mklx | 12 + tex/context/base/mkxl/file-mod.lmt | 309 +++++ tex/context/base/mkxl/file-mod.mklx | 2 +- tex/context/base/mkxl/grph-trf.mkxl | 6 +- tex/context/base/mkxl/luat-cod.lmt | 12 +- tex/context/base/mkxl/luat-ini.lmt | 46 + tex/context/base/mkxl/luat-lib.mkxl | 2 +- tex/context/base/mkxl/meta-ini.mkxl | 2 +- tex/context/base/mkxl/mlib-fio.lmt | 6 +- tex/context/base/mkxl/mlib-lmt.lmt | 19 +- tex/context/base/mkxl/mlib-pps.mkxl | 16 +- tex/context/base/mkxl/mult-sys.mkxl | 1 + tex/context/base/mkxl/node-fin.lmt | 23 + tex/context/base/mkxl/scrn-ini.mklx | 88 +- tex/context/base/mkxl/spac-ali.mkxl | 4 + tex/context/base/mkxl/spac-par.mkxl | 49 +- tex/context/base/mkxl/strc-sec.mkxl | 44 +- tex/context/base/mkxl/supp-box.lmt | 1 + tex/context/base/mkxl/supp-box.mkxl | 37 +- tex/context/base/mkxl/syst-ini.mkxl | 3 + tex/context/base/mkxl/typo-mar.mkxl | 4 +- tex/context/interface/mkii/keys-it.xml | 3 + tex/context/modules/mkiv/m-tikz.mkiv | 76 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 43 files changed, 1981 insertions(+), 174 deletions(-) create mode 100644 tex/context/base/mkxl/anch-pgr.lmt create mode 100644 tex/context/base/mkxl/file-mod.lmt create mode 100644 tex/context/base/mkxl/luat-ini.lmt (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 7a5ef95b4..166b632f8 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{2021.02.14 16:11} +\newcontextversion{2021.02.17 13:30} %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 1f5e76b38..9291fb479 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{2021.02.14 16:11} +\edef\contextversion{2021.02.17 13:30} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index cd463106f..4a4676f68 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -774,6 +774,8 @@ \setinterfaceconstant{deepnumbercommand}{deepnumbercommand} \setinterfaceconstant{deeptextcommand}{deeptextcommand} \setinterfaceconstant{default}{implicito} +\setinterfaceconstant{defaultheight}{defaultheight} +\setinterfaceconstant{defaultwidth}{defaultwidth} \setinterfaceconstant{define}{define} \setinterfaceconstant{delay}{attesa} \setinterfaceconstant{depth}{profondita} @@ -1118,6 +1120,7 @@ \setinterfaceconstant{print}{print} \setinterfaceconstant{printable}{stampabile} \setinterfaceconstant{process}{process} +\setinterfaceconstant{processors}{processors} \setinterfaceconstant{profile}{profile} \setinterfaceconstant{properties}{properties} \setinterfaceconstant{pubsep}{pubsep} diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index 239b33010..8e400cd12 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -1210,7 +1210,7 @@ posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; implement { name = "fetchposboxes", arguments = { "string", "string", "integer" }, - actions = function(tags,anchor,page) -- no caching (yet) / todo: anchor, page + actions = function(tags,anchor,page) -- no caching (yet) / page local collected = jobpositions.collected if type(tags) == "string" then tags = utilities.parsers.settings_to_array(tags) @@ -1222,6 +1222,9 @@ implement { local c = collected[tag] if c then local r = c.r + if anchor ~= r then + r = anchor + end if r then r = collected[r] if r then @@ -1231,7 +1234,7 @@ implement { local rh = r.h local rd = r.d local cx = c.x - rx - local cy = c.y + local cy = c.y - ry local cw = cx + c.w local ch = cy + c.h local cd = cy - c.d diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index a8c68be75..181bb0da5 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{2021.02.14 16:11} +\newcontextversion{2021.02.17 13:30} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 57f0fc064..f63e4b1a6 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{2021.02.14 16:11} +\edef\contextversion{2021.02.17 13:30} %D Kind of special: diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua index cec0161e7..39453b44c 100644 --- a/tex/context/base/mkiv/luat-ini.lua +++ b/tex/context/base/mkiv/luat-ini.lua @@ -25,21 +25,15 @@ if not global then global = _G end -LUATEXVERSION = status.luatex_version/100 - + tonumber(status.luatex_revision)/10000 - -LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) - or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex") - +LUATEXVERSION = status.luatex_version/100 + tonumber(status.luatex_revision)/10000 +LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) or "luametatex" LUATEXFUNCTIONALITY = status.development_id or 6346 - LUATEXFORMATID = status.format_id or 0 +JITSUPPORTED = false +INITEXMODE = status.run_state == 0 -- initializing updating production +CONTEXTLMTXMODE = 1 -JITSUPPORTED = LUATEXENGINE == "luajittex" or jit - -INITEXMODE = status.ini_version - -CONTEXTLMTXMODE = CONTEXTLMTXMODE or (LUATEXENGINE == "luametatex" and 1) or 0 +status.ini_version = INITEXMODE -- for a while function os.setlocale() -- no need for a message diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index ca65934ba..a893d455c 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -73,7 +73,8 @@ return { "frozenadjustcode", "frozenprotrudecode", "frozentolerancecode", "frozenstretchcode", "frozenloosenesscode", "frozenlastlinecode", "frozenlinepenaltycode", "frozenclubpenaltycode", "frozenwidowpenaltycode", "frozendisplaypenaltycode", "frozenbrokenpenaltycode", - "frozendemeritscode", "frozenshapecode", "frozenlinecode", "frozenallcode", + "frozendemeritscode", "frozenshapecode", "frozenlinecode", "frozenhyphenationcode", + "frozenallcode", -- "activemathcharcode", -- @@ -162,6 +163,7 @@ return { "compoundhyphenationmodecode", "strictstarthyphenationmodecode", "strictendhyphenationmodecode", "automaticpenaltyhyphenationmodecode", "explicitpenaltyhyphenationmodecode", "permitgluehyphenationmodecode", "permitallhyphenationmodecode", "permitmathreplacehyphenationmodecode", + "forcecheckhyphenationmodecode", "lazyligatureshyphenationmodecode", -- "normalizelinecode", "parindentskipcode", "swaphangindentcode", "swapparsshapecode", "breakafterdircode", "removemarginkernscode", "clipwidthcode", -- @@ -277,7 +279,7 @@ return { "next", "nexttoken", -- "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", - "boxisempty", + "boxisempty", "boxtostring", "contentostring", "prerolltostring", -- "givenwidth", "givenheight", "givendepth", "scangivendimensions", -- @@ -519,6 +521,8 @@ return { "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", -- + "hcontainer", "vcontainer", "tcontainer", + -- "frule", -- "compoundhyphenpenalty", @@ -548,7 +552,7 @@ return { -- "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", -- - "pushoverloadmode", "popoverloadmode", + "pushoverloadmode", "popoverloadmode", "pushrunstate", "poprunstate", -- "suggestedalias", -- diff --git a/tex/context/base/mkiv/mult-mes.lua b/tex/context/base/mkiv/mult-mes.lua index 299f1a404..65ae022c0 100644 --- a/tex/context/base/mkiv/mult-mes.lua +++ b/tex/context/base/mkiv/mult-mes.lua @@ -1159,6 +1159,9 @@ return { no = "slutten av blokk %a (seksjon)", ro = "sfarsit de bloc sectiune %a", }, + ["structures:3"] = { + en = "title to bookmark: %s", + }, ["symbols:1"] = { cs = "nacita se soubor symbolu %a", de = "Lade Symboldatei %a", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index c4ac7d938..f934bfab7 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index d91dbaebb..4ec3a9778 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index 6b84d33df..aafbc787e 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -1174,6 +1174,9 @@ % \let\pushoverloadmode\relax \let\popoverloadmode\relax + + \let\pushrunstate\relax + \let\poprunstate \relax \fi %D Now we define a few helpers that we need in a very early stage. We have no diff --git a/tex/context/base/mkxl/anch-bck.mklx b/tex/context/base/mkxl/anch-bck.mklx index 03e9c5195..c8f989624 100644 --- a/tex/context/base/mkxl/anch-bck.mklx +++ b/tex/context/base/mkxl/anch-bck.mklx @@ -668,6 +668,7 @@ \startMPpositiongraphic{mpos:encircle}{linecolor,fillcolor,linewidth,lineoffset} \MPgetposboxes{\MPvar{self}}{\MPanchorid} + % getposboxes("self","anchor") ; if nofposboxes = 1 : posboxes[1] := posboxes[1] enlarged \MPvar{lineoffset} cornered \MPvar{lineoffset} ; fill posboxes[1] withcolor \MPvar{fillcolor} ; @@ -686,6 +687,7 @@ boxlineoffset := \MPvar{lineoffset} ; def boxlineoptions = withcolor \MPvar{linecolor} enddef ; \MPgetposboxes{\MPvar{from},\MPvar{to}}{\MPanchorid} + % getposboxes("from,to","anchor") ; connect_positions ; \stopMPpositiongraphic diff --git a/tex/context/base/mkxl/anch-pgr.lmt b/tex/context/base/mkxl/anch-pgr.lmt new file mode 100644 index 000000000..0cf9ea9e4 --- /dev/null +++ b/tex/context/base/mkxl/anch-pgr.lmt @@ -0,0 +1,1318 @@ +if not modules then modules = { } end modules ['anch-pgr'] = { + version = 1.001, + comment = "companion to anch-pgr.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is a bit messy module but backgrounds are messy anyway. Especially when we want to +-- follow shapes. This will always be work in progress as it also depends on new features +-- in context. +-- +-- Alas, shapes and inline didn't work as expected end of 2016 so I had to pick up this +-- thread again. But with regular excursions to listening to Brad Mehldau's Mehliana I +-- could keep myself motivated. Some old stuff has been removed, some suboptimal code has +-- been replaced. Background code is still not perfect, but some day ... the details manual +-- will discuss this issue. + +local tonumber = tonumber +local sort, concat = table.sort, table.concat +local splitter = lpeg.splitat(":") +local lpegmatch = lpeg.match + +local jobpositions = job.positions +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex + +local enableaction = nodes.tasks.enableaction + +local commands = commands +local context = context + +local implement = interfaces.implement + +local getmacro = tokens.getters.macro + +local report_graphics = logs.reporter("backgrounds") +local report_shapes = logs.reporter("backgrounds","shapes") +local report_free = logs.reporter("backgrounds","free") + +local trace_shapes = false trackers.register("backgrounds.shapes", function(v) trace_shapes = v end) +local trace_ranges = false trackers.register("backgrounds.shapes.ranges",function(v) trace_ranges = v end) +local trace_free = false trackers.register("backgrounds.shapes.free", function(v) trace_free = v end) + +local f_b_tag = formatters["b:%s"] +local f_e_tag = formatters["e:%s"] +local f_p_tag = formatters["p:%s"] + +local f_tag_two = formatters["%s:%s"] + +local f_point = formatters["%p"] +local f_pair = formatters["(%p,%p)"] +local f_path = formatters["%--t--cycle"] +local f_pair_i = formatters["(%r,%r)"] -- rounded + +graphics = graphics or { } +local backgrounds = { } +graphics.backgrounds = backgrounds + +-- -- -- + +local texsetattribute = tex.setattribute + +local a_textbackground = attributes.private("textbackground") + +local nuts = nodes.nuts + +local new_latelua = nuts.pool.latelua +local new_rule = nuts.pool.rule +local new_kern = nuts.pool.kern +local new_hlist = nuts.pool.hlist + +local getbox = nuts.getbox +local getid = nuts.getid +----- getlist = nuts.getlist +local setlink = nuts.setlink +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local nodecodes = nodes.nodecodes +local par_code = nodecodes.par + +local start_of_par = nuts.start_of_par +local insert_before = nuts.insert_before +local insert_after = nuts.insert_after + +local processranges = nuts.processranges + +local unsetvalue = attributes.unsetvalue + +local jobpositions = job.positions +local getpos = jobpositions.getpos +local getfree = jobpositions.getfree + +local data = { } +local realpage = 1 +local recycle = 1000 -- only tables can overflow this +local enabled = false + +-- Freeing the data is somewhat tricky as we can have backgrounds spanning +-- many pages but for an arbitrary background shape that is not so common. + +local function check(specification) + local a = specification.attribute + local index = specification.index + local depth = specification.depth + local d = specification.data + local where = specification.where + local ht = specification.ht + local dp = specification.dp + -- this is not yet r2l ready + local w = d.shapes[realpage] + local x, y = getpos() + if trace_ranges then + report_shapes("attribute %i, index %i, depth %i, location %s, position (%p,%p)", + a,index,depth,where,x,y) + end + local n = #w + if d.index ~= index then + n = n + 1 + d.index = index + d.depth = depth + -- w[n] = { x, x, y, ht, dp } + w[n] = { y, ht, dp, x, x } + else + local wn = w[n] + local wh = wn[2] + local wd = wn[3] + if depth < d.depth then + local wy = wn[1] + wn[1] = y + d.depth = depth + local dy = wy - y + wh = wh - dy + wd = wd - dy + end + if where == "r" then + if x > wn[5] then + wn[5] = x + end + else + if x < wn[4] then + wn[4] = x + end + end + if ht > wh then + wn[2] = ht + end + if dp > wd then + wn[3] = dp + end + end + -- inspect(w) +end + +local index = 0 + +local function flush(head,f,l,a,parent,depth) + local d = data[a] + if d then + local ix = index + local ht = getheight(parent) + local dp = getdepth(parent) + local ln = new_latelua { action = check, attribute = a, index = ix, depth = depth, data = d, where = "l", ht = ht, dp = dp } + local rn = new_latelua { action = check, attribute = a, index = ix, depth = depth, data = d, where = "r", ht = ht, dp = dp } + if trace_ranges then + ln = new_hlist(setlink(new_rule(65536,65536*4,0),new_kern(-65536),ln)) + rn = new_hlist(setlink(new_rule(65536,0,65536*4),new_kern(-65536),rn)) + end + if getid(f) == par_code and start_of_par(f) then -- we need to clean this mess + insert_after(head,f,ln) + else + head, f = insert_before(head,f,ln) + end + insert_after(head,l,rn) + end + return head, true +end + +local function registerbackground(name) + local n = #data + 1 + if n > recycle then + -- we could also free all e: that are beyond a page but we don't always + -- know the page so a recycle is nicer and the s lists are kept anyway + -- so the amount of kept data is not that large + n = 1 + end + local b = jobpositions.tobesaved["b:"..name] + if b then + local s = setmetatableindex("table") + b.s = s + data[n] = { + bpos = b, + name = name, + n = n, + shapes = s, + count = 0, + sindex = 0, + } + texsetattribute(a_textbackground,n) + if not enabled then + enableaction("contributers", "nodes.handlers.textbackgrounds") + enabled = true + end + else + texsetattribute(a_textbackground,unsetvalue) + end +end + +-- local function collectbackgrounds(r,n) +-- if enabled then +-- local parent = getbox(n) +-- local head = getlist(parent) +-- realpage = r +-- processranges(a_textbackground,flush,head) -- ,parent) +-- end +-- end +-- +-- interfaces.implement { +-- name = "collectbackgrounds", +-- actions = collectbackgrounds, +-- arguments = { "integer", "integer" } +-- } + +nodes.handlers.textbackgrounds = function(head,where,parent) -- we have hlistdir and local dir + -- todo enable action in register + index = index + 1 + return processranges(a_textbackground,flush,head,parent) +end + +interfaces.implement { + name = "registerbackground", + actions = registerbackground, + arguments = "string", +} + +-- optimized already but we can assume a cycle i.e. prune the last point and then +-- even less code .. we could merge some loops but his is more robust + +-- use idiv here + +local function topairs(t,n) + local r = { } + for i=1,n do + local ti = t[i] + r[i] = f_pair_i(ti[1]/65556,ti[2]/65536) + end + return concat(r," ") +end + +local eps = 65536 / 4 +local pps = eps +local nps = - pps + +local function unitvector(x,y) + if x < pps and x > nps then + x = 0 + elseif x < 0 then + x = -1 + else + x = 1 + end + if y < pps and y > nps then + y = 0 + elseif y < 0 then + y = -1 + else + y = 1 + end + return x, y +end + +local function finish(t) + local tm = #t + if tm < 2 then + return + end + if trace_ranges then + report_shapes("initial list: %s",topairs(t,tm)) + end + -- remove similar points + local n = 1 + local tn = tm + local tf = t[1] + local tx = tf[1] + local ty = tf[2] + for i=2,#t do + local ti = t[i] + local ix = ti[1] + local iy = ti[2] + local dx = ix - tx + local dy = iy - ty + if dx > eps or dx < - eps or dy > eps or dy < - eps then + n = n + 1 + t[n] = ti + tx = ix + ty = iy + end + end + if trace_shapes then + report_shapes("removing similar points: %s",topairs(t,n)) + end + if n > 2 then + -- remove redundant points + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] + + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= vx2 then + n = n + 1 + t[n] = ti + else + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= vy2 then + n = n + 1 + t[n] = ti + end + end + + tmx = tix + tmy = tiy + end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing redundant points: %s",topairs(t,n)) + end + -- remove spikes + if n > 2 then + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] + + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= - vx2 then + n = n + 1 + t[n] = ti + else + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= - vy2 then + n = n + 1 + t[n] = ti + end + end + + tmx = tix + tmy = tiy + end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing spikes: %s",topairs(t,n)) + end + end + end + -- prune trailing points + if tm > n then + for i=tm,n+1,-1 do + t[i] = nil + end + end + if n > 1 then + local tf = t[1] + local tl = t[n] + local dx = tf[1] - tl[1] + local dy = tf[2] - tl[2] + if dx > eps or dx < - eps or dy > eps or dy < - eps then + -- different points + else + -- saves a point (as we -- cycle anyway) + t[n] = nil + n = n -1 + end + if trace_shapes then + report_shapes("removing cyclic endpoints: %s",topairs(t,n)) + end + end + return t +end + +local eps = 65536 + +-- The next function can introduce redundant points but these are removed later on +-- in the unspiker. It makes checking easier. + +local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) + local s = b.s + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape",kind) + end + return + end + s = s[realpage] + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape for page %s",kind,realpage) + end + return + end + local ns = #s + if ns == 0 then + if trace_shapes then + report_shapes("calculating %s area, empty shape for page %s",kind,realpage) + end + return + end + -- + if trace_shapes then + report_shapes("calculating %s area, using shape for page %s",kind,realpage) + end + -- it's a bit inefficient to use the par values and later compensate for b and + -- e but this keeps the code (loop) cleaner + local ph = p and p.h or 0 + local pd = p and p.d or 0 + -- + xmax = xmax + eps + xmin = xmin - eps + ymax = ymax + eps + ymin = ymin - eps + local ls = { } -- left shape + local rs = { } -- right shape + local pl = nil -- previous left x + local pr = nil -- previous right x + local n = 0 + local xl = nil + local xr = nil + local mh = ph -- min + local md = pd -- min + for i=1,ns do + local si = s[i] + local y = si[1] + local ll = si[4] -- can be sparse + if ll then + xl = ll + local rr = si[5] -- can be sparse + if rr then + xr = rr + end + end + if trace_ranges then + report_shapes("original : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) + end + if xl ~= xr then -- could be catched in the finalizer + local xm = xl + (xr - xl)/2 -- midpoint should be in region + if xm >= xmin and xm <= xmax and y >= ymin and y <= ymax then + local ht = si[2] -- can be sparse + if ht then + ph = ht + local dp = si[3] -- can be sparse + if dp then + pd = dp + end + end + local h = y + (ph < mh and mh or ph) + local d = y - (pd < md and md or pd) + if pl then + n = n + 1 + ls[n] = { pl, h } + rs[n] = { pr, h } + if trace_ranges then + report_shapes("paragraph : [%02i] xl=%p xr=%p y=%p",i,pl,pr,h) + end + end + n = n + 1 + ls[n] = { xl, h } + rs[n] = { xr, h } + if trace_ranges then + report_shapes("height : [%02i] xl=%p xr=%p y=%p",i,xl,xr,h) + end + n = n + 1 + ls[n] = { xl, d } + rs[n] = { xr, d } + if trace_ranges then + report_shapes("depth : [%02i] xl=%p xr=%p y=%p",i,xl,xr,d) + end + end + pl, pr = xl, xr + else + if trace_ranges then + report_shapes("ignored : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) + end + end + end + -- + if true and n > 0 then + -- use height of b and depth of e, maybe check for weird border + -- cases here + if fh then + local lsf = ls[1] + local rsf = rs[1] + if lsf[2] < fh then + lsf[2] = fh + end + if rsf[2] < fh then + rsf[2] = fh + end + end + if fd then + local lsl = ls[n] + local rsl = rs[n] + if lsl[2] > fd then + lsl[2] = fd + end + if rsl[2] > fd then + rsl[2] = fd + end + end + end + -- + for i=n,1,-1 do + n = n + 1 rs[n] = ls[i] + end + return rs +end + +local function singlepart(b,e,p,realpage,r,left,right) + local bx = b.x + local by = b.y + local ex = e.x + local ey = e.y + local rx = r.x + local ry = r.y + local bh = by + b.h + local bd = by - b.d + local eh = ey + e.h + local ed = ey - e.d + local rh = ry + r.h + local rd = ry - r.d + local rw = rx + r.w + if left then + rx = rx + left + rw = rw - right + end + if ex == rx then + -- We probably have a strut at the next line so we force a width + -- although of course it is better to move up. But as we have whitespace + -- (at least visually) injected then it's best to stress the issue. + ex = rw + end + local area + if by == ey then + if trace_shapes then + report_shapes("calculating single area, partial line") + end + area = { + { bx, bh }, + { ex, eh }, + { ex, ed }, + { bx, bd }, + } + elseif b.k == 2 then + area = { + { rx, bh }, + { rw, bh }, + { rw, ed }, + { rx, ed }, + } + else + area = shape("single",b,p,realpage,rx,rw,rd,rh,bh,ed) + end + if not area then + area = { + { bx, bh }, + { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, bd }, + { bx, bd }, + } + end + return { + location = "single", + region = r, + area = finish(area), + } +end + +local function firstpart(b,e,p,realpage,r,left,right) + local bx = b.x + local by = b.y + local rx = r.x + local ry = r.y + local bh = by + b.h + local bd = by - b.d + local rh = ry + r.h + local rd = ry - r.d + local rw = rx + r.w + if left then + rx = rx + left + rw = rw - right + end + local area = shape("first",b,p,realpage,rx,rw,rd,rh,bh,false) + if not area then + if b.k == 2 then + area = { + { rx, bh }, + { rw, bh }, + { rw, rd }, + { rx, rd }, + } + else + area = { + { bx, bh }, + { rw, bh }, + { rw, rd }, -- { rw, eh }, + { rx, rd }, -- { rx, ed }, + { rx, bd }, + { bx, bd }, + } + end + end + return { + location = "first", + region = r, + area = finish(area), + } +end + +local function middlepart(b,e,p,realpage,r,left,right) + local rx = r.x + local ry = r.y + local rh = ry + r.h + local rd = ry - r.d + local rw = rx + r.w + if left then + rx = rx + left + rw = rw - right + end + local area = shape("middle",b,p,realpage,rx,rw,rd,rh,false,false) + if not area then + area = { + { rw, rh }, + { rw, rd }, + { rx, rd }, + { rx, rh }, + } + end + return { + location = "middle", + region = r, + area = finish(area), + } +end + +local function lastpart(b,e,p,realpage,r,left,right) + local ex = e.x + local ey = e.y + local rx = r.x + local ry = r.y + local eh = ey + e.h + local ed = ey - e.d + local rh = ry + r.h + local rd = ry - r.d + local rw = rx + r.w + if left then + rx = rx + left + rw = rw - right + end + local area = shape("last",b,p,realpage,rx,rw,rd,rh,false,ed) + if not area then + if b.k == 2 then + area = { + { rw, rh }, + { rw, ed }, + { rx, ed }, + { rx, rh }, + } + else + area = { + { rw, rh }, -- { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, rh }, -- { rx, bd }, + } + end + end + return { + location = "last", + region = r, + area = finish(area), + } +end + +local function calculatemultipar(tag) + local collected = jobpositions.collected + local b = collected[f_b_tag(tag)] + local e = collected[f_e_tag(tag)] + if not b or not e then + report_shapes("invalid tag %a",tag) + return { } + end + local br = b.r + local er = e.r + if not br or not er then + report_shapes("invalid region for %a",tag) + return { } + end + local btag, bindex = lpegmatch(splitter,br) + local etag, eindex = lpegmatch(splitter,er) + if not bindex or not eindex or btag ~= etag then + report_shapes("invalid indices for %a",tag) + return { } + end + local bindex = tonumber(bindex) + local eindex = tonumber(eindex) + -- Here we compensate for columns (in tables): a table can have a set of column + -- entries and these are shared. We compensate left/right based on the columns + -- x and w but need to take the region into acount where the specification was + -- flushed and not the begin pos's region, because otherwise we get the wrong + -- compensation for asymetrical doublesided layouts. + local left = 0 + local right = 0 + local bc = b.c + local rc = bc and collected[bc] + if rc then + local tb = collected[rc.r] + if tb then + left = -(tb.x - rc.x) + right = (tb.w - rc.w - left) + end + end + -- Obeying intermediate changes of left/rightskip makes no sense as it will + -- look bad, so we only look at the begin situation. + local bn = b.n + local p = bn and collected[f_p_tag(bn)] -- par + if p then + left = left + (p.ls or 0) + right = right + (p.rs or 0) + end + -- + local bp = b.p -- page + if trace_shapes then + report_shapes("tag %a, left %p, right %p, par %s, page %s, column %s", + tag,left,right,bn or "-",bp or "-",bc or "-") + end + -- + if bindex == eindex then + return { + list = { [bp] = { singlepart(b,e,p,bp,collected[br],left,right) } }, + bpos = b, + epos = e, + } + else + local list = { + [bp] = { firstpart(b,e,p,bp,collected[br],left,right) }, + } + for i=bindex+1,eindex-1 do + br = f_tag_two(btag,i) + local r = collected[br] + if not r then + report_graphics("invalid middle for %a",br) + else + local rp = r.p -- page + local pp = list[rp] + local mp = middlepart(b,e,p,rp,r,left,right) + if pp then + pp[#pp+1] = mp + else + list[rp] = { mp } + end + end + end + local ep = e.p -- page + local pp = list[ep] + local lp = lastpart(b,e,p,ep,collected[er],left,right) + if pp then + pp[#pp+1] = lp + else + list[ep] = { lp } + end + return { + list = list, + bpos = b, + epos = e, + } + end +end + +local pbg = { } -- will move to pending + +local multilocs = { + single = 1, -- maybe 0 + first = 1, + middle = 2, + last = 3, +} + +-- if unknown context_abck : input mp-abck.mpiv ; fi ; + +local f_template_a = formatters[ [[ +path multiregs[], multipars[], multibox ; +string multikind[] ; +numeric multilocs[], nofmultipars ; +nofmultipars := %s ; +multibox := unitsquare xyscaled (%p,%p) ; +numeric par_strut_height, par_strut_depth, par_line_height ; +par_strut_height := %p ; +par_strut_depth := %p ; +par_line_height := %p ; +]] ] + +local f_template_b = formatters[ [[ +multilocs[%s] := %s ; +multikind[%s] := "%s" ; +multipars[%s] := (%--t--cycle) shifted - (%p,%p) ; +]] ] + +-- unspiked(simplified(%--t--cycle)) shifted - (%p,%p) ; + +local f_template_c = formatters[ [[ +setbounds currentpicture to multibox ; +]] ] + +local function freemultipar(pagedata,frees) -- ,k + -- if k == 3 then + -- -- tables have local regions + -- return + -- end + if not frees then + return + end + local nfree = #frees + if nfree == 0 then + return + end + for i=1,#pagedata do + local data = pagedata[i] + local area = data.area + + if area then + + local region = data.region + local y = 0 -- region.y + -- local x = region.x + local areas = { } + data.areas = areas + + local f_1 = { } + local n_1 = 0 + local f_2 = { } + local n_2 = 0 + for i=1,#frees do + local f = frees[i] + local k = f.k + if k == 1 then -- pag + n_1 = n_1 + 1 + f_1[n_1] = f + elseif k == 2 or k == 3 then -- par + n_2 = n_2 + 1 + f_2[n_2] = f + end + end + + local lineheight = tex.dimen.lineheight + + -- page floats + + local function check_one(free1,free2) + local temp = { } + local some = false + local top = (free2 and (y + free2.y + free2.h + (free2.to or 0))) or false + local bot = (free1 and (y + free1.y - free1.d - (free1.bo or 0))) or false + for i=1,#area do + local a = area[i] + local x = a[1] + local y = a[2] + if free2 and y <= top then + y = top + end + if free1 and y >= bot then + y = bot + end + if not some then + some = y + elseif some == true then + -- done + elseif y ~= some then + some = true + end + temp[i] = { x, y } + end + if some == true then + areas[#areas+1] = temp + end + end + + if n_1 > 0 then + check_one(false,f_1[1]) + for i=2,n_1 do + check_one(f_1[i-1],f_1[i]) + end + check_one(f_1[n_1],false) + end + + -- par floats + + if #areas == 0 then + areas[1] = area + end + + -- we can collect the coordinates first + + local function check_two(area,frees) + local ul = area[1] + local ur = area[2] + local lr = area[3] + local ll = area[4] + local ulx = ul[1] + local uly = ul[2] + local urx = ur[1] + local ury = ur[2] + local lrx = lr[1] + local lry = lr[2] + local llx = ll[1] + local lly = ll[2] + + local temp = { } + local n = 0 + local done = false + + for i=1,#frees do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 3 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, right") -- ok + end + n = n + 1 temp[n] = { xmin, ury } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, right") -- ok + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, right") + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, lry } + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, right") + end + n = n + 1 temp[n] = { xmin, uly } + n = n + 1 temp[n] = { xmin, lly } + done = true + else + -- case 0 + if trace_free then + report_free("case 0, nothing") + end + end + end + end + + if not done then + if trace_free then + report_free("no right shape") + end + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { lrx, lry } + n = n + 1 temp[n] = { llx, lly } + else + done = false + end + + for i=#frees,1,-1 do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 2 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, left") -- ok + end + n = n + 1 temp[n] = { ulx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, uly } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, left") -- ok + end + n = n + 1 temp[n] = { llx, lly } + n = n + 1 temp[n] = { llx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, uly } + done = true + else + -- case 0 + end + end + end + + if not done then + if trace_free then + report_free("no left shape") + end + n = n + 1 temp[n] = { llx, lly } + end + n = n + 1 temp[n] = { ulx, uly } + + return temp + end + + if n_2 > 0 then + for i=1,#areas do + local area = areas[i] + if #area == 4 then -- and also check type, must be pargaraph + areas[i] = check_two(area,f_2) + else + -- message that not yet supported + end + end + end + + for i=1,#areas do + finish(areas[i]) -- again + end + + end + + end +end + +local function fetchmultipar(n,anchor,page) + local a = jobpositions.collected[anchor] + if not a then + report_graphics("missing anchor %a",anchor) + else + local data = pbg[n] + if not data then + data = calculatemultipar(n) + pbg[n] = data -- can be replaced by register + -- register(data.list,n,anchor) + end + local list = data and data.list + if list then + local pagedata = list[page] + if pagedata then + local k = data.bpos.k + if k ~= 3 then + -- to be checked: no need in txt mode + freemultipar(pagedata,getfree(page)) + end + local nofmultipars = #pagedata + if trace_shapes then + report_graphics("fetching %a at page %s using anchor %a containing %s multipars", + n,page,anchor,nofmultipars) + end + local x = a.x + local y = a.y + local w = a.w + local h = a.h + local d = a.d + local bpos = data.bpos + local bh = bpos.h + local bd = bpos.d + local result = { false } -- slot 1 will be set later + local n = 0 + for i=1,nofmultipars do + local data = pagedata[i] + local location = data.location + local region = data.region + local areas = data.areas + if not areas then + areas = { data.area } + end + for i=1,#areas do + local area = areas[i] + for i=1,#area do + local a = area[i] + area[i] = f_pair(a[1],a[2]) + end + n = n + 1 + result[n+1] = f_template_b(n,multilocs[location],n,location,n,area,x,y) + end + end + data[page] = nil + result[1] = f_template_a(n,w,h+d,bh,bd,bh+bd) -- was delayed + result[n+2] = f_template_c() + return concat(result,"\n") + end + end + end + return f_template_a(0,0,0,0,0,0); +end + +backgrounds.fetchmultipar = fetchmultipar + +backgrounds.point = f_point +backgrounds.pair = f_pair +backgrounds.path = f_path + +-- n anchor page + +implement { + name = "fetchmultipar", + actions = { fetchmultipar, context }, + arguments = { "string", "string", "integer" } +} + +-- todo: use inject + +do + + local scanstring = mp.scan.string + + local f_template_a = formatters[ [[ + path posboxes[], posregions[] ; + numeric pospages[] ; + numeric nofposboxes ; + nofposboxes := %s ; + %t + ]] ] + + local f_template_b = formatters[ [[ + pospages[%s] := %s ; + posboxes[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; + posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; + ]] ] + + local function getposboxes(tags,anchor,page) -- no caching (yet) / page + local collected = jobpositions.collected + if type(tags) == "string" then + tags = utilities.parsers.settings_to_array(tags) + end + local list = { } + local nofboxes = 0 + for i=1,#tags do + local tag= tags[i] + local c = collected[tag] + if c then + local r = c.r + if anchor ~= r then + r = anchor + end + if r then + r = collected[r] + if r then + local rx = r.x + local ry = r.y + local rw = r.w + local rh = r.h + local rd = r.d + local cx = c.x - rx + local cy = c.y - ry + local cw = cx + c.w + local ch = cy + c.h + local cd = cy - c.d + nofboxes = nofboxes + 1 + list[nofboxes] = f_template_b( + nofboxes,c.p, + nofboxes,cx,ch,cw,ch,cw,cd,cx,cd, + nofboxes,0,rh,rw,rh,rw,rd,0,rd + ) + end + end + else + -- print("\n missing",tag) + end + end + return f_template_a(nofboxes,list) + end + + local namespace + + -- metapost.registerscript("var", function() + -- local name = scanstring() + -- if not namespace then + -- namespace = getmacro("??graphicvariable") + -- end + -- return getmacro(namespace .. getmacro("currentmpvariableclass") .. ":" .. name) + -- end + + metapost.registerscript("getposboxes", function() + local tags = scanstring() + local anchor = scanstring() + local page = nil + if tags == "self" then + if not namespace then + namespace = getmacro("??graphicvariable") + end + tags = getmacro(namespace .. getmacro("currentmpvariableclass") .. ":self") + end + if anchor == "anchor" then + anchor = getmacro("MPanchorid") -- brrr + end + if tags and anchor then + return getposboxes(tags,anchor,page) + end + end) + + implement { + name = "fetchposboxes", + arguments = { "string", "string", "integer" }, + actions = { getposboxes, context }, + } + +end + +local doifelse = commands.doifelse + +implement { + name = "doifelserangeonpage", + arguments = { "string", "string", "integer" }, + actions = function(first,last,page) + local c = jobpositions.collected + local f = c[first] + if f then + f = f.p + if f and f ~= true and page >= f then + local l = c[last] + if l then + l = l.p + doifelse(l and l ~= true and page <= l) + return + end + end + end + doifelse(false) + end +} diff --git a/tex/context/base/mkxl/anch-pgr.mkxl b/tex/context/base/mkxl/anch-pgr.mkxl index 6b0fef441..ec8f0e549 100644 --- a/tex/context/base/mkxl/anch-pgr.mkxl +++ b/tex/context/base/mkxl/anch-pgr.mkxl @@ -16,7 +16,7 @@ %D Before we come to graphics support, we have to make sure of the reference point %D on the page. The next macros do so and are hooked into the page building routine. -\registerctxluafile{anch-pgr}{} +\registerctxluafile{anch-pgr}{autosuffix} \unprotect diff --git a/tex/context/base/mkxl/back-ext.mkxl b/tex/context/base/mkxl/back-ext.mkxl index bba33335d..a3d9d2633 100644 --- a/tex/context/base/mkxl/back-ext.mkxl +++ b/tex/context/base/mkxl/back-ext.mkxl @@ -84,4 +84,12 @@ \permanent\protected\def\dostopclipping {\clf_stopclipping} +%D This wrapper is needed when you use code that messes with e.g. local color +%D directives, invisible for the rest of the machinery. It's only needed in very +%D special cases, like around the above scaler directives: + +\permanent\protected\edef\hcontainer{\hpack \s!direction\directionlefttoright \s!container\space} +\permanent\protected\edef\vcontainer{\vpack \s!direction\directionlefttoright \s!container\space} +\permanent\protected\edef\tcontainer{\tpack \s!direction\directionlefttoright \s!container\space} + \protect \endinput diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index a50137486..13ddba0fd 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.02.14 16:11} +\newcontextversion{2021.02.17 13:30} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index d628aa307..68860f7e5 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.02.14 16:11} +\immutable\edef\contextversion{2021.02.17 13:30} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/core-ini.mkxl b/tex/context/base/mkxl/core-ini.mkxl index ce6121061..de7c645b4 100644 --- a/tex/context/base/mkxl/core-ini.mkxl +++ b/tex/context/base/mkxl/core-ini.mkxl @@ -60,7 +60,7 @@ \newtoks \everyforgetall \newtoks \everycleanupfeatures \newtoks \everysimplifycommands -\newtoks \everypreroll +%newtoks \everypreroll \aliased\let\simplifiedcommands\everysimplifycommands % backward compatible, will stay as it's used in styles diff --git a/tex/context/base/mkxl/file-job.mklx b/tex/context/base/mkxl/file-job.mklx index d898a3c07..9fb14c9bf 100644 --- a/tex/context/base/mkxl/file-job.mklx +++ b/tex/context/base/mkxl/file-job.mklx @@ -271,6 +271,18 @@ [\c!before=\directsetup{\s!document:\v!start}, \c!after =\directsetup{\s!document:\v!stop}] +% to be discussed: +% +% \setupdocument +% [metadata:title=\documentvariable\c!title, +% metadata:subject=\documentvariable\c!subtitle, +% metadata:subtitle=\documentvariable\c!subtitle, +% metadata:author=\documentvariable\c!author, +% metadata:authors=\documentvariable\c!author, +% metadata:keyword=\documentvariable\c!keyword, +% metadata:keywords=\documentvariable\c!keyword, +% metadata:date=\documentvariable\c!date] + \def\syst_document_setup#1% {\directsetup{\doifelsesetups{\currentdocument:\v!start}\currentdocument\s!document:\v!start}} diff --git a/tex/context/base/mkxl/file-mod.lmt b/tex/context/base/mkxl/file-mod.lmt new file mode 100644 index 000000000..6af5d8816 --- /dev/null +++ b/tex/context/base/mkxl/file-mod.lmt @@ -0,0 +1,309 @@ +if not modules then modules = { } end modules ['file-mod'] = { + version = 1.001, + comment = "companion to file-mod.mkvi", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This module will be redone! For instance, the prefixes will move to data-* +-- as they arr sort of generic along with home:// etc/. + +-- context is not defined yet! todo! (we need to load tupp-fil after cld) +-- todo: move startreadingfile to lua and push regime there + +--[[ldx-- +

It's more convenient to manipulate filenames (paths) in + than in . These methods have counterparts +at the side.

+--ldx]]-- + +local format, find, concat, tonumber = string.format, string.find, table.concat, tonumber +local sortedhash = table.sortedhash +local basename = file.basename + +local trace_modules = false trackers .register("modules.loading", function(v) trace_modules = v end) +local permit_unprefixed = false directives.register("modules.permitunprefixed", function(v) permit_unprefixed = v end) + +local report = logs.reporter("modules") + +local commands = commands +local context = context +local implement = interfaces.implement + +local findbyscheme = resolvers.finders.byscheme -- use different one +local iterator = utilities.parsers.iterator + +-- modules can have a specific suffix or can specify one + +local prefixes = { + "m", -- module, extends functionality + "p", -- private code + "s", -- styles + "x", -- xml specific modules + -- "v", -- an old internal one for examples + "t", -- third party extensions +} + +-- the order might change and how about cld + +local suffixes = CONTEXTLMTXMODE > 0 and +{ + "mklx", -- preprocessed mkiv lmtx files + "mkxl", -- mkiv lmtx files + "mkvi", -- preprocessed mkiv files + "mkiv", -- mkiv files + "tex", -- normally source code files + "cld", -- context lua documents (often stand alone) + "lua", -- lua files +} + or +{ + "mkvi", + "mkiv", + "tex", + "cld", + "lua", +} + +-- This controls embedded overloads. Maybe at some point we will limit this to files in the +-- tree but on the other hand we don't need to be that strict. It is just an extra level +-- of protection. + +local setrunstate = tex.setrunstate +local level = 0 + +local function pushrunstate() + level = level + 1 + if level == 1 then + setrunstate(1) + end +end + +local function poprunstate() + if level == 1 then + setrunstate(3) + end + if level > 0 then + level = level - 1 + end +end + +luatex.pushrunstate = pushrunstate +luatex.poprunstate = poprunstate + +tex.setrunstate = function() end + +implement { name = "pushrunstate", public = true, protected = true, actions = pushrunstate } +implement { name = "poprunstate", public = true, protected = true, actions = poprunstate } + +-- Till here. + +local modstatus = { } +local missing = false + +local function usemodule(name,hasscheme) + local foundname + if hasscheme then + -- no auto suffix as http will return a home page or error page + -- so we only add one if missing + local fullname = file.addsuffix(name,"tex") + if trace_modules then + report("checking url %a",fullname) + end + foundname = resolvers.findtexfile(fullname) or "" + elseif file.suffix(name) ~= "" then + if trace_modules then + report("checking file %a",name) + end + foundname = findbyscheme("any",name) or "" + else + for i=1,#suffixes do + local fullname = file.addsuffix(name,suffixes[i]) + if trace_modules then + report("checking file %a",fullname) + end + foundname = findbyscheme("any",fullname) or "" + if foundname ~= "" then + break + end + end + end + if foundname ~= "" then + if trace_modules then + report("loading file %a",foundname) + end + context.pushrunstate() + context.startreadingfile() + resolvers.jobs.usefile(foundname,true) -- once, notext + -- context.input(foundname) + context.stopreadingfile() + context.poprunstate() + return true + else + return false + end +end + +function environment.usemodules(prefix,askedname,truename) + local truename = truename or environment.truefilename(askedname) or askedname + if truename and truename ~= "" then + local hasprefix = prefix and prefix ~= "" + local hashname = ((hasprefix and prefix) or "*") .. "-" .. truename + local status = modstatus[hashname] or false -- yet unset + if status == 0 then + -- not found + elseif status == 1 then + status = status + 1 + else + if trace_modules then + report("locating, prefix %a, askedname %a, truename %a",prefix,askedname,truename) + end + local hasscheme = url.hasscheme(truename) + if hasscheme then + -- no prefix and suffix done + if usemodule(truename,true) then + status = 1 + else + status = 0 + end + elseif hasprefix then + if usemodule(prefix .. "-" .. truename) then + status = 1 + else + status = 0 + end + else + for i=1,#prefixes do + -- todo: reconstruct name i.e. basename + local thename = prefixes[i] .. "-" .. truename + if usemodule(thename) then + status = 1 + break + end + end + if status then + -- ok, don't change + elseif find(truename,"-",1,true) and usemodule(truename) then + -- assume a user namespace + report("using user prefixed file %a",truename) + status = 1 + elseif permit_unprefixed and usemodule(truename) then + report("using unprefixed file %a",truename) + status = 1 + else + status = 0 + end + end + end + if status == 0 then + missing = true + report("%a is not found",askedname) + elseif status == 1 then + report("%a is loaded",trace_modules and truename or askedname) + else + report("%a is already loaded",trace_modules and truename or askedname) + end + modstatus[hashname] = status + end +end + +statistics.register("loaded tex modules", function() + if next(modstatus) then + local t, f, nt, nf = { }, { }, 0, 0 + for k, v in sortedhash(modstatus) do + local b = basename(k) + if v == 0 then + nf = nf + 1 + f[nf] = b + else + nt = nt + 1 + t[nt] = b + end + end + if nf == 0 then + return format("%s requested, all found (%s)",nt,concat(t," ")) + elseif nt == 0 then + return format("%s requested, all missing (%s)",nf,concat(f," ")) + else + return format("%s requested, %s found (%s), %s missing (%s)",nt+nf,nt,concat(t," "),nf,concat(f," ")) + end + else + return nil + end +end) + +logs.registerfinalactions(function() + logs.startfilelogging(report,"used modules") + for k, v in sortedhash(modstatus) do + report(v == 0 and "missing: %s" or "loaded : %s",basename(k)) + end + logs.stopfilelogging() + if missing and logs.loggingerrors() then + logs.starterrorlogging(report,"missing modules") + for k, v in sortedhash(modstatus) do + if v == 0 then + report("%w%s",6,basename(k)) + end + end + logs.stoperrorlogging() + end +end) + +-- moved from syst-lua.lua: + +local lpegmatch = lpeg.match +local splitter = lpeg.tsplitter(lpeg.S(". "),tonumber) + +function environment.comparedversion(one,two) -- one >= two + if not two or two == "" then + one, two = environment.version, one + elseif one == "" then + one = environment.version + end + one = lpegmatch(splitter,one) + two = lpegmatch(splitter,two) + one = (one[1] or 0) * 10000 + (one[2] or 0) * 100 + (one[3] or 0) + two = (two[1] or 0) * 10000 + (two[2] or 0) * 100 + (two[3] or 0) + if one < two then + return -1 + elseif one > two then + return 1 + else + return 0 + end +end + +environment.comparedversion = comparedversion + + +function environment.useluamodule(list) + for filename in iterator(list) do + environment.loadluafile(filename) + end +end + +implement { + name = "usemodules", + actions = environment.usemodules, + arguments = "2 strings", +} + +implement { + name = "doifelseolderversion", + actions = function(one,two) commands.doifelse(comparedversion(one,two) >= 0) end, + arguments = "2 strings" +} + +implement { + name = "useluamodule", + actions = environment.useluamodule, + arguments = "string" +} + +implement { + name = "loadluamodule", + actions = function(name) dofile(resolvers.findctxfile(name)) end, -- hack + arguments = "string" +} + diff --git a/tex/context/base/mkxl/file-mod.mklx b/tex/context/base/mkxl/file-mod.mklx index c353b8c61..24471e30f 100644 --- a/tex/context/base/mkxl/file-mod.mklx +++ b/tex/context/base/mkxl/file-mod.mklx @@ -15,7 +15,7 @@ \unprotect -\registerctxluafile{file-mod}{} +\registerctxluafile{file-mod}{autosuffix} %D \macros %D {usemodule} diff --git a/tex/context/base/mkxl/grph-trf.mkxl b/tex/context/base/mkxl/grph-trf.mkxl index 550eb6f96..356b4a8f8 100644 --- a/tex/context/base/mkxl/grph-trf.mkxl +++ b/tex/context/base/mkxl/grph-trf.mkxl @@ -185,7 +185,7 @@ \fi} \def\grph_scale_apply_yes - {\setbox\nextbox\naturalhpack + {\setbox\nextbox\hcontainer {\dostartscaling \finalscaleboxxscale \finalscaleboxyscale \smashedbox\nextbox \dostopscaling}% @@ -656,7 +656,7 @@ \wd\nextbox\zeropoint \ht\nextbox\zeropoint \dp\nextbox\zeropoint - \setbox\nextbox\naturalhpack + \setbox\nextbox\hcontainer {\advance\scratchwidth \dimexpr\clippingparameter\c!leftoffset +\clippingparameter\c!rightoffset\relax \advance\scratchheight\dimexpr\clippingparameter\c!bottomoffset+\clippingparameter\c!topoffset \relax \dostartclipping{\clippingparameter\c!mp}\scratchwidth\scratchheight @@ -942,7 +942,7 @@ % \setbox\nextbox\naturalvpack to \d_grph_rotate_y_size {\vfilll - \naturalhpack to \d_grph_rotate_x_size + \hcontainer to \d_grph_rotate_x_size {\dostartrotation\p_rotation_rotation \wd\nextbox\zeropoint \ht\nextbox\zeropoint diff --git a/tex/context/base/mkxl/luat-cod.lmt b/tex/context/base/mkxl/luat-cod.lmt index a1f46b1ae..49d90777d 100644 --- a/tex/context/base/mkxl/luat-cod.lmt +++ b/tex/context/base/mkxl/luat-cod.lmt @@ -142,17 +142,15 @@ local targetpath = "." -- pdftex went beyond "9" but anyway we test for it if LUATEXENGINE == nil then - LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) - or (find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex") + LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) or "luametatex" end if LUATEXVERSION == nil then - LUATEXVERSION = status.luatex_version/100 - + tonumber(status.luatex_revision)/10000 + LUATEXVERSION = status.luatex_version/100 + tonumber(status.luatex_revision)/10000 end if CONTEXTLMTXMODE == nil then - CONTEXTLMTXMODE = LUATEXENGINE == "luametatex" and 1 or 0 + CONTEXTLMTXMODE = 1 end if LUATEXFUNCTIONALITY == nil then @@ -164,11 +162,11 @@ if LUATEXFORMATID == nil then end if JITSUPPORTED == nil then - JITSUPPORTED = LUATEXENGINE == "luajittex" or jit -- "or jit" can go + JITSUPPORTED = false end if INITEXMODE == nil then - INITEXMODE = status.ini_version + INITEXMODE = status.run_state == 0 -- initializing updating production end environment.luatexengine = LUATEXENGINE diff --git a/tex/context/base/mkxl/luat-ini.lmt b/tex/context/base/mkxl/luat-ini.lmt new file mode 100644 index 000000000..cec0161e7 --- /dev/null +++ b/tex/context/base/mkxl/luat-ini.lmt @@ -0,0 +1,46 @@ +if not modules then modules = { } end modules ['luat-ini'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

We cannot load anything yet. However what we will do us reserve a few tables. +These can be used for runtime user data or third party modules and will not be +cluttered by macro package code.

+--ldx]]-- + +userdata = userdata or { } -- for users (e.g. functions etc) +thirddata = thirddata or { } -- only for third party modules +moduledata = moduledata or { } -- only for development team +documentdata = documentdata or { } -- for users (e.g. raw data) +parametersets = parametersets or { } -- for special purposes + +table.setmetatableindex(moduledata,"table") +table.setmetatableindex(thirddata, "table") + +if not global then + global = _G +end + +LUATEXVERSION = status.luatex_version/100 + + tonumber(status.luatex_revision)/10000 + +LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) + or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex") + +LUATEXFUNCTIONALITY = status.development_id or 6346 + +LUATEXFORMATID = status.format_id or 0 + +JITSUPPORTED = LUATEXENGINE == "luajittex" or jit + +INITEXMODE = status.ini_version + +CONTEXTLMTXMODE = CONTEXTLMTXMODE or (LUATEXENGINE == "luametatex" and 1) or 0 + +function os.setlocale() + -- no need for a message +end diff --git a/tex/context/base/mkxl/luat-lib.mkxl b/tex/context/base/mkxl/luat-lib.mkxl index f0b25c070..24020b9a6 100644 --- a/tex/context/base/mkxl/luat-lib.mkxl +++ b/tex/context/base/mkxl/luat-lib.mkxl @@ -77,7 +77,7 @@ \registerctxluafile{luat-cnf}{} \registerctxluafile{luat-lua}{} \registerctxluafile{luat-sto}{} -\registerctxluafile{luat-ini}{} +\registerctxluafile{luat-ini}{autosuffix} \registerctxluafile{util-env}{} \registerctxluafile{luat-env}{} \registerctxluafile{luat-exe}{} % simplified diff --git a/tex/context/base/mkxl/meta-ini.mkxl b/tex/context/base/mkxl/meta-ini.mkxl index 6b79c39c9..2100912d7 100644 --- a/tex/context/base/mkxl/meta-ini.mkxl +++ b/tex/context/base/mkxl/meta-ini.mkxl @@ -666,7 +666,7 @@ \protected\def\meta_reuse_box#1#2#3#4#5% space delimiting would save some tokens {\MPllx#2\MPlly#3\MPurx#4\MPury#5% - \hpack{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent + \hpack container{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent \protected\def\meta_use_box {\setunreferencedobject{MP}} diff --git a/tex/context/base/mkxl/mlib-fio.lmt b/tex/context/base/mkxl/mlib-fio.lmt index 92efcdf48..15d993d92 100644 --- a/tex/context/base/mkxl/mlib-fio.lmt +++ b/tex/context/base/mkxl/mlib-fio.lmt @@ -224,10 +224,10 @@ mplib.propertycodes = propertycodes local report = logs.reporter("metafun", "log") local function overload(property,name) - if overloadmode then - local iserror = + if overloadmode and property >= 0 then -- turn of warning after format is loaded - report("overloading %s %a",propertycodes[property] or "unknown", name) + local code = propertycodes[property] or "unknown" + report("overloading %s %a",code, name) -- no overload permitted if overloadmode == "error" then luatex.abort() diff --git a/tex/context/base/mkxl/mlib-lmt.lmt b/tex/context/base/mkxl/mlib-lmt.lmt index cf60774f3..e44674d13 100644 --- a/tex/context/base/mkxl/mlib-lmt.lmt +++ b/tex/context/base/mkxl/mlib-lmt.lmt @@ -163,11 +163,12 @@ registerscript("scrutenized", function() local x1 = round(p[1][1]) local y1 = round(p[1][2]) local n = 1 + local m = #p local t = { p[1], cycle = p.cycle } - for i=2,#p do + for i=2,m-1 do local pi = p[i] - local x2 = round(pi[1]) - local y2 = round(pi[2]) + local x2 = r(pi[1]) + local y2 = r(pi[2]) if x1 ~= x2 or y1 ~= y2 then n = n + 1 t[n] = p[i] @@ -175,5 +176,15 @@ registerscript("scrutenized", function() y1 = y2 end end - injectpath(t) + local x1 = r(p[1][1]) + local y1 = r(p[1][2]) + local x2 = r(p[m][1]) + local y2 = r(p[m][2]) + if x1 ~= x2 or y1 ~= y2 then + n = n + 1 + t[n] = p[m] + end + mp.path(t) + -- injectpath(t) end) + diff --git a/tex/context/base/mkxl/mlib-pps.mkxl b/tex/context/base/mkxl/mlib-pps.mkxl index 11d7e5672..2fa721445 100644 --- a/tex/context/base/mkxl/mlib-pps.mkxl +++ b/tex/context/base/mkxl/mlib-pps.mkxl @@ -78,7 +78,13 @@ \permanent\permanent\protected\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}}} + \vpack to \zeropoint + {\vss + %\hpack to \zeropoint \s!container + \hcontainer to \zeropoint + {\scale + [\c!sx=#2,\c!sy=#3]% + {\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}} \let\mlib_sx\!!zerocount % set at the lua end \let\mlib_sy\!!zerocount % set at the lua end @@ -86,7 +92,10 @@ \permanent\protected\def\MPLIBfigure#1#2% {\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}% \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint - \vpack to \zeropoint{\vss\hpack to \zeropoint{\fastsxsy{\mlib_sx}{\mlib_sy}{\box\scratchbox}\hss}}} + \vpack to \zeropoint + {\vss + \hpack to \zeropoint + {\fastsxsy{\mlib_sx}{\mlib_sy}{\box\scratchbox}\hss}}} % horrible (we could inline scale and matrix code): @@ -96,7 +105,8 @@ \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop ... will be changed to proper lua call (avoid small numbers) \vpack to \zeropoint\bgroup \vss - \hpack to \zeropoint \bgroup + %\hpack to \zeropoint \s!container \bgroup + \hcontainer to \zeropoint \bgroup % \scale[\c!sx=#8,\c!sy=#9]{\raise\dp\MPtextbox\box\MPtextbox}% % \scale[\c!sx=#8,\c!sy=#9,\c!depth=\v!no]{\box\MPtextbox}% \fastsxsy{#8}{#9}{\raise\dp\MPtextbox\box\MPtextbox}% diff --git a/tex/context/base/mkxl/mult-sys.mkxl b/tex/context/base/mkxl/mult-sys.mkxl index 9b48c7a99..4a86fb21e 100644 --- a/tex/context/base/mkxl/mult-sys.mkxl +++ b/tex/context/base/mkxl/mult-sys.mkxl @@ -149,6 +149,7 @@ \definesystemconstant {command} \definesystemconstant {compare} \definesystemconstant {complex} +\definesystemconstant {container} \definesystemconstant {counter} \definesystemconstant {cramped} \definesystemconstant {current} diff --git a/tex/context/base/mkxl/node-fin.lmt b/tex/context/base/mkxl/node-fin.lmt index a9180ddb2..3f88c59fe 100644 --- a/tex/context/base/mkxl/node-fin.lmt +++ b/tex/context/base/mkxl/node-fin.lmt @@ -50,6 +50,8 @@ local boxrule_code = rulecodes.box local imagerule_code = rulecodes.image local emptyrule_code = rulecodes.empty +local container_code = nodes.listcodes.container + local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local glue_code = nodecodes.glue @@ -195,6 +197,9 @@ local function process(attribute,head,inheritance,default) -- one attribute elseif id == hlist_code or id == vlist_code then -- tricky checking local outer + if subtype == container_code then + check = true + end if getorientation(stack) then outer = getattr(stack,attribute) if outer then @@ -308,6 +313,9 @@ local function simple(attribute,head) check = true leader = content elseif id == hlist_code or id == vlist_code then + if subtype == container_code then + check = true + end if getorientation(stack) then local outer = getattr(stack,attribute) if outer then @@ -384,6 +392,9 @@ end -- leader = content -- getleader(stack) -- elseif id == hlist_code or id == vlist_code then -- -- tricky checking +-- if subtype == container_code then +-- check = true +-- end -- local outer -- if getorientation(stack) then -- outer = getattr(stack,attribute) @@ -506,6 +517,9 @@ local function selective(attribute,head,inheritance,default) -- two attributes leader = content -- getleader(stack) elseif id == hlist_code or id == vlist_code then -- tricky checking + if subtype == container_code then + check = true + end local outer, s if getorientation(stack) then outer, s = getattrs(stack,attribute,nsselector) @@ -642,6 +656,9 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, if content then -- the problem is that broken lines gets the attribute which can be a later one local list + if subtype == container_code then + check = true + end if nslistwise then local a = getattr(stack,attribute) if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below @@ -730,6 +747,9 @@ end -- local content = getlist(current) -- if content then -- local list +-- if subtype == container_code then +-- check = true +-- end -- if nslistwise then -- local a = getattr(current,attribute) -- if a and attrib ~= a and nslistwise[a] then -- viewerlayer @@ -821,6 +841,9 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, check = true elseif id == hlist_code or id == vlist_code then local list + if subtype == container_code then + check = true + end if nslistwise then local a = getattr(current,attribute) if a and attrib ~= a and nslistwise[a] then -- viewerlayer diff --git a/tex/context/base/mkxl/scrn-ini.mklx b/tex/context/base/mkxl/scrn-ini.mklx index bc32073b9..c0246bc83 100644 --- a/tex/context/base/mkxl/scrn-ini.mklx +++ b/tex/context/base/mkxl/scrn-ini.mklx @@ -56,6 +56,13 @@ \setupinteraction [\c!state=\v!stop] +\setupinteraction + [\c!title=, + \c!subtitle=, + \c!author=, + \c!keyword=, + \c!date=] + \appendtoks \setupinteraction % todo: remember info at the lua end (already possible) \to \everyjob @@ -177,52 +184,52 @@ %D Identity +% \newconditional\c_scrn_identity_preroll +% +% \installtexdirective +% {interaction.identity.preroll} +% {\settrue \c_scrn_identity_preroll} +% {\setfalse\c_scrn_identity_preroll} +% +% \def\scrn_identity_prerolled#1% +% {\begingroup +% \edef\tempstring{\interactionparameter#1}% +% \ifempty\tempstring +% \endgroup +% \else +% \the\everypreroll +% \nodestostring\tempstring{\tempstring}% +% \normalexpanded{\endgroup\setexpandedinteractionparameter{#1}{\tempstring}}% +% \fi} +% % \def\scrn_identity_synchronize -% {\clf_setupidentity +% {\begingroup +% \ifconditional\c_scrn_identity_preroll +% \scrn_identity_prerolled\c!title +% \scrn_identity_prerolled\c!subtitle +% \scrn_identity_prerolled\c!author +% \scrn_identity_prerolled\c!date +% \scrn_identity_prerolled\c!keyword +% \fi +% \clf_setupidentity % title {\interactionparameter\c!title}% % subtitle {\interactionparameter\c!subtitle}% % author {\interactionparameter\c!author}% % % creator {ConTeXt - \contextversion}% % date {\interactionparameter\c!date}% % keywords {\interactionparameter\c!keyword}% -% \relax} - -\newconditional\c_scrn_identity_preroll - -\installtexdirective - {interaction.identity.preroll} - {\settrue \c_scrn_identity_preroll} - {\setfalse\c_scrn_identity_preroll} - -\def\scrn_identity_prerolled#1% - {\begingroup - \edef\tempstring{\interactionparameter#1}% - \ifempty\tempstring - \endgroup - \else - \the\everypreroll - \nodestostring\tempstring{\tempstring}% - \normalexpanded{\endgroup\setexpandedinteractionparameter{#1}{\tempstring}}% - \fi} +% \relax +% \endgroup} \def\scrn_identity_synchronize - {\begingroup - \ifconditional\c_scrn_identity_preroll - \scrn_identity_prerolled\c!title - \scrn_identity_prerolled\c!subtitle - \scrn_identity_prerolled\c!author - \scrn_identity_prerolled\c!date - \scrn_identity_prerolled\c!keyword - \fi - \clf_setupidentity - title {\interactionparameter\c!title}% - subtitle {\interactionparameter\c!subtitle}% - author {\interactionparameter\c!author}% - % creator {ConTeXt - \contextversion}% - date {\interactionparameter\c!date}% - keywords {\interactionparameter\c!keyword}% - \relax - \endgroup} + {\clf_setupidentity + title {\prerolltostring{\interactionparameter\c!title}}% + subtitle {\prerolltostring{\interactionparameter\c!subtitle}}% + author {\prerolltostring{\interactionparameter\c!author}}% + % creator {ConTeXt - \contextversion}% fixed + date {\prerolltostring{\interactionparameter\c!date}}% + keywords {\prerolltostring{\interactionparameter\c!keyword}}% + \relax} \appendtoks \scrn_identity_synchronize @@ -244,11 +251,4 @@ \scrn_identity_document {date}\c!date \to \everystartdocument % or stop -\setupinteraction - [\c!title=, - \c!subtitle=, - \c!author=, - \c!keyword=, - \c!date=] - \protect \endinput diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl index b8c1d6dc8..78d09295d 100644 --- a/tex/context/base/mkxl/spac-ali.mkxl +++ b/tex/context/base/mkxl/spac-ali.mkxl @@ -737,6 +737,10 @@ %defcsname\??aligncommand ...\endcsname{\toksapp\t_spac_align_collected{\nopenalties}} %defcsname\??aligncommand ...\endcsname{\toksapp\t_spac_align_collected{\setdefaultpenalties}} +% experiment + +\defcsname\??aligncommand\v!always\endcsname{\toksapp\t_spac_align_collected{\bitwiseflip\hyphenationmode\forcecheckhyphenationmodecode}} + \definehspace [\v!final] [\emspaceamount] \def\spac_align_flush_parfill diff --git a/tex/context/base/mkxl/spac-par.mkxl b/tex/context/base/mkxl/spac-par.mkxl index 808043cb6..134a60e2a 100644 --- a/tex/context/base/mkxl/spac-par.mkxl +++ b/tex/context/base/mkxl/spac-par.mkxl @@ -51,32 +51,37 @@ + \frozenshapecode \relax -\setnewconstant\frozenparagraphdefault\numexpr - \frozenhsizecode % \hsize - + \frozenskipcode % \leftskip \rightskip - + \frozenhangcode % \hangindent \hangafter - + \frozenindentcode % \parindent - + \frozenparfillcode % \parfillskip \parfillleftskip - + \frozenadjustcode % \adjustspacing - + \frozenprotrudecode % \protrudechars - + \frozentolerancecode % \tolerance \pretolerance - + \frozenstretchcode % \emergcystretch - + \frozenloosenesscode % \looseness - + \frozenlastlinecode % \lastlinefit - + \frozenlinepenaltycode % \linepenalty \interlinepenalty \interlinepenalties - + \frozenclubpenaltycode % \clubpenalty \clubpenalties - + \frozenwidowpenaltycode % \widowpenalty \widowpenalties - + \frozendisplaypenaltycode % \displaypenalty \displaypenalties - + \frozenbrokenpenaltycode % \brokenpenalty - + \frozendemeritscode % \doublehyphendemerits \finalhyphendemerits \adjdemerits - + \frozenshapecode % \parshape - % \frozenlinecode % \baselineskip \lineskip \lineskiplimit -\relax - \setnewconstant\paragraphlinecodes\numexpr \frozenlinecode \relax +\setnewconstant\paragraphhyphenationcodes\numexpr + \frozenhyphenationcode +\relax + +\setnewconstant\frozenparagraphdefault\numexpr + \frozenhsizecode % \hsize + + \frozenskipcode % \leftskip \rightskip + + \frozenhangcode % \hangindent \hangafter + + \frozenindentcode % \parindent + + \frozenparfillcode % \parfillskip \parfillleftskip + + \frozenadjustcode % \adjustspacing + + \frozenprotrudecode % \protrudechars + + \frozentolerancecode % \tolerance \pretolerance + + \frozenstretchcode % \emergcystretch + + \frozenloosenesscode % \looseness + + \frozenlastlinecode % \lastlinefit + + \frozenlinepenaltycode % \linepenalty \interlinepenalty \interlinepenalties + + \frozenclubpenaltycode % \clubpenalty \clubpenalties + + \frozenwidowpenaltycode % \widowpenalty \widowpenalties + + \frozendisplaypenaltycode % \displaypenalty \displaypenalties + + \frozenbrokenpenaltycode % \brokenpenalty + + \frozendemeritscode % \doublehyphendemerits \finalhyphendemerits \adjdemerits + + \frozenshapecode % \parshape + % \frozenlinecode % \baselineskip \lineskip \lineskiplimit + + \frozenhyphenationcode % \hyphenationmode +\relax + \permanent\protected\def\freezeparagraphproperties {\snapshotpar\frozenparagraphdefault} \permanent\protected\def\defrostparagraphproperties{\snapshotpar\zerocount} diff --git a/tex/context/base/mkxl/strc-sec.mkxl b/tex/context/base/mkxl/strc-sec.mkxl index 1175aed45..4e6464db4 100644 --- a/tex/context/base/mkxl/strc-sec.mkxl +++ b/tex/context/base/mkxl/strc-sec.mkxl @@ -111,26 +111,6 @@ \mutable\let\currentheadrenderingsetup \empty \mutable\let\currentheadtext \empty -% The next directive only makes sense when we have sort of garanteed outcome (math is not so -% nice for instance). -% -% \enabledirectives[references.bookmarks.preroll] - -\newconditional\c_strc_bookmarks_preroll - -\installtexdirective - {references.bookmarks.preroll} - {\settrue \c_strc_bookmarks_preroll} - {\setfalse\c_strc_bookmarks_preroll} - -\def\strc_sectioning_autobookmark#1% - {\begingroup - % \settrialtypesetting - \the\everypreroll - \nodestostring\tempstring{#1}% - \glet\currentstructurebookmark\tempstring - \endgroup} - % zeros: % % \setuphead[subsection][criterium=all] @@ -166,9 +146,9 @@ \xdef\currentstructurelist {\structureparameter\c!list}% \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}% \xmlstopraw - \iflocation \ifempty\currentstructurebookmark \ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark\currentstructuretitle - \fi \fi \fi + \iflocation \ifempty\currentstructurebookmark + \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}% + \fi \fi \ifempty\currentstructurelist \glet\currentstructurelist\currentstructuretitle \fi @@ -180,9 +160,9 @@ \xdef\currentstructuremarking {\structureparameter\c!marking}% \xdef\currentstructurelist {\structureparameter\c!list}% \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}% - \iflocation \ifempty\currentstructurebookmark \ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark\currentstructuretitle - \fi \fi \fi + \iflocation \ifempty\currentstructurebookmark + \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}% + \fi \fi \else \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% \xdef\currentstructurebookmark {\detokenizedstructureparameter\c!bookmark}% @@ -190,14 +170,7 @@ \xdef\currentstructurelist {\detokenizedstructureparameter\c!list}% \xdef\currentstructurereferencetext{\detokenizedstructureparameter\c!referencetext}% \iflocation \ifempty\currentstructurebookmark - \ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark{\structureparameter\c!title}% - \else - \begingroup - \simplifycommands - \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% - \endgroup - \fi + \xdef\currentstructurebookmark{\prerolltostring{\structureparameter\c!title}}% \fi \fi \fi \ifempty\currentstructurelist @@ -205,6 +178,9 @@ \fi \glet\currentstructurecoding\s!tex \fi + \iflocation \ifempty\currentstructurebookmark \orelse \ifx\currentstructurebookmark\currentstructuretitle \else + \showmessage\m!structures3{\currentstructurebookmark}% + \fi \fi \setnextinternalreference \storeinternalreference\currentstructurename{\the\locationcount}% \strc_sectioning_set_reference_prefix diff --git a/tex/context/base/mkxl/supp-box.lmt b/tex/context/base/mkxl/supp-box.lmt index 206529bae..e1feba99d 100644 --- a/tex/context/base/mkxl/supp-box.lmt +++ b/tex/context/base/mkxl/supp-box.lmt @@ -380,6 +380,7 @@ implement { implement { name = "boxtostring", arguments = "integer", + public = true, actions = function(n) context.puretext(nodes.toutf(texgetbox(n).list)) -- helper is defined later end diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl index 3f8739c42..ee6ef97e6 100644 --- a/tex/context/base/mkxl/supp-box.mkxl +++ b/tex/context/base/mkxl/supp-box.mkxl @@ -2656,10 +2656,41 @@ %D A bit dirty: +% \permanent\protected\def\nodestostring#1#2% more tolerant for #2=\cs +% {\begingroup +% \setbox\nextbox\hbox{#2}% +% \normalexpanded{\endgroup\edef\noexpand#1{\boxtostring\nextbox}}} +% +% \permanent\def\tostring +% {\beginlocalcontrol +% \dowithnextbox{\endlocalcontrol\boxtostring\nextbox}\hbox} +% +% \permanent\def\tostring +% {\beginlocalcontrol\begingroup +% \dowithnextbox{\normalexpanded{\endgroup\endlocalcontrol\boxtostring\nextbox}}\hbox} + +\def\syst_boxes_contenttostring + {\normalexpanded{\endgroup\endlocalcontrol\boxtostring\nextbox}} + +\permanent\def\contenttostring + {\beginlocalcontrol\begingroup + \dowithnextboxcs\syst_boxes_contenttostring\hbox} + +\newtoks\everypreroll + +\let\prerolltostring\firstofoneargument % we need to bypass initializations + +\appendtoks + \permanent\def\prerolltostring + {\beginlocalcontrol\begingroup + \the\everypreroll + \dowithnextboxcs\syst_boxes_contenttostring\hbox} +\to \everydump + +% depricated: + \permanent\protected\def\nodestostring#1#2% more tolerant for #2=\cs - {\begingroup - \setbox\nextbox\hbox{#2}% - \normalexpanded{\endgroup\edef\noexpand#1{\clf_boxtostring\nextbox}}} + {\edef#2{\contenttostring{#1}}} %D Even more dirty: diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl index 781515615..0efbaaaa7 100644 --- a/tex/context/base/mkxl/syst-ini.mkxl +++ b/tex/context/base/mkxl/syst-ini.mkxl @@ -726,6 +726,9 @@ \aliased\let\popoverloadmode\relax +\let\pushrunstate\relax % will be defined later +\let\poprunstate \relax % will be defined later + \newtoks\everydump \pushoverloadmode diff --git a/tex/context/base/mkxl/typo-mar.mkxl b/tex/context/base/mkxl/typo-mar.mkxl index daed1ee3d..4862ee671 100644 --- a/tex/context/base/mkxl/typo-mar.mkxl +++ b/tex/context/base/mkxl/typo-mar.mkxl @@ -195,7 +195,9 @@ \ifparameter#dataparameters\or \setupcurrentmargindata[#dataparameters]% \fi - \doifelsenothing{#content}\donefalse\donetrue + % \doifelsenothing{#content}\donefalse\donetrue + % \doifelsetext{#content}\donetrue\donefalse + \ifparameter#content\donefalse\or\donetrue\else\donefalse\fi \global\advance\c_typo_margins_n\plusone \ifdone \edef\currentmarginreference{\margindataparameter\c!reference}% diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index e64127e57..f45b5a574 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -780,6 +780,8 @@ + + @@ -1124,6 +1126,7 @@ + diff --git a/tex/context/modules/mkiv/m-tikz.mkiv b/tex/context/modules/mkiv/m-tikz.mkiv index e04d53156..9267f90d4 100644 --- a/tex/context/modules/mkiv/m-tikz.mkiv +++ b/tex/context/modules/mkiv/m-tikz.mkiv @@ -7,35 +7,69 @@ \protect \fi -\ifcase\contextlmtxmode \else - \overloadmode\zerocount -\fi -\pushcatcodetable +\pushoverloadmode + + \pushcatcodetable - \setcatcodetable\texcatcodes + \setcatcodetable\texcatcodes - \catcode`\@=11 - \catcode`\|=12 - \catcode`\!=12 + \catcode`\@=11 + \catcode`\|=12 + \catcode`\!=12 - \input t-pgf.tex - \input t-pgffor.tex - \input tikz.code.tex + \input t-pgf.tex + \input t-pgffor.tex + \input tikz.code.tex -\popcatcodetable + \popcatcodetable -\protected\def\tikzerrormessage#1#2#3% +\popoverloadmode + +\permanent\protected\def\tikzerrormessage#1#2#3% {\writestatus{#1}{#2}} -\protected\def\starttikzpicture - {\begingroup - \ifdefined\PackageError\else \let\PackageError\tikzerrormessage \fi - \overloadmode\zerocount - \tikzpicture} +\ifcase\contextlmtxmode + + \let\starttikzsettings\relax + \let\stoptikzsettings \relax + + \protected\def\starttikzpicture + {% \dontleavehmode + \begingroup + \ifdefined\PackageError\else \let\PackageError\tikzerrormessage \fi + \tikzpicture} + + \protected\def\stoptikzpicture + {\endtikzpicture + \endgroup} + +\else + + % for now: -\protected\def\stoptikzpicture - {\endtikzpicture - \endgroup} + \overloadmode\zerocount + + % but this will be mandate for settings outside the start .. stop + + \permanent\protected\def\starttikzsettings + {\pushoverloadmode} + + \permanent\protected\def\stoptikzsettings + {\popoverloadmode} + + \permanent\protected\def\starttikzpicture + {\dontleavehmode + \hcontainer\bgroup + % \pushoverloadmode + \ifdefined\PackageError\else \let\PackageError\tikzerrormessage \fi + \tikzpicture} + + \permanent\protected\def\stoptikzpicture + {\endtikzpicture + % \popoverloadmode + \egroup} + +\fi \stopmodule diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index cf618d021..390693ed0 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 : 2021-02-14 16:11 +-- merge date : 2021-02-17 13:30 do -- begin closure to overcome local limits and interference -- cgit v1.2.3