diff options
Diffstat (limited to 'tex')
34 files changed, 1918 insertions, 619 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 9a776779e..2086790a3 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.04.28 18:34} +\newcontextversion{2021.04.29 23:04} %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 1862a0199..8a7a89fdc 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.04.28 18:34} +\edef\contextversion{2021.04.29 23:04} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index 36d93f259..6a1b268c1 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -761,6 +761,7 @@ \setinterfaceconstant{coupling}{koppeling} \setinterfaceconstant{couplingway}{koppelwijze} \setinterfaceconstant{criterium}{criterium} +\setinterfaceconstant{crop}{crop} \setinterfaceconstant{cropoffset}{cropoffset} \setinterfaceconstant{crossreference}{crossreference} \setinterfaceconstant{cssfile}{cssfile} diff --git a/tex/context/base/mkiv/anch-snc.lua b/tex/context/base/mkiv/anch-snc.lua index ee13adca3..e7520f88d 100644 --- a/tex/context/base/mkiv/anch-snc.lua +++ b/tex/context/base/mkiv/anch-snc.lua @@ -24,8 +24,8 @@ local mpnumeric = mp.numeric local mppoints = mp.points local texgetdimen = tex.getdimen -local p_number = patterns.cardinal/tonumber -local p_space = patterns.whitespace^0 +local p_number = lpegpatterns.cardinal/tonumber +local p_space = lpegpatterns.whitespace^0 local p_tag = P("syncpos:") * p_number * P(":") * p_number local p_option = p_number * ((P(",") * p_space * P("reset") * Cc(true)) + Cc(false)) -- for now diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index cd7b5e90c..18ec52a17 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.04.28 18:34} +\newcontextversion{2021.04.29 23:04} %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 4dd68dcd4..06ea3e597 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.04.28 18:34} +\edef\contextversion{2021.04.29 23:04} %D Kind of special: diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 56a91dbbb..47e2e93d4 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -4161,49 +4161,60 @@ end -- so far -local plugins = { } -otf.plugins = plugins - -local report = logs.reporter("fonts") - -function otf.registerplugin(name,f) - if type(name) == "string" and type(f) == "function" then - plugins[name] = { name, f } - report() - report("plugin %a has been loaded, please be aware of possible side effects",name) - report() - if logs.pushtarget then - logs.pushtarget("log") - end - report("Plugins are not officially supported unless stated otherwise. This is because") - report("they bypass the regular font handling and therefore some features in ConTeXt") - report("(especially those related to fonts) might not work as expected or might not work") - report("at all. Some plugins are for testing and development only and might change") - report("whenever we feel the need for it.") - report() - if logs.poptarget then - logs.poptarget() +do + + local plugins = { } + otf.plugins = plugins + + local report = logs.reporter("fonts") + local warned = false + local okay = { text = true } + + function otf.registerplugin(name,f) + if type(name) == "string" and type(f) == "function" then + plugins[name] = { name, f } + if okay[name] then + -- no warning (e.g. the diagnostic text plugin) + else + report("plugin %a has been loaded, please be aware of possible side effects",name) + if not warned then + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end + warned = true + end + end end end -end -function otf.plugininitializer(tfmdata,value) - if type(value) == "string" then - tfmdata.shared.plugin = plugins[value] + function otf.plugininitializer(tfmdata,value) + if type(value) == "string" then + tfmdata.shared.plugin = plugins[value] + end end -end -function otf.pluginprocessor(head,font,attr,direction) -- n - local s = fontdata[font].shared - local p = s and s.plugin - if p then - if trace_plugins then - report_process("applying plugin %a",p[1]) + function otf.pluginprocessor(head,font,dynamic,direction) -- n + local s = fontdata[font].shared + local p = s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font,dynamic,direction) + else + return head, false end - return p[2](head,font,attr,direction) - else - return head, false end + end function otf.featuresinitializer(tfmdata,value) diff --git a/tex/context/base/mkiv/font-txt.lua b/tex/context/base/mkiv/font-txt.lua index 20f290ddb..c52878ca7 100644 --- a/tex/context/base/mkiv/font-txt.lua +++ b/tex/context/base/mkiv/font-txt.lua @@ -247,303 +247,307 @@ end -- users do that. On the other hand, we do support longer glyph runs in both modes -- so there we gain a bit. -local function texthandler(head,font,attr,rlmode,handler,startspacing,stopspacing,nesting) - if not head then - return - end - if startspacing == nil then - startspacing = false - end - if stopspacing == nil then - stopspacing = false - end +do - if getid(head) == par_code and start_of_par(head) then - rlmode = pardirstate(head) - elseif rlmode == righttoleft_code then - rlmode = -1 - else - rlmode = 0 - end - - local dirstack = { } - local rlparmode = 0 - local topstack = 0 - local text = { } - local size = 0 - local current = head - local start = nil - local stop = nil - local startrlmode = rlmode + local function texthandler(head,font,dynamic,rlmode,handler,startspacing,stopspacing,nesting) + if not head then + return + end + if startspacing == nil then + startspacing = false + end + if stopspacing == nil then + stopspacing = false + end - local function handle(leading,trailing) -- what gets passed can become configureable: e.g. utf 8 - local stop = current or start -- hm, what with outer stop - if getid(stop) ~= glyph_code then - stop = getprev(stop) + if getid(head) == par_code and start_of_par(head) then + rlmode = pardirstate(head) + elseif rlmode == righttoleft_code then + rlmode = -1 + else + rlmode = 0 end - head = handler(head,font,attr,rlmode,start,stop,text,leading,trailing) -- handler can adapt text - size = 0 - text = { } - start = nil - end - while current do - local char, id = ischar(current,font) - if char then - if not start then - start = current - startrlmode = rlmode - end - local char = getchar(current) - size = size + 1 - text[size] = char - current = getnext(current) - elseif char == false then - -- so a mixed font - if start and size > 0 then - handle(startspacing,false) + local dirstack = { } + local rlparmode = 0 + local topstack = 0 + local text = { } + local size = 0 + local current = head + local start = nil + local stop = nil + local startrlmode = rlmode + + local function handle(leading,trailing) -- what gets passed can become configureable: e.g. utf 8 + local stop = current or start -- hm, what with outer stop + if getid(stop) ~= glyph_code then + stop = getprev(stop) end - startspacing = false - current = getnext(current) - elseif id == glue_code then - -- making this branch optional i.e. always use the else doesn't really - -- make a difference in performance (in hb) .. tricky anyway as we can - local width = getwidth(current) - if width > 0 then - if start and size > 0 then - handle(startspacing,true) + head = handler(head,font,dynamic,rlmode,start,stop,text,leading,trailing) -- handler can adapt text + size = 0 + text = { } + start = nil + end + + while current do + local char, id = ischar(current,font) + if char then + if not start then + start = current + startrlmode = rlmode end - startspacing = true - stopspacing = false - else + local char = getchar(current) + size = size + 1 + text[size] = char + current = getnext(current) + elseif char == false then + -- so a mixed font if start and size > 0 then - head = handle(startspacing) + handle(startspacing,false) end startspacing = false - stopspacing = false - end - current = getnext(current) - elseif id == disc_code and usesfont(current,font) then -- foo|-|bar : has hbox - -- This looks much like the original code but I don't see a need to optimize - -- for e.g. deva or r2l fonts. If there are no disc nodes then we won't see - -- this branch anyway and if there are, we should just deal with them. - -- - -- There is still some weird code here ... start/stop and such. When I'm in - -- the mood (or see a need) I'll rewrite this bit. + current = getnext(current) + elseif id == glue_code then + -- making this branch optional i.e. always use the else doesn't really + -- make a difference in performance (in hb) .. tricky anyway as we can + local width = getwidth(current) + if width > 0 then + if start and size > 0 then + handle(startspacing,true) + end + startspacing = true + stopspacing = false + else + if start and size > 0 then + head = handle(startspacing) + end + startspacing = false + stopspacing = false + end + current = getnext(current) + elseif id == disc_code and usesfont(current,font) then -- foo|-|bar : has hbox + -- This looks much like the original code but I don't see a need to optimize + -- for e.g. deva or r2l fonts. If there are no disc nodes then we won't see + -- this branch anyway and if there are, we should just deal with them. + -- + -- There is still some weird code here ... start/stop and such. When I'm in + -- the mood (or see a need) I'll rewrite this bit. - -- bug: disc in last word moves to end (in practice not an issue as one - -- doesn't want a break there) + -- bug: disc in last word moves to end (in practice not an issue as one + -- doesn't want a break there) - local pre = nil - local post = nil - local currentnext = getnext(current) - local current_pre, current_post, current_replace = getdisc(current) - setdisc(current) -- why, we set it later - if start then - pre = copy_node_list(start,current) - stop = getprev(current) - -- why also current and not: - -- pre = copy_node_list(start,stop) - if start == head then - head = current + local pre = nil + local post = nil + local currentnext = getnext(current) + local current_pre, current_post, current_replace = getdisc(current) + setdisc(current) -- why, we set it later + if start then + pre = copy_node_list(start,current) + stop = getprev(current) + -- why also current and not: + -- pre = copy_node_list(start,stop) + if start == head then + head = current + end + setlink(getprev(start),current) + setlink(stop,current_pre) + current_pre = start + setprev(current_pre) + start = nil + stop = nil + startrlmode = rlmode end - setlink(getprev(start),current) - setlink(stop,current_pre) - current_pre = start - setprev(current_pre) - start = nil - stop = nil - startrlmode = rlmode - end - while currentnext do - local char, id = ischar(currentnext,font) - if char or id == disc_code then - stop = currentnext - currentnext = getnext(currentnext) - elseif id == glue_code then - local width = getwidth(currentnext) - if width and width > 0 then - stopspacing = true + while currentnext do + local char, id = ischar(currentnext,font) + if char or id == disc_code then + stop = currentnext + currentnext = getnext(currentnext) + elseif id == glue_code then + local width = getwidth(currentnext) + if width and width > 0 then + stopspacing = true + else + stopspacing = false + end + break else - stopspacing = false + break end - break - else - break end - end - if stop then - local currentnext = getnext(current) - local stopnext = getnext(stop) - post = copy_node_list(currentnext,stopnext) - if current_post then - setlink(find_node_tail(current_post),currentnext) - else - setprev(currentnext) - current_post = currentnext + if stop then + local currentnext = getnext(current) + local stopnext = getnext(stop) + post = copy_node_list(currentnext,stopnext) + if current_post then + setlink(find_node_tail(current_post),currentnext) + else + setprev(currentnext) + current_post = currentnext + end + setlink(current,stopnext) + setnext(stop) + stop = nil end - setlink(current,stopnext) - setnext(stop) - stop = nil - end - if pre then - setlink(find_node_tail(pre),current_replace) - current_replace = pre - pre = nil - end - if post then - if current_replace then - setlink(find_node_tail(current_replace),post) - else - current_replace = post + if pre then + setlink(find_node_tail(pre),current_replace) + current_replace = pre + pre = nil end - post = nil - end - size = 0 -- hm, ok, start is also nil now - text = { } - if current_pre then - current_pre = texthandler(current_pre,font,attr,rlmode,handler,startspacing,false,"pre") - end - if current_post then - current_post = texthandler(current_post,font,attr,rlmode,handler,false,stopspacing,"post") - end - if current_replace then - current_replace = texthandler(current_replace,font,attr,rlmode,handler,startspacing,stopspacing,"replace") - end - startspacing = false - stopspacing = false - local cpost = current_post and find_node_tail(current_post) - local creplace = current_replace and find_node_tail(current_replace) - local cpostnew = nil - local creplacenew = nil - local newcurrent = nil - while cpost and equalnode(cpost,creplace) do - cpostnew = cpost - creplacenew = creplace - if creplace then - creplace = getprev(creplace) + if post then + if current_replace then + setlink(find_node_tail(current_replace),post) + else + current_replace = post + end + post = nil end - cpost = getprev(cpost) - end - if cpostnew then - if cpostnew == current_post then - current_post = nil - else - setnext(getprev(cpostnew)) + size = 0 -- hm, ok, start is also nil now + text = { } + if current_pre then + current_pre = texthandler(current_pre,font,dynamic,rlmode,handler,startspacing,false,"pre") end - flush_list(cpostnew) - if creplacenew == current_replace then - current_replace = nil - else - setnext(getprev(creplacenew)) + if current_post then + current_post = texthandler(current_post,font,dynamic,rlmode,handler,false,stopspacing,"post") end - local c = getnext(current) - setlink(current,creplacenew) - local creplacenewtail = find_node_tail(creplacenew) - setlink(creplacenewtail,c) - newcurrent = creplacenewtail - end - current_post = current_post and deletedisc(current_post) - current_replace = current_replace and deletedisc(current_replace) - local cpre = current_pre - local creplace = current_replace - local cprenew = nil - local creplacenew = nil - while cpre and equalnode(cpre, creplace) do - cprenew = cpre - creplacenew = creplace - if creplace then - creplace = getnext(creplace) + if current_replace then + current_replace = texthandler(current_replace,font,dynamic,rlmode,handler,startspacing,stopspacing,"replace") end - cpre = getnext(cpre) - end - if cprenew then - cpre = current_pre - current_pre = getnext(cprenew) - if current_pre then - setprev(current_pre) + startspacing = false + stopspacing = false + local cpost = current_post and find_node_tail(current_post) + local creplace = current_replace and find_node_tail(current_replace) + local cpostnew = nil + local creplacenew = nil + local newcurrent = nil + while cpost and equalnode(cpost,creplace) do + cpostnew = cpost + creplacenew = creplace + if creplace then + creplace = getprev(creplace) + end + cpost = getprev(cpost) end - setnext(cprenew) - flush_list(cpre) - creplace = current_replace - current_replace = getnext(creplacenew) - if current_replace then - setprev(current_replace) + if cpostnew then + if cpostnew == current_post then + current_post = nil + else + setnext(getprev(cpostnew)) + end + flush_list(cpostnew) + if creplacenew == current_replace then + current_replace = nil + else + setnext(getprev(creplacenew)) + end + local c = getnext(current) + setlink(current,creplacenew) + local creplacenewtail = find_node_tail(creplacenew) + setlink(creplacenewtail,c) + newcurrent = creplacenewtail end - setlink(getprev(current),creplace) - if current == head then - head = creplace + current_post = current_post and deletedisc(current_post) + current_replace = current_replace and deletedisc(current_replace) + local cpre = current_pre + local creplace = current_replace + local cprenew = nil + local creplacenew = nil + while cpre and equalnode(cpre, creplace) do + cprenew = cpre + creplacenew = creplace + if creplace then + creplace = getnext(creplace) + end + cpre = getnext(cpre) end - setlink(creplacenew,current) - end - setdisc(current,current_pre,current_post,current_replace) - current = currentnext - else - if start and size > 0 then - handle(startspacing,stopspacing) - end - startspacing = false - stopspacing = false - if id == math_code then - current = getnext(end_of_math(current)) - elseif id == dir_code then - startspacing = false - topstack, rlmode = txtdirstate(current,dirstack,topstack,rlparmode) - current = getnext(current) - -- elseif id == par_code and start_of_par(current) then - -- startspacing = false - -- rlparmode, rlmode = pardirstate(current) - -- current = getnext(current) + if cprenew then + cpre = current_pre + current_pre = getnext(cprenew) + if current_pre then + setprev(current_pre) + end + setnext(cprenew) + flush_list(cpre) + creplace = current_replace + current_replace = getnext(creplacenew) + if current_replace then + setprev(current_replace) + end + setlink(getprev(current),creplace) + if current == head then + head = creplace + end + setlink(creplacenew,current) + end + setdisc(current,current_pre,current_post,current_replace) + current = currentnext else - current = getnext(current) + if start and size > 0 then + handle(startspacing,stopspacing) + end + startspacing = false + stopspacing = false + if id == math_code then + current = getnext(end_of_math(current)) + elseif id == dir_code then + startspacing = false + topstack, rlmode = txtdirstate(current,dirstack,topstack,rlparmode) + current = getnext(current) + -- elseif id == par_code and start_of_par(current) then + -- startspacing = false + -- rlparmode, rlmode = pardirstate(current) + -- current = getnext(current) + else + current = getnext(current) + end end end + if start and size > 0 then + handle(startspacing,stopspacing) + end + return head, true end - if start and size > 0 then - handle(startspacing,stopspacing) - end - return head, true -end -function fonts.handlers.otf.texthandler(head,font,attr,direction,action) - if action then - return texthandler(head,font,attr,direction == righttoleft_code and -1 or 0,action) - else - return head, false + function fonts.handlers.otf.texthandler(head,font,dynamic,direction,action) + if action then + return texthandler(head,font,dynamic,direction == righttoleft_code and -1 or 0,action) + else + return head, false + end end -end --- Next comes a tracer plug into context. + -- Next comes a tracer plug into context. -local texthandler = fonts.handlers.otf.texthandler -local report_text = logs.reporter("otf plugin","text") -local nofruns = 0 -local nofsnippets = 0 -local f_unicode = string.formatters["%U"] + ----- texthandler = fonts.handlers.otf.texthandler + local report_text = logs.reporter("otf plugin","text") + local nofruns = 0 + local nofsnippets = 0 + local f_unicode = string.formatters["%U"] -local function showtext(head,font,attr,rlmode,start,stop,list,before,after) - if list then - nofsnippets = nofsnippets + 1 - local plus = { } - for i=1,#list do - local u = list[i] - list[i] = utfchar(u) - plus[i] = f_unicode(u) + local function showtext(head,font,dynamic,rlmode,start,stop,list,before,after) + if list then + nofsnippets = nofsnippets + 1 + local plus = { } + for i=1,#list do + local u = list[i] + list[i] = utfchar(u) + plus[i] = f_unicode(u) + end + report_text("%03i : [%s] %t [%s]-> % t", nofsnippets, before and "+" or "-", list, after and "+" or "-", plus) + else + report_text() + report_text("invalid list") + report_text() end - report_text("%03i : [%s] %t [%s]-> % t", nofsnippets, before and "+" or "-", list, after and "+" or "-", plus) - else - report_text() - report_text("invalid list") - report_text() + return head, false end - return head, false -end -fonts.handlers.otf.registerplugin("text",function(head,font,attr,direction) - nofruns = nofruns + 1 - nofsnippets = 0 - report_text("start run %i",nofruns) - local h, d = texthandler(head,font,attr,direction,showtext) - report_text("stop run %i",nofruns) - return h, d -end) + fonts.handlers.otf.registerplugin("text",function(head,font,dynamic,direction) + nofruns = nofruns + 1 + nofsnippets = 0 + report_text("start run %i",nofruns) + local h, d = texthandler(head,font,dynamic,direction,showtext) + report_text("stop run %i",nofruns) + return h, d + end) + +end diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index 072cb319a..38ec753cd 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -29,7 +29,6 @@ \registerctxluafile{node-snp}{} \registerctxluafile{node-tsk}{} \registerctxluafile{node-tex}{} -\registerctxluafile{node-dir}{} % experimental, not yet (and maybe never) used \registerctxluafile{node-pro}{} \registerctxluafile{node-ser}{} %registerctxluafile{node-ext}{} diff --git a/tex/context/base/mkiv/node-tst.lua b/tex/context/base/mkiv/node-tst.lua index 0dacff375..c28086f81 100644 --- a/tex/context/base/mkiv/node-tst.lua +++ b/tex/context/base/mkiv/node-tst.lua @@ -16,11 +16,7 @@ local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty local kern_code = nodecodes.kern local glyph_code = nodecodes.glyph -local whatsit_code = nodecodes.whatsit -local hlist_code = nodecodes.hlist -local leftskip_code = gluecodes.leftskip -local rightskip_code = gluecodes.rightskip local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip @@ -35,52 +31,16 @@ local getkern = nuts.getkern local getpenalty = nuts.getpenalty local getwidth = nuts.getwidth -local find_node_tail = nuts.tail - -function nuts.leftmarginwidth(n) -- todo: three values - while n do - local id = getid(n) - if id == glue_code then - return getsubtype(n) == leftskip_code and getwidth(n) or 0 - elseif id == whatsit_code then - n = getnext(n) - elseif id == hlist_code then - return getwidth(n) - else - break - end - end - return 0 -end - -function nuts.rightmarginwidth(n) - if n then - n = find_node_tail(n) - while n do - local id = getid(n) - if id == glue_code then - return getsubtype(n) == rightskip_code and getwidth(n) or 0 - elseif id == whatsit_code then - n = getprev(n) - else - break - end - end - end - return false -end - function nuts.somespace(n,all) if n then local id = getid(n) if id == glue_code then return (all or (getwidth(n) ~= 0)) and glue_code -- temp: or 0 elseif id == kern_code then - return (all or (getkern(n) ~= 0)) and kern + return (all or (getkern(n) ~= 0)) and kern_code elseif id == glyph_code then - local category = chardata[getchar(n)].category -- maybe more category checks are needed - return (category == "zs") and glyph_code + return (chardata[getchar(n)].category == "zs") and glyph_code end end return false diff --git a/tex/context/base/mkiv/node-typ.lua b/tex/context/base/mkiv/node-typ.lua index adf0d18c0..2f00c9413 100644 --- a/tex/context/base/mkiv/node-typ.lua +++ b/tex/context/base/mkiv/node-typ.lua @@ -107,7 +107,7 @@ local function tohbox(str,fontid,spacing) end local function tovpack(str,fontid,spacing) - -- vpack is just a hack, and a proper implemtation is on the agenda + -- vpack is just a hack, and a proper implementation is on the agenda -- as it needs more info etc than currently available return vpack_node_list(tonodes(str,fontid,spacing)) end diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua index 06983ef5c..d3ff2cdad 100644 --- a/tex/context/base/mkiv/page-lin.lua +++ b/tex/context/base/mkiv/page-lin.lua @@ -84,7 +84,6 @@ local nextvlist = nuts.traversers.vlist local copy_node = nuts.copy ----- hpack_nodes = nuts.hpack local is_display_math = nuts.is_display_math -local leftmarginwidth = nuts.leftmarginwidth ----- nodepool = nuts.pool ----- new_kern = nodepool.kern diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 54187bc87..88bc8d7fb 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 e12630a56..e02a4f376 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua index 82149ef02..4e94648e3 100644 --- a/tex/context/base/mkiv/task-ini.lua +++ b/tex/context/base/mkiv/task-ini.lua @@ -26,12 +26,6 @@ local freezecallbacks = callbacks.freeze ------------("processors", "before", "nodes.properties.attach", nil, "nut", "enabled" ) -if CONTEXTLMTXMODE > 0 then - -appendaction("processors", "normalizers", "builders.kernel.collapsing", nil, "nut", "enabled" ) - -end - appendaction("processors", "normalizers", "typesetters.periodkerns.handler", nil, "nut", "disabled" ) appendaction("processors", "normalizers", "languages.replacements.handler", nil, "nut", "disabled" ) appendaction("processors", "normalizers", "typesetters.wrappers.handler", nil, "nut", "disabled" ) @@ -71,13 +65,8 @@ appendaction("processors", "lists", "typesetters.kerns.handler", appendaction("processors", "lists", "typesetters.digits.handler", nil, "nut", "disabled" ) appendaction("processors", "lists", "typesetters.italics.handler", nil, "nut", "disabled" ) appendaction("processors", "lists", "languages.visualizediscretionaries", nil, "nut", "disabled" ) - -if CONTEXTLMTXMODE == 0 then - appendaction("processors", "lists", "nodes.handlers.migrate", nil, "nut", "disabled" ) -end - appendaction("processors", "after", "typesetters.marksuspects", nil, "nut", "disabled" ) appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "production") @@ -131,14 +120,9 @@ appendaction("math", "builders", "typesetters.directions.processmath" appendaction("math", "builders", "noads.handlers.makeup", nil, "nonut", "disabled" ) appendaction("math", "builders", "noads.handlers.align", nil, "nonut", "enabled" ) -if CONTEXTLMTXMODE == 0 then - appendaction("finalizers", "lists", "typesetters.paragraphs.normalize", nil, "nut", "enabled" ) -- "disabled" - -end - -appendaction("finalizers", "lists", "nodes.handlers.showhyphenation", nil, "nut", "disabled" ) -appendaction("finalizers", "lists", "nodes.handlers.visualizehyphenation", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "nodes.handlers.showhyphenation", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "nodes.handlers.visualizehyphenation", nil, "nut", "disabled" ) appendaction("finalizers", "lists", "typesetters.margins.localhandler", nil, "nut", "disabled" ) appendaction("finalizers", "lists", "builders.paragraphs.keeptogether", nil, "nut", "disabled" ) @@ -150,11 +134,6 @@ appendaction("finalizers", "lists", "nodes.linefillers.handler", appendaction("contributers", "normalizers", "nodes.handlers.flattenline", nil, "nut", "disabled" ) appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds", nil, "nut", "disabled" ) -if CONTEXTLMTXMODE > 0 then - -appendaction("contributers", "normalizers", "nodes.handlers.wipe", nil, "nut", "disabled" ) - -end appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox", nil, "nut", "disabled" ) ------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler", nil, "nut", "disabled" ) diff --git a/tex/context/base/mkxl/anch-bar.mkxl b/tex/context/base/mkxl/anch-bar.mkxl index 3587eb8a0..252f41239 100644 --- a/tex/context/base/mkxl/anch-bar.mkxl +++ b/tex/context/base/mkxl/anch-bar.mkxl @@ -157,8 +157,7 @@ \MPpositiongraphic{mpos:sidebar}{}% \stopMPpositionmethod -%D We now reimplement the \MKII\ margin rules handler in a more -%D modern way. +%D We now reimplement the \MKII\ margin rules handler in a more modern way. %D %D \setupmarginrules %D [rulecolor=darkred, diff --git a/tex/context/base/mkxl/anch-snc.lmt b/tex/context/base/mkxl/anch-snc.lmt new file mode 100644 index 000000000..57789a5a0 --- /dev/null +++ b/tex/context/base/mkxl/anch-snc.lmt @@ -0,0 +1,243 @@ +if not modules then modules = { } end modules ['anch-snc'] = { + version = 1.001, + comment = "companion to anch-snc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tonumber, next, setmetatable = tonumber, next, setmetatable +local concat, sort, remove, copy = table.concat, table.sort, table.remove, table.copy +local match, find = string.match, string.find +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local setmetatableindex = table.setmetatableindex +local P, Cc = lpeg.P, lpeg.Cc + +graphics = graphics or { } +local synchronizers = { } +graphics.synchronizers = synchronizers + +local p_number = lpegpatterns.cardinal/tonumber +local p_space = lpegpatterns.whitespace^0 +local p_tag = P("syncpos:") * p_number * P(":") * p_number +local p_option = p_number * ((P(",") * p_space * P("reset") * Cc(true)) + Cc(false)) -- for now + +local list = { } +local kinds = { + above = 1, + continue = 2, + nothing = 3, + normal = 4, + below = 5, +} + +local allentries = setmetatableindex(function(t,category) + setmetatable(t,nil) + for tag, pos in next, job.positions.collected do + local c, n = lpegmatch(p_tag,tag) + if c then + local tc = t[c] + if tc then + tc[n] = pos + else + t[c] = { [n] = pos } + end + end + end + for k, list in next, t do + sort(list,function(a,b) + local ap = a.p + local bp = b.p + if ap == bp then + return b.y < a.y + else + return ap < bp + end + end) + list.start = 1 + end + setmetatableindex(t,"table") + return t[category] +end) + +local lastdone = { } + +function synchronizers.collect(category,realpage,region) + local all = allentries[category] + local m = 0 + local n = #all + list = { } + if region and region ~= "" then + -- successive can be optimized when we sort by region + local start = 1 + local done = false + local last, rtop, rbot + for i=start,n do + local pos = all[i] + local p = pos.p + local r = pos.r + if r == region then + if not done then + local region = job.positions.collected[r] + list.region = region + list.page = region + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + end + end + if done then + last.bottom = rbot + end + else + local start = all.start or 1 + local done = false + local last, rtop, rbot, ptop, pbot + for i=start,n do + local pos = all[i] + local p = pos.p + if p == realpage then + if not done then + local region = job.positions.collected[pos.r] + local page = job.positions.collected["page:"..realpage] or region + list.region = region + list.page = page + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + ptop = (page .y or 0) + (page .h or 0) + pbot = (page .y or 0) - (page .d or 0) + last = { kind = "above", top = ptop, bottom = rtop, task = 0 } + m = m + 1 ; list[m] = last + if i > 1 then + local task, reset = lpegmatch(p_option,all[i-1].e) + last = { kind = "continue", top = rtop, bottom = 0, task = task } + m = m + 1 ; list[m] = last + else + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + end + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + if reset then + local l = list[2] + l.kind = "nothing" + l.task = 0 + end + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + elseif p > realpage then + all.start = i -- tricky, only for page + break + end + end + if done then + last.bottom = rbot + last = { kind = "below", top = rbot, bottom = pbot, task = 0 } + m = m + 1 ; list[m] = last + lastdone[category] = { + { kind = "above", top = ptop, bottom = rtop, task = 0 }, + { kind = "continue", top = rtop, bottom = rbot, task = list[#list-1].task }, -- lasttask + { kind = "below", top = rbot, bottom = pbot, task = 0 }, + region = list.region, + page = list.page, + } + else + local l = lastdone[category] + if l then + list = copy(l) -- inefficient, maybe metatable for region/page + m = 3 + end + end + end + return m +end + +function synchronizers.extend() + local n = #list + if n > 0 then + for i=1,n do + local l = list[i] + local k = l.kind + if k == "nothing" then + local ll = list[i+1] + if ll and ll.kind == "normal" then + ll.top = l.top + remove(list,i) + n = #list + break + end + end + end + end + return n +end + +function synchronizers.prune() + local n = #list + if n > 0 then + if list[1].kind == "above" then + remove(list,1) + end + if list[1].kind == "nothing" then + remove(list,1) + end + if list[#list].kind == "below" then + remove(list,#list) + end + n = #list + end + return n +end + +function synchronizers.collapse() + local n = #list + if n > 0 then + local m = 0 + local p = nil + for i=1,n do + local l = list[i] + local t = l.task + if p == t then + list[m].bottom = l.bottom + else + m = m + 1 + list[m] = l + end + p = t + end + for i=n,m+1,-1 do + list[i] = nil + end + n = m + end + return n +end + +function synchronizers.getsize () return #list end +function synchronizers.gettop (n) return list[n].top end +function synchronizers.getbottom(n) return list[n].bottom end +function synchronizers.getkind (n) return kinds[list[n].kind] end +function synchronizers.gettask (n) return list[n].task end + +function synchronizers.getx() return list.page.x or 0 end +function synchronizers.gety() return list.page.y or 0 end +function synchronizers.getw() return list.page.w or 0 end +function synchronizers.geth() return list.page.h or 0 end +function synchronizers.getd() return list.page.d or 0 end + +-- function mp.xxOverlayRegion() +-- local r = tokens.getters.macro("m_overlay_region") +-- mp.quoted('"'.. r .. '"') +-- end + diff --git a/tex/context/base/mkxl/anch-snc.mkxl b/tex/context/base/mkxl/anch-snc.mkxl index e186e024f..436305634 100644 --- a/tex/context/base/mkxl/anch-snc.mkxl +++ b/tex/context/base/mkxl/anch-snc.mkxl @@ -11,15 +11,119 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D The original is in the mkii file. It does more at the \TEX\ end and -%D has some more magic. If we really need that I'll add it. After all, -%D in mkiv we can do things different. - -%D TODO: bleed : + left , minus right oro check if it touches page ... autobleed +%D This is a rather old mechanism that we once needed in an actually nice design. +%D Those were the times that processing a rather complex xml file with \PDFTEX\ into +%D a 400 page document took 45 minutes (a few runs) while nowadays with luatex and +%D \MKIV\ (and \LMTX) we express runtime in seconds. +%D +%D In retrospect it was a waste of time (and money) to invest in all these +%D mechanisms because the publishers we were dealign with were far from ready for +%D dealing with xml and let alone automatic rendering. But, as the code still worked +%D well after nearly two decades I decided to revive it .. maybe some curious +%D \CONTEXT\ user can benefit from it after all. +%D +%D The logic is mostly the same as in \MKII\ but some work is now delegated to \LUA\ +%D so that we save memory and gain some runtime. As this was not really a used +%D module the interface also was upgraded. As we know the bottlenecks in \METAPOST\ +%D we also work around those a bit. It made sense too change the interface to use +%D the new \LMTX\ mechanisms for passing parameters. The old interface can be found +%D in the \MKII\ and \MKIV\ files. + +%D TODO: bleed | autobleed \writestatus{loading}{ConTeXt Anchoring Macros / Synchronization} \registerctxluafile{anch-snc}{} +\registerctxluafile{mlib-snc}{} + +%D \stoptyping +%D \starttext +%D +%D \setuplayout[location=middle] +%D \setupbodyfont[dejavu] +%D +%D \definesyncpositions[1] +%D \definesyncpositions[2] +%D +%D % \startuseMPgraphic{sync1} +%D % StartPage ; +%D % lmt_synchronizer [ ... ] ; +%D % clip currentpicture to Page ; +%D % setbounds currentpicture to Page ; +%D % StopPage ; +%D % \stopuseMPgraphic +%D +%D \startuseMPgraphic{sync1} +%D lmt_synchronizer [ +%D % page = "yes", +%D index = 1, +%D hoffset = 0, +%D width = BackSpace - LeftMarginDistance, +%D extend = false, +%D prune = true, +%D draw = false, +%D fill = true, +%D ] ; +%D \stopuseMPgraphic +%D +%D \startuseMPgraphic{sync2} +%D lmt_synchronizer [ +%D index = 2, +%D region = OverlayRegion, +%D hoffset = -1cm, +%D width = 1cm, +%D extend = true, +%D prune = false, +%D draw = false, +%D fill = true, +%D ] ; +%D clip currentpicture to OverlayBox leftenlarged 1cm; +%D setbounds currentpicture to OverlayBox ; +%D \stopuseMPgraphic +%D +%D \defineoverlay[tempoverlay1][\useMPgraphic{sync1}] +%D \defineoverlay[tempoverlay2][\useMPgraphic{sync2}] +%D +%D \setupbackgrounds[page][background=tempoverlay1] +%D +%D \framed[region=yes,background=tempoverlay2,width=14cm,align=normal]{% +%D \syncposition[2][1]\samplefile{ward}\endgraf +%D \syncposition[2][2]\samplefile{ward}\endgraf +%D \syncposition[2][3]\samplefile{ward}\endgraf +%D } +%D +%D \vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=16cm,align=normal]{% +%D \syncposition[2][1]\samplefile{ward}\endgraf +%D \syncposition[2][2]\samplefile{ward}\endgraf +%D \syncposition[2][3]\samplefile{ward}\endgraf +%D } +%D +%D \vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=10cm,align=normal]{% +%D \syncposition[2][1]\samplefile{ward}\endgraf +%D \syncposition[2][2]\samplefile{ward}\endgraf +%D \syncposition[2][3]\samplefile{ward}\endgraf +%D } +%D +%D \dorecurse {100} { +%D \startchapter[title={Test #1}] +%D \syncposition[1][1,reset]\dorecurse{20}{\samplefile{ward}\endgraf} +%D \syncposition[1][2]\dorecurse {4}{\samplefile{ward}\endgraf} +%D \syncposition[1][3]\dorecurse {7}{\samplefile{ward}\endgraf} +%D \syncposition[1][4]\dorecurse {3}{\samplefile{ward}\endgraf} +%D \stopchapter +%D } +%D +%D \dorecurse {100} { +%D \startchapter[title={Test #1}] +%D \syncposition[1][1]\dorecurse{1}{\samplefile{ward}\endgraf} +%D \syncposition[1][2]\dorecurse{1}{\samplefile{ward}\endgraf} +%D \syncposition[1][3]\dorecurse{1}{\samplefile{ward}\endgraf} +%D \syncposition[1][4]\dorecurse{1}{\samplefile{ward}\endgraf} +%D \stopchapter +%D } +%D +%D \stoptext +%D \stoptyping \unprotect @@ -46,112 +150,3 @@ \ignorespaces} \protect - -\continueifinputfile{anch-snc.mkiv} - -\starttext - -% \setuppapersize[A4][A3] - -\setuplayout[location=middle] - -\setupbodyfont[dejavu] - -\definesyncpositions[1] -\definesyncpositions[2] - -% \enabletrackers[metapost.lua] - -\startMPdefinitions - input "mp-asnc.mpiv" ; - - SetSyncColor(1,0,"magenta") ; - SetSyncColor(1,1,"red") ; - SetSyncColor(1,2,"green") ; - SetSyncColor(1,3,"blue") ; - SetSyncColor(1,4,"yellow") ; - - SetSyncColor(2,0,"magenta") ; - SetSyncColor(2,1,"red") ; - SetSyncColor(2,2,"green") ; - SetSyncColor(2,3,"blue") ; - SetSyncColor(2,4,"yellow") ; -\stopMPdefinitions - -\startuseMPgraphic{sync1} - StartPage ; - StartSync(1) ; - SyncHOffset := 0 ; - SyncWidth := BackSpace - LeftMarginDistance; - CollectSyncDataPage ; - % ExtendSyncPaths ; % to top of text area - PruneSyncPaths ; % clip top / bottom - CollapseSyncPaths ; - MakeSyncPaths ; - % DrawSyncPaths ; - FillSyncPaths ; - StopSync ; - clip currentpicture to Page ; - setbounds currentpicture to Page ; - StopPage ; -\stopuseMPgraphic - -\startuseMPgraphic{sync2} - StartSync(2) ; - SyncHOffset := -1cm ; - SyncWidth := 1cm ; - CollectSyncDataRegion(OverlayRegion) ; - ExtendSyncPaths ; % to top of text area - MakeSyncPaths ; - FillSyncPaths ; - StopSync ; - clip currentpicture to OverlayBox leftenlarged 1cm; - setbounds currentpicture to OverlayBox ; -\stopuseMPgraphic - -\defineoverlay[tempoverlay1][\useMPgraphic{sync1}] -\defineoverlay[tempoverlay2][\useMPgraphic{sync2}] - -\setupbackgrounds[page][background=tempoverlay1] - -\framed[region=yes,background=tempoverlay2,width=14cm,align=normal]{ - \syncposition[2][1]\samplefile{ward}\endgraf - \syncposition[2][2]\samplefile{ward}\endgraf - \syncposition[2][3]\samplefile{ward}\endgraf -} - - -\vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=16cm,align=normal]{ - \syncposition[2][1]\samplefile{ward}\endgraf - \syncposition[2][2]\samplefile{ward}\endgraf - \syncposition[2][3]\samplefile{ward}\endgraf -} - -\vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=10cm,align=normal]{ - \syncposition[2][1]\samplefile{ward}\endgraf - \syncposition[2][2]\samplefile{ward}\endgraf - \syncposition[2][3]\samplefile{ward}\endgraf -} - - -\dorecurse {100} { -% \dorecurse {1} { - \startchapter[title={Test #1}] - \syncposition[1][1,reset]\dorecurse{20}{\samplefile{ward}\endgraf} - \syncposition[1][2]\dorecurse {4}{\samplefile{ward}\endgraf} - \syncposition[1][3]\dorecurse {7}{\samplefile{ward}\endgraf} - \syncposition[1][4]\dorecurse {3}{\samplefile{ward}\endgraf} - \stopchapter -} - -\dorecurse {100} { -% \dorecurse {1} { - \startchapter[title={Test #1}] - \syncposition[1][1]\dorecurse{1}{\samplefile{ward}\endgraf} - \syncposition[1][2]\dorecurse{1}{\samplefile{ward}\endgraf} - \syncposition[1][3]\dorecurse{1}{\samplefile{ward}\endgraf} - \syncposition[1][4]\dorecurse{1}{\samplefile{ward}\endgraf} - \stopchapter -} - -\stoptext diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 39593056b..3b39145bf 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.04.28 18:34} +\newcontextversion{2021.04.29 23:04} %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 f7395c758..9de5a2c11 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.04.28 18:34} +\immutable\edef\contextversion{2021.04.29 23:04} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error @@ -467,7 +467,7 @@ \loadmklxfile{anch-bck} \loadmkxlfile{anch-tab} % overloads tabl-tbl \loadmkxlfile{anch-bar} -%loadmkxlfile{anch-snc} % when needed this one will be redone +\loadmkxlfile{anch-snc} \loadmkxlfile{math-ini} % way after font-pre ! \loadmkxlfile{math-pln} diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt index ec2d4bb29..84ca14488 100644 --- a/tex/context/base/mkxl/font-ots.lmt +++ b/tex/context/base/mkxl/font-ots.lmt @@ -4199,7 +4199,6 @@ registerotffeature { } } - -- Moved here (up) a bit. This doesn't really belong in generic so it will -- move to a context module some day. diff --git a/tex/context/base/mkxl/font-txt.lmt b/tex/context/base/mkxl/font-txt.lmt index ce177e114..bc2f15464 100644 --- a/tex/context/base/mkxl/font-txt.lmt +++ b/tex/context/base/mkxl/font-txt.lmt @@ -249,7 +249,6 @@ end -- users do that. On the other hand, we do support longer glyph runs in both modes -- so there we gain a bit. - do local currentscale, currentxscale, currentyscale @@ -294,20 +293,9 @@ do start = nil end - -- maybe: isnextchar - while current do - -- local char, id = ischar(current,font,dynamic) local char, id = ischar(current,font,dynamic,currentscale,currentxscale,currentyscale) if char then - -- local s, sx, sy = getscales(current) - -- if s ~= currentscale or sx ~= currentxscale or sy ~= currentyscale then - -- if start and size > 0 then - -- handle(startspacing,false) - -- end - -- startspacing = false - -- currentscale, currentxscale, currentyscale = s, sx, sy - -- end if not start then start = current startrlmode = rlmode diff --git a/tex/context/base/mkxl/mlib-snc.lmt b/tex/context/base/mkxl/mlib-snc.lmt new file mode 100644 index 000000000..0d9c970a3 --- /dev/null +++ b/tex/context/base/mkxl/mlib-snc.lmt @@ -0,0 +1,43 @@ +if not modules then modules = { } end modules ['mlib-snc'] = { + version = 1.001, + comment = "companion to anch-snc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local scanners = mp.scan +local injectors = mp.inject + +local scannumeric = scanners.numeric +local scaninteger = scanners.integer +local scanstring = scanners.string +local mpnumeric = injectors.numeric + +local factor = number.dimenfactors.bp + +local synchronizers = graphics.synchronizers +local registerscript = metapost.registerscript + +-- no need for locals (yet) + +registerscript("asnc_collect", function() + -- category realpage region + mpnumeric(synchronizers.collect(scaninteger(),scaninteger(),scanstring())) +end) + +registerscript("asnc_extend", function() mpnumeric(synchronizers.extend ()) end) +registerscript("asnc_prune", function() mpnumeric(synchronizers.prune ()) end) +registerscript("asnc_collapse", function() mpnumeric(synchronizers.collapse()) end) + +registerscript("asnc_getsize", function() mpnumeric(synchronizers.getsize () ) end) +registerscript("asnc_gettop", function() mpnumeric(synchronizers.gettop (scaninteger()) * factor) end) +registerscript("asnc_getbottom",function() mpnumeric(synchronizers.getbottom(scaninteger()) * factor) end) +registerscript("asnc_getkind", function() mpnumeric(synchronizers.getkind (scaninteger()) ) end) +registerscript("asnc_gettask", function() mpnumeric(synchronizers.gettask (scaninteger()) ) end) + +registerscript("asnc_getx", function() mpnumeric(synchronizers.getx() * factor) end) +registerscript("asnc_gety", function() mpnumeric(synchronizers.gety() * factor) end) +registerscript("asnc_getw", function() mpnumeric(synchronizers.getw() * factor) end) +registerscript("asnc_geth", function() mpnumeric(synchronizers.geth() * factor) end) +registerscript("asnc_getd", function() mpnumeric(synchronizers.getd() * factor) end) diff --git a/tex/context/base/mkiv/node-dir.lua b/tex/context/base/mkxl/node-dir.lmt index 762f20739..c959fef07 100644 --- a/tex/context/base/mkiv/node-dir.lua +++ b/tex/context/base/mkxl/node-dir.lmt @@ -9,6 +9,9 @@ if not modules then modules = { } end modules ['node-dir'] = { local nodes = nodes local nuts = nodes.nuts +local nodecodes = nodes.nodecodes +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist local normaldir_code = nodes.dircodes.normal local line_code = nodes.listcodes.line local lefttoright_code = nodes.dirvalues.lefttoright @@ -16,15 +19,17 @@ local lefttoright_code = nodes.dirvalues.lefttoright local getnext = nuts.getnext local getlist = nuts.getlist local getwhd = nuts.getwhd +local getwidth = nuts.getwidth local getdirection = nuts.getdirection local setlist = nuts.setlist local nextdir = nuts.traversers.dir -local nexthlist = nuts.traversers.hlist +local nextlist = nuts.traversers.list local rangedimensions = nuts.rangedimensions local insert_before = nuts.insert_before +local insert_after = nuts.insert_after local new_rule = nuts.pool.rule local new_kern = nuts.pool.kern @@ -32,32 +37,8 @@ local new_kern = nuts.pool.kern local setcolor = nodes.tracers.colors.set local settransparency = nodes.tracers.transparencies.set --- local function dirdimensions(parent,begindir) -- can be a helper --- local level = 1 --- local enddir = begindir --- local width = 0 --- for current, subtype in nextdir, getnext(begindir) do --- if subtype == normaldir_code then -- todo --- level = level + 1 --- else --- level = level - 1 --- end --- if level == 0 then -- does the type matter --- enddir = current --- width = rangedimensions(parent,begindir,enddir) --- return width, enddir --- end --- end --- if enddir == begindir then --- width = rangedimensions(parent,begindir) --- end --- return width, enddir --- end - local function dirdimensions(parent,begindir) -- can be a helper - local level = 1 - local lastdir = nil - local width = 0 + local level = 1 for current, subtype in nextdir, getnext(begindir) do if subtype == normaldir_code then -- todo level = level + 1 @@ -69,6 +50,7 @@ local function dirdimensions(parent,begindir) -- can be a helper end end return (rangedimensions(parent,begindir)), begindir +-- return getwidth(parent), begindir end nuts.dirdimensions = dirdimensions @@ -84,31 +66,32 @@ local function colorit(list,current,dir,w,h,d) return list, current end -function nodes.tracers.directions(head) - for hlist, subtype in nexthlist, head do - if subtype == line_code then - local list = getlist(hlist) - local w, h, d = getwhd(hlist) - list = colorit(list,list,getdirection(hlist),w,h,d) - for current in nextdir, list do - local dir, cancel = getdirection(current) - if not cancel then - local width = dirdimensions(hlist,current) - list = colorit(list,current,dir,width,h,d) + +local function tracedirections(head) + for parent, id, subtype, list in nextlist, head do + if list then + if subtype == line_code then + local w, h, d = getwhd(parent) + list = colorit(list,list,getdirection(parent),w,h,d) + for current in nextdir, list do + local dir, cancel = getdirection(current) + if not cancel then + local width = dirdimensions(parent,current) + list = colorit(list,current,dir,width,h,d) + end end end - setlist(hlist,list) + tracedirections(list) end end return head end -local enabled = false +nodes.tracers.directions = tracedirections + +-- so, not attribute driven, only shipout, so more a document wide tracer, maybe +-- per page (so keep enabled and delayed disabled trackers.register("nodes.directions", function(v) - if not enabled then - enabled = true - nodes.tasks.appendaction("finalizers","after","nodes.tracers.directions",nil,"nut","enabled") - end - nodes.tasks.setaction(v) + nodes.tasks.setaction("shipouts","nodes.tracers.directions",v) end) diff --git a/tex/context/base/mkxl/node-ini.mkxl b/tex/context/base/mkxl/node-ini.mkxl index b3f17e041..438e6ff01 100644 --- a/tex/context/base/mkxl/node-ini.mkxl +++ b/tex/context/base/mkxl/node-ini.mkxl @@ -26,12 +26,12 @@ %registerctxluafile{node-ppt}{} % experimental, not used so probably useless \registerctxluafile{node-aux}{autosuffix} \registerctxluafile{node-gcm}{autosuffix} -\registerctxluafile{node-tst}{} +\registerctxluafile{node-tst}{autosuffix} \registerctxluafile{node-tra}{autosuffix} \registerctxluafile{node-snp}{autosuffix} -\registerctxluafile{node-tsk}{} +\registerctxluafile{node-tsk}{autosuffix} \registerctxluafile{node-tex}{autosuffix} -\registerctxluafile{node-dir}{} % experimental, not yet (and maybe never) used +\registerctxluafile{node-dir}{autosuffix} \registerctxluafile{node-pro}{autosuffix} \registerctxluafile{node-ser}{autosuffix} \registerctxluafile{node-acc}{autosuffix} % experimental diff --git a/tex/context/base/mkxl/node-tsk.lmt b/tex/context/base/mkxl/node-tsk.lmt new file mode 100644 index 000000000..ca7c7fee4 --- /dev/null +++ b/tex/context/base/mkxl/node-tsk.lmt @@ -0,0 +1,796 @@ +if not modules then modules = { } end modules ['node-tsk'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This might move to task-* and become less code as in sequencers +-- we already have dirty flags as well. On the other hand, nodes are +-- rather specialized and here we focus on node related tasks. + +local format = string.format + +local trace_tasks = false trackers.register("tasks.creation", function(v) trace_tasks = v end) + +local report_tasks = logs.reporter("tasks") + +local allocate = utilities.storage.allocate + +local context = context +local nodes = nodes + +local tasks = nodes.tasks or { } +nodes.tasks = tasks + +local tasksdata = { } -- no longer public + +local sequencers = utilities.sequencers +local compile = sequencers.compile +local nodeprocessor = sequencers.nodeprocessor + +local newsequencer = sequencers.new + +local appendgroup = sequencers.appendgroup +----- prependgroup = sequencers.prependgroup +----- replacegroup = sequencers.replacegroup +local enablegroup = sequencers.enablegroup +local disablegroup = sequencers.disablegroup + +local appendaction = sequencers.appendaction +local prependaction = sequencers.prependaction +local replaceaction = sequencers.replaceaction +local enableaction = sequencers.enableaction +local disableaction = sequencers.disableaction + +local frozengroups = "no" + +function tasks.freeze(kind) + frozengroups = kind or "tolerant" -- todo: hook into jobname +end + +function tasks.new(specification) -- was: name,arguments,list + local name = specification.name + local sequence = specification.sequence + if name and sequence then + local tasklist = newsequencer { + name = name + -- we can move more to the sequencer now .. todo + } + tasksdata[name] = { + name = name, + list = tasklist, + runner = false, + frozen = { }, + processor = specification.processor or nodeprocessor, + -- could be metatable but best freeze it + arguments = specification.arguments or 0, + templates = specification.templates, + } + for l=1,#sequence do + appendgroup(tasklist,sequence[l]) + end + end +end + +local function valid(name) + local data = tasksdata[name] + if not data then + report_tasks("unknown task %a",name) + else + return data + end +end + +local function validgroup(name,group,what) + local data = tasksdata[name] + if not data then + report_tasks("unknown task %a",name) + else + local frozen = data.frozen[group] + if frozen then + if frozengroup == "no" then + -- default + elseif frozengroup == "strict" then + report_tasks("warning: group %a of task %a is frozen, %a applied but not supported",group,name,what) + return + else -- if frozengroup == "tolerant" then + report_tasks("warning: group %a of task %a is frozen, %a ignored",group,name,what) + end + end + return data + end +end + +function tasks.freezegroup(name,group) + local data = valid(name) + if data then + data.frozen[group] = true + end +end + +function tasks.restart(name) + local data = valid(name) + if data then + data.runner = false + end +end + +function tasks.enableaction(name,action) + local data = valid(name) + if data then + enableaction(data.list,action) + data.runner = false + end +end + +function tasks.disableaction(name,action) + local data = valid(name) + if data then + disableaction(data.list,action) + data.runner = false + end +end + +function tasks.replaceaction(name,group,oldaction,newaction) + local data = valid(name) + if data then + replaceaction(data.list,group,oldaction,newaction) + data.runner = false + end +end + +do + + local enableaction = tasks.enableaction + local disableaction = tasks.disableaction + + function tasks.setaction(name,action,value) + if value then + enableaction(name,action) + else + disableaction(name,action) + end + end + +end + +function tasks.enablegroup(name,group) + local data = validgroup(name,"enable group") + if data then + enablegroup(data.list,group) + data.runner = false + end +end + +function tasks.disablegroup(name,group) + local data = validgroup(name,"disable group") + if data then + disablegroup(data.list,group) + data.runner = false + end +end + +function tasks.appendaction(name,group,action,where,kind,state) + local data = validgroup(name,"append action") + if data then + local list = data.list + appendaction(list,group,action,where,kind) + if state == "disabled" or (state == "production" and environment.initex) then + disableaction(list,action) + end + data.runner = false + end +end + +function tasks.prependaction(name,group,action,where,kind,state) + local data = validgroup(name,"prepend action") + if data then + local list = data.list + prependaction(list,group,action,where,kind) + if state == "disabled" or (state == "production" and environment.initex) then + disableaction(list,action) + end + data.runner = false + end +end + +function tasks.removeaction(name,group,action) + local data = validgroup(name,"remove action") + if data then + removeaction(data.list,group,action) + data.runner = false + end +end + +function tasks.showactions(name,group,action,where,kind) + local data = valid(name) + if data then + report_tasks("task %a, list:\n%s",name,nodeprocessor(data.list)) + end +end + +-- Optimizing for the number of arguments makes sense, but getting rid of +-- the nested call (no problem but then we also need to register the +-- callback with this mechanism so that it gets updated) does not save +-- much time (24K calls on mk.tex). + +local created, total = 0, 0 + +statistics.register("node list callback tasks", function() + if total > 0 then + return format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasksdata),created,total) + else + return nil + end +end) + +local function create(data,t) + created = created + 1 + local runner = compile(data.list,data.processor,t) + if trace_tasks then + report_tasks("creating runner %a, %i actions enabled",t.name,data.list.steps or 0) + end + data.runner = runner + return runner +end + +function tasks.actions(name) + local data = tasksdata[name] + if data then + local t = data.templates + if t then + t.name = data.name + return function(...) + total = total + 1 + return (data.runner or create(data,t))(...) + end + end + end + return nil +end + +function tasks.table(name) --maybe move this to task-deb.lua + local tsk = tasksdata[name] + local lst = tsk and tsk.list + local HL, NC, NR, bold, type = context.HL, context.NC, context.NR, context.bold, context.type + if lst then + local list, order = lst.list, lst.order + if list and order then + context.starttabulate { "|l|l|" } + NC() bold("category") NC() bold("function") NC() NR() + for i=1,#order do + HL() + local o = order[i] + local l = list[o] + if #l == 0 then + NC() type(o) NC() context("unset") NC() NR() + else + local done = false + for k, v in table.sortedhash(l) do + NC() if not done then type(o) done = true end NC() type(v) NC() NR() + end + end + end + context.stoptabulate() + end + end +end + +-- -- shipouts everypar -- -- + +-- the shipout handlers acts on boxes so we don't need to return something +-- and also don't need to keep the state (done) + +local templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead)))) +]], + +nut = [[ + nuthead = %action%(nuthead) +]], + +nohead = [[ + %action%(tonode(nuthead)) +]], + +nonut = [[ + %action%(nuthead) +]], + +} + +tasks.new { + name = "shipouts", + processor = nodeprocessor, + sequence = { + "before", -- users + "normalizers", -- system + "finishers", -- system + "after", -- users + "wrapup", -- system + }, + templates = templates +} + +tasks.new { + name = "everypar", + processor = nodeprocessor, + sequence = { + "before", -- users + "normalizers", -- system + "after", -- users + }, + templates = templates, +} + +-- -- finalizers -- -- + +tasks.new { + name = "finalizers", + sequence = { + "before", -- for users + "normalizers", + "fonts", + "lists", + "after", -- for users + }, + processor = nodeprocessor, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode) +]], + +nonut = [[ + %action%(nuthead,groupcode) +]], + + } +} + +-- -- processors -- -- + +tasks.new { + name = "processors", + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "characters", + "words", + "fonts", + "lists", + "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode,size,packtype,direction,attributes) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,direction,attributes))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,size,packtype,direction,attributes) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,size,packtype,direction,attributes) +]], + +nonut = [[ + %action%(nuthead,groupcode,size,packtype,direction,attributes) +]], + + } +} + +tasks.new { + name = "finalizers", + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "fonts", + "lists", + "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead)))) +]], + +nut = [[ + nuthead = %action%(nuthead) +]], + +nohead = [[ + %action%(tonode(nuthead)) +]], + +nonut = [[ + %action%(nuthead) +]], + + } +} + +tasks.new { + name = "mvlbuilders", + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode) +]], + +nonut = [[ + %action%(nuthead,groupcode) +]], + + } +} + +tasks.new { + name = "vboxbuilders", + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode,size,packtype,maxdepth,direction) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction) +]], + +nonut = [[ + %action%(nuthead,groupcode,size,packtype,maxdepth,direction) +]], + + } + +} + +tasks.new { + name = "contributers", + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +-- we operate exclusively on nuts + +return function(nuthead,groupcode,nutline) +%actions% + return nuthead +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,line))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,nutline) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,line) +]], + +nonut = [[ + %action%(nuthead,groupcode,nutline) +]], + + } +} + +-- -- math -- -- + +tasks.new { + name = "math", + processor = nodeprocessor, + sequence = { + "before", + "normalizers", + "builders", + "after", + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,style,penalties) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),style,penalties))) +]], + +nut = [[ + nuthead = %action%(nuthead,style,penalties) +]], + +nohead = [[ + %action%(tonode(nuthead),style,penalties) +]], + +nonut = [[ + %action%(nuthead,style,penalties) +]], + + } +} + +-- tasks.new { +-- name = "parbuilders", +-- arguments = 1, +-- processor = nodeprocessor, +-- sequence = { +-- "before", -- for users +-- "lists", +-- "after", -- for users +-- } +-- } + +-- tasks.new { +-- name = "pagebuilders", +-- arguments = 5, +-- processor = nodeprocessor, +-- sequence = { +-- "before", -- for users +-- "lists", +-- "after", -- for users +-- } +-- } + +-- for now quite useless (too fuzzy) +-- +-- tasks.new { +-- name = "listbuilders", +-- processor = nodeprocessor, +-- sequence = { +-- "before", -- for users +-- "normalizers", +-- "after", -- for users +-- }, +-- templates = { +-- -- we don't need a default +-- default = [[ +-- return function(box,location,prevdepth) +-- return box, prevdepth +-- end +-- ]], +-- process = [[ +-- %localize% +-- return function(box,location,prevdepth,mirrored) +-- %actions% +-- return box, prevdepth +-- end +-- ]], +-- step = [[ +-- box, prevdepth = %action%(box,location,prevdepth,mirrored) +-- ]], +-- }, +-- } + +-- -- math -- -- + +-- not really a node processor + +-- tasks.new { +-- name = "newpar", +-- processor = nodeprocessor, +-- sequence = { +-- "before", +-- "normalizers", +-- "after", +-- }, +-- templates = { +-- +-- default = [[ +-- return function(mode,indent) +-- return indent +-- end +-- ]], +-- +-- process = [[ +-- %localize% +-- +-- return function(mode,indent) +-- +-- %actions% +-- return indent +-- end +-- ]], +-- +-- step = [[ +-- indent = %action%(mode,indent) +-- ]], +-- +-- } +-- } diff --git a/tex/context/base/mkxl/node-tst.lmt b/tex/context/base/mkxl/node-tst.lmt new file mode 100644 index 000000000..c28086f81 --- /dev/null +++ b/tex/context/base/mkxl/node-tst.lmt @@ -0,0 +1,97 @@ +if not modules then modules = { } end modules ['node-tst'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local nodes, node = nodes, node + +local chardata = characters.data +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes + +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local glyph_code = nodecodes.glyph + +local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip +local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip + +local nuts = nodes.nuts + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getchar = nuts.getchar +local getsubtype = nuts.getsubtype +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth + +function nuts.somespace(n,all) + if n then + local id = getid(n) + if id == glue_code then + return (all or (getwidth(n) ~= 0)) and glue_code -- temp: or 0 + elseif id == kern_code then + return (all or (getkern(n) ~= 0)) and kern_code + elseif id == glyph_code then + -- maybe more category checks are needed + return (chardata[getchar(n)].category == "zs") and glyph_code + end + end + return false +end + +function nuts.somepenalty(n,value) + if n then + local id = getid(n) + if id == penalty_code then + if value then + return getpenalty(n) == value + else + return true + end + end + end + return false +end + +function nuts.is_display_math(head) + local n = getprev(head) + while n do + local id = getid(n) + if id == penalty_code then + elseif id == glue_code then + if getsubtype(n) == abovedisplayshortskip_code then + return true + end + else + break + end + n = getprev(n) + end + n = getnext(head) + while n do + local id = getid(n) + if id == penalty_code then + elseif id == glue_code then + if getsubtype(n) == belowdisplayshortskip_code then + return true + end + else + break + end + n = getnext(n) + end + return false +end + +nodes.leftmarginwidth = nodes.vianuts(nuts.leftmarginwidth) +nodes.rightmarginwidth = nodes.vianuts(nuts.rightmarginwidth) +nodes.somespace = nodes.vianuts(nuts.somespace) +nodes.somepenalty = nodes.vianuts(nuts.somepenalty) +nodes.is_display_math = nodes.vianuts(nuts.is_display_math) diff --git a/tex/context/base/mkxl/pack-rul.lmt b/tex/context/base/mkxl/pack-rul.lmt index d99f0a78e..62f305cba 100644 --- a/tex/context/base/mkxl/pack-rul.lmt +++ b/tex/context/base/mkxl/pack-rul.lmt @@ -52,8 +52,10 @@ local getdirection = nuts.getdirection local setshift = nuts.setshift local setwidth = nuts.setwidth local getwidth = nuts.getwidth -local setboxglue = nuts.setboxglue -local getboxglue = nuts.getboxglue +-- local setboxglue = nuts.setboxglue +-- local getboxglue = nuts.getboxglue +local setboxglue = nuts.setglue +local getboxglue = nuts.getglue local hpack = nuts.hpack local getdimensions = nuts.dimensions @@ -135,9 +137,9 @@ local function doreshapeframedbox(n) if list and id == hlist_code then -- called a lot so maybe a simple case is needed if subtype == boxlist_code or subtype == linelist_code then - -- getdirection is irrelevant here so it will go - -- somehow a parfillskip also can get influenced - local p = hpack(list,maxwidth,'exactly',getdirection(h)) -- multiple return value + -- -- getdirection is irrelevant here so it will go + -- local p = hpack(list,maxwidth,'exactly',getdirection(h)) -- multiple return value + local p = hpack(list,maxwidth,'exactly') -- multiple return value local set, order, sign = getboxglue(p) setboxglue(h,set,order,sign) setlist(p) diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl index 78d09295d..1fdececfd 100644 --- a/tex/context/base/mkxl/spac-ali.mkxl +++ b/tex/context/base/mkxl/spac-ali.mkxl @@ -722,17 +722,17 @@ \defcsname\??aligncommand\v!stretch \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_stretch}} \defcsname\??aligncommand\v!extremestretch \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_extreme_stretch}} -\defcsname\??aligncommand \v!final\endcsname{\c_spac_align_state_par_fill\plusone} -\defcsname\??aligncommand1*\v!final\endcsname{\c_spac_align_state_par_fill\plusone} -\defcsname\??aligncommand2*\v!final\endcsname{\c_spac_align_state_par_fill\plustwo} % hardcoded multiplier -\defcsname\??aligncommand3*\v!final\endcsname{\c_spac_align_state_par_fill\plusthree} -\defcsname\??aligncommand4*\v!final\endcsname{\c_spac_align_state_par_fill\plusfour} +\defcsname\??aligncommand \v!final\endcsname{\c_spac_align_state_par_fill\plusone} +\defcsname\??aligncommand 1*\v!final\endcsname{\c_spac_align_state_par_fill\plusone} +\defcsname\??aligncommand 2*\v!final\endcsname{\c_spac_align_state_par_fill\plustwo} % hardcoded multiplier +\defcsname\??aligncommand 3*\v!final\endcsname{\c_spac_align_state_par_fill\plusthree} +\defcsname\??aligncommand 4*\v!final\endcsname{\c_spac_align_state_par_fill\plusfour} % a one shot (only usefull in e.g. framed, also needs tolerance and stretch) -\defcsname\??aligncommand \v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}} -\defcsname\??aligncommand1*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}} -\defcsname\??aligncommand2*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plustwo}} +\defcsname\??aligncommand \v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}} +\defcsname\??aligncommand 1*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}} +\defcsname\??aligncommand 2*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plustwo}} %defcsname\??aligncommand ...\endcsname{\toksapp\t_spac_align_collected{\nopenalties}} %defcsname\??aligncommand ...\endcsname{\toksapp\t_spac_align_collected{\setdefaultpenalties}} diff --git a/tex/context/base/mkxl/task-ini.lmt b/tex/context/base/mkxl/task-ini.lmt new file mode 100644 index 000000000..933bc948d --- /dev/null +++ b/tex/context/base/mkxl/task-ini.lmt @@ -0,0 +1,199 @@ +if not modules then modules = { } end modules ['task-ini'] = { + version = 1.001, + comment = "companion to task-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is a temporary solution, we need to isolate some modules and then +-- the load order can determine the trickery to be applied to node lists +-- +-- we can disable more handlers and enable then when really used (*) +-- +-- todo: two finalizers: real shipout (can be imposed page) and page shipout (individual page) +-- +-- todo: consider moving the kernel kerning/ligaturing functions in the main font loop because +-- there we know if they are needed; doesn't save time but; if we overload unh* commands to +-- not apply the font handler, we can remove all checks for subtypes 255 + +local tasks = nodes.tasks +local appendaction = tasks.appendaction +local disableaction = tasks.disableaction +local enableaction = tasks.enableaction +local freezegroup = tasks.freezegroup +local freezecallbacks = callbacks.freeze + +------------("processors", "before", "nodes.properties.attach", nil, "nut", "enabled" ) + +appendaction("processors", "normalizers", "builders.kernel.collapsing", nil, "nut", "enabled" ) +appendaction("processors", "normalizers", "typesetters.periodkerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "languages.replacements.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "typesetters.wrappers.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "typesetters.characters.handler", nil, "nut", "enabled" ) +appendaction("processors", "normalizers", "fonts.collections.process", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "fonts.checkers.missing", nil, "nut", "disabled" ) + +appendaction("processors", "characters", "scripts.autofontfeature.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "scripts.splitters.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.cleaners.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.directions.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.cases.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.breakpoints.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "scripts.injectors.handler", nil, "nut", "disabled" ) + +appendaction("processors", "words", "languages.words.check", nil, "nut", "disabled" ) +appendaction("processors", "words", "languages.hyphenators.handler", nil, "nut", "enabled" ) +appendaction("processors", "words", "typesetters.initials.handler", nil, "nut", "disabled" ) +appendaction("processors", "words", "typesetters.firstlines.handler", nil, "nut", "disabled" ) + +appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.characters", nil, "nut", "enabled" ) +appendaction("processors", "fonts", "nodes.injections.handler", nil, "nut", "enabled" ) +appendaction("processors", "fonts", "typesetters.fontkerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nonut", "enabled" ) +appendaction("processors", "fonts", "builders.kernel.ligaturing", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "builders.kernel.kerning", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.show", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.stripping", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.flatten", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "fonts.goodies.colorschemes.coloring", nil, "nut", "disabled" ) + +appendaction("processors", "lists", "typesetters.rubies.check", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.characteralign.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.spacings.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.kerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.digits.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.italics.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "languages.visualizediscretionaries", nil, "nut", "disabled" ) + +appendaction("processors", "after", "typesetters.marksuspects", nil, "nut", "disabled" ) + +appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "production") +appendaction("shipouts", "normalizers", "typesetters.showsuspects", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.alignments.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.references.handler", nil, "nut", "production") +appendaction("shipouts", "normalizers", "nodes.destinations.handler", nil, "nut", "production") +appendaction("shipouts", "normalizers", "nodes.rules.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.shifts.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "structures.tags.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.handlers.accessibility", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.rubies.attach", nil, "nut", "disabled" ) +------------("shipouts", "normalizers", "nodes.properties.delayed", nil, "nut", "production") +appendaction("shipouts", "normalizers", "nodes.tracers.directions", nil, "nut", "disabled" ) + +appendaction("shipouts", "finishers", "nodes.visualizers.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.colors.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.transparencies.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.colorintents.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.negatives.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.effects.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.alternates.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.viewerlayers.handler", nil, "nut", "disabled" ) + +appendaction("shipouts", "wrapup", "nodes.handlers.export", nil, "nut", "disabled" ) -- always last +appendaction("shipouts", "wrapup", "luatex.synctex.collect", nil, "nut", "disabled" ) + +appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.unstack", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.variants", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.families", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.render", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.fixscripts", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.domains", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.autofences", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.resize", nil, "nonut", "enabled" ) +------------("math", "normalizers", "noads.handlers.respace", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.alternates", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.tags", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.italics", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.classes", nil, "nonut", "disabled" ) + +appendaction("math", "builders", "builders.kernel.mlist_to_hlist", nil, "nut", "enabled" ) -- mandate +appendaction("math", "builders", "typesetters.directions.processmath", nil, "nut", "disabled" ) +appendaction("math", "builders", "noads.handlers.makeup", nil, "nonut", "disabled" ) +appendaction("math", "builders", "noads.handlers.align", nil, "nonut", "enabled" ) + +appendaction("finalizers", "lists", "nodes.handlers.showhyphenation", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "nodes.handlers.visualizehyphenation", nil, "nut", "disabled" ) + +appendaction("finalizers", "lists", "typesetters.margins.localhandler", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "builders.paragraphs.keeptogether", nil, "nut", "disabled" ) +appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize", nil, "nonut", "disabled" ) +appendaction("finalizers", "lists", "builders.paragraphs.tag", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "nodes.linefillers.handler", nil, "nut", "disabled" ) + + +appendaction("contributers", "normalizers", "nodes.handlers.flattenline", nil, "nut", "disabled" ) +appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds", nil, "nut", "disabled" ) +appendaction("contributers", "normalizers", "nodes.handlers.wipe", nil, "nut", "disabled" ) + +appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox", nil, "nut", "disabled" ) +------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler", nil, "nut", "disabled" ) +appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler", nil, "nut", "enabled" ) +appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler", nil, "nut", "disabled" ) +appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) + +appendaction("mvlbuilders", "normalizers", "nodes.handlers.backgroundspage", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler", nil, "nut", "enabled" ) +appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) + +appendaction("everypar", "normalizers", "nodes.handlers.checkparcounter", nil, "nut", "disabled" ) + +-- some protection + +freezecallbacks("find_.*_file", "find file using resolver") +freezecallbacks("read_.*_file", "read file at once") +freezecallbacks("open_.*_file", "open file for reading") + +-- experimental: + +freezegroup("processors", "normalizers") +freezegroup("processors", "characters") +freezegroup("processors", "words") +freezegroup("processors", "fonts") +freezegroup("processors", "lists") + +freezegroup("finalizers", "normalizers") +freezegroup("finalizers", "fonts") +freezegroup("finalizers", "lists") + +freezegroup("math", "normalizers") +freezegroup("math", "builders") + +freezegroup("shipouts", "normalizers") +freezegroup("shipouts", "finishers") +freezegroup("shipouts", "wrapup") + +freezegroup("mvlbuilders", "normalizers") +freezegroup("vboxbuilders", "normalizers") + +-----------("parbuilders", "lists") +-----------("pagebuilders", "lists") + +freezegroup("math", "normalizers") +freezegroup("math", "builders") + +freezegroup("everypar", "normalizers") + +-- new: disabled here + +directives.register("nodes.basepass", function(v) + if v then + enableaction("processors", "builders.kernel.ligaturing") + enableaction("processors", "builders.kernel.kerning") + else + disableaction("processors", "builders.kernel.ligaturing") + disableaction("processors", "builders.kernel.kerning") + end +end) diff --git a/tex/context/base/mkxl/typo-spa.lmt b/tex/context/base/mkxl/typo-spa.lmt index 84dd0696d..f453814fb 100644 --- a/tex/context/base/mkxl/typo-spa.lmt +++ b/tex/context/base/mkxl/typo-spa.lmt @@ -96,10 +96,8 @@ function spacings.handler(head) local ok = false local prevprev = getprev(prev) if alternative == 1 then - local somespace = somespace(prev,true) - if somespace then - local somepenalty = somepenalty(prevprev,10000) - if somepenalty then + if somespace(prev,true) then + if somepenalty(prevprev,10000) then if trace_spacing then report_spacing("removing penalty and space before %C (left)",char) end @@ -129,24 +127,19 @@ function spacings.handler(head) local ok = false local nextnext = getnext(next) if alternative == 1 then - local somepenalty = somepenalty(next,10000) - if somepenalty then - local somespace = somespace(nextnext,true) - if somespace then + if somepenalty(next,10000) then + if somespace(nextnext,true) then if trace_spacing then report_spacing("removing penalty and space after %C right",char) end head = remove_node(head,next,true) head = remove_node(head,nextnext,true) end - else - local somespace = somespace(next,true) - if somespace then - if trace_spacing then - report_spacing("removing space after %C (right)", char) - end - head = remove_node(head,next,true) + elseif somespace(next,true) then + if trace_spacing then + report_spacing("removing space after %C (right)", char) end + head = remove_node(head,next,true) end ok = true else diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index 9797b8d1f..8c9a389f3 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -767,6 +767,7 @@ <cd:constant name='coupling' value='koppeling'/> <cd:constant name='couplingway' value='koppelwijze'/> <cd:constant name='criterium' value='criterium'/> + <cd:constant name='crop' value='crop'/> <cd:constant name='cropoffset' value='cropoffset'/> <cd:constant name='crossreference' value='crossreference'/> <cd:constant name='cssfile' value='cssfile'/> diff --git a/tex/context/patterns/lmtx/lang-de.llg b/tex/context/patterns/lmtx/lang-de.llg index b7230d0fa..89b8eef1f 100644 --- a/tex/context/patterns/lmtx/lang-de.llg +++ b/tex/context/patterns/lmtx/lang-de.llg @@ -2634,9 +2634,9 @@ return { }, { patterns = { - ffi = "f|f|i", - ffl = "f|f|l", - fff = "f|f|f", + ffi = "ff|i", + ffl = "ff|l", + fff = "ff|f", }, words = [[ Griffleisten diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 86d81983a..09fb9e955 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-04-28 18:34 +-- merge date : 2021-04-29 23:04 do -- begin closure to overcome local limits and interference @@ -29949,44 +29949,52 @@ do return head end end -local plugins={} -otf.plugins=plugins -local report=logs.reporter("fonts") -function otf.registerplugin(name,f) - if type(name)=="string" and type(f)=="function" then - plugins[name]={ name,f } - report() - report("plugin %a has been loaded, please be aware of possible side effects",name) - report() - if logs.pushtarget then - logs.pushtarget("log") - end - report("Plugins are not officially supported unless stated otherwise. This is because") - report("they bypass the regular font handling and therefore some features in ConTeXt") - report("(especially those related to fonts) might not work as expected or might not work") - report("at all. Some plugins are for testing and development only and might change") - report("whenever we feel the need for it.") - report() - if logs.poptarget then - logs.poptarget() +do + local plugins={} + otf.plugins=plugins + local report=logs.reporter("fonts") + local warned=false + local okay={ text=true } + function otf.registerplugin(name,f) + if type(name)=="string" and type(f)=="function" then + plugins[name]={ name,f } + if okay[name] then + else + report("plugin %a has been loaded, please be aware of possible side effects",name) + if not warned then + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end + warned=true + end + end end end -end -function otf.plugininitializer(tfmdata,value) - if type(value)=="string" then - tfmdata.shared.plugin=plugins[value] + function otf.plugininitializer(tfmdata,value) + if type(value)=="string" then + tfmdata.shared.plugin=plugins[value] + end end -end -function otf.pluginprocessor(head,font,attr,direction) - local s=fontdata[font].shared - local p=s and s.plugin - if p then - if trace_plugins then - report_process("applying plugin %a",p[1]) + function otf.pluginprocessor(head,font,dynamic,direction) + local s=fontdata[font].shared + local p=s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font,dynamic,direction) + else + return head,false end - return p[2](head,font,attr,direction) - else - return head,false end end function otf.featuresinitializer(tfmdata,value) |