From 5c6357cdb820b4f628d036ba7b2248f221d50c0b Mon Sep 17 00:00:00 2001
From: Luigi Scarso
Some code may move to a module in the language namespace.
--ldx]]-- -local floor, date, time, concat = math.floor, os.date, os.time, table.concat +local floor, osdate, ostime, concat = math.floor, os.date, os.time, table.concat local lower, upper, rep, match, gsub = string.lower, string.upper, string.rep, string.match, string.gsub local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring, type, rawset = tonumber, tostring, type, rawset @@ -33,6 +33,7 @@ local setmetatableindex = table.setmetatableindex local formatters = string.formatters local variables = interfaces.variables local constants = interfaces.constants +local addformatter = utilities.strings.formatters.add local texset = tex.set @@ -42,6 +43,9 @@ local converters = converters languages = languages or { } local languages = languages +local helpers = converters.helpers or { } +converters.helpers = helpers + local ctx_labeltext = context.labeltext local ctx_LABELTEXT = context.LABELTEXT local ctx_space = context.space @@ -304,14 +308,14 @@ local function leapyear(year) end local function textime() - return tonumber(date("%H")) * 60 + tonumber(date("%M")) + return tonumber(osdate("%H")) * 60 + tonumber(osdate("%M")) end -function converters.year () return date("%Y") end -function converters.month () return date("%m") end -function converters.hour () return date("%H") end -function converters.minute() return date("%M") end -function converters.second() return date("%S") end +function converters.year () return osdate("%Y") end +function converters.month () return osdate("%m") end +function converters.hour () return osdate("%H") end +function converters.minute() return osdate("%M") end +function converters.second() return osdate("%S") end converters.weekday = weekday converters.isleapyear = isleapyear @@ -323,11 +327,11 @@ implement { name = "weekday", actions = { weekday, context }, arguments = { "i implement { name = "leapyear", actions = { leapyear, context }, arguments = { "integer" } } implement { name = "nofdays", actions = { nofdays, context }, arguments = { "integer", "integer" } } -implement { name = "year", actions = { date, context }, arguments = "'%Y'" } -implement { name = "month", actions = { date, context }, arguments = "'%m'" } -implement { name = "hour", actions = { date, context }, arguments = "'%H'" } -implement { name = "minute", actions = { date, context }, arguments = "'%M'" } -implement { name = "second", actions = { date, context }, arguments = "'%S'" } +implement { name = "year", actions = { osdate, context }, arguments = "'%Y'" } +implement { name = "month", actions = { osdate, context }, arguments = "'%m'" } +implement { name = "hour", actions = { osdate, context }, arguments = "'%H'" } +implement { name = "minute", actions = { osdate, context }, arguments = "'%M'" } +implement { name = "second", actions = { osdate, context }, arguments = "'%S'" } implement { name = "textime", actions = { textime, context } } implement { @@ -1222,45 +1226,108 @@ setmetatableindex(months, function(t,k) return "unknown" end) setmetatableindex(days, function(t,k) return "unknown" end) setmetatableindex(monthmnems, function(t,k) return months[k] .. ":mnem" end) -local function dayname(n) - return days[n] -end +do -local function weekdayname(day,month,year) - return days[weekday(day,month,year)] -end + local function dayname(n) + ctx_labeltext(days[n]) + end -local function monthname(n) - return months[n] -end + local function weekdayname(day,month,year) + ctx_labeltext(days[weekday(day,month,year)]) + end -local function monthmnem(n) - return monthmnems[n] -end + local function monthname(n) + ctx_labeltext(months[n]) + end -implement { - name = "dayname", - actions = { dayname, ctx_labeltext }, - arguments = "integer", -} + local function monthmnem(n) + ctx_labeltext(monthmnems[n]) + end -implement { - name = "weekdayname", - actions = { weekdayname, ctx_labeltext }, - arguments = { "integer", "integer", "integer" } -} + implement { + name = "dayname", + actions = dayname, + arguments = "integer", + } -implement { - name = "monthname", - actions = { monthname, ctx_labeltext }, - arguments = { "integer" } -} + implement { + name = "weekdayname", + actions = weekdayname, + arguments = { "integer", "integer", "integer" } + } -implement { - name = "monthmnem", - actions = { monthmnem, ctx_labeltext }, - arguments = { "integer" } -} + implement { + name = "monthname", + actions = monthname, + arguments = { "integer" } + } + + implement { + name = "monthmnem", + actions = monthmnem, + arguments = { "integer" } + } + + local f_monthlong = formatters["\\monthlong{%s}"] + local f_monthshort = formatters["\\monthshort{%s}"] + local f_weekday = formatters["\\weekday{%s}"] + local f_dayoftheweek = formatters["\\dayoftheweek{%s}{%s}{%s}"] + + local function tomonthlong (m) return f_monthlong (tonumber(m) or 1) end + local function tomonthshort(m) return f_monthshort(tonumber(m) or 1) end + local function toweekday (d) return f_weekday (tonumber(d) or 1) end + + local function todayoftheweek(d,m,y) + return f_dayoftheweek(tonumber(d) or 1,tonumber(m) or 1,tonumber(y) or 2000) + end + + addformatter(formatters,"monthlong", [[tomonthlong(%s)]], { tomonthlong = tomonthlong }) + addformatter(formatters,"monthshort", [[tomonthshort(%s)]], { tomonthshort = tomonthshort }) + addformatter(formatters,"weekday", [[toweekday(%s)]], { toweekday = toweekday }) + addformatter(formatters,"dayoftheweek",[[todayoftheweek(%s,%s,%s)]],{ todayoftheweek = todayoftheweek }) + + -- using %t is slower, even with caching as we seldom use > 3 items per epoch + + local function toeyear (e) return osdate("%Y",tonumber(e)) end + local function toemonth (e) return osdate("%m",tonumber(e)) end + local function toeday (e) return osdate("%d",tonumber(e)) end + local function toeminute(e) return osdate("%M",tonumber(e)) end + local function toesecond(e) return osdate("%S",tonumber(e)) end + + local function toemonthlong(e) + return f_monthlong(tonumber(osdate("%m",tonumber(e)))) + end + + local function toemonthshort(e) + return f_monthshort(tonumber(osdate("%m",tonumber(e)))) + end + + local function toeweek(e) -- we run from 1-7 not 0-6 + return tostring(tonumber(osdate("%w",tonumber(e)))+1) + end + + local function toeweekday(e) + return f_weekday(tonumber(osdate("%w",tonumber(e)))+1) + end + + local function toedate(format,e) + return osdate(format,tonumber(e)) + end + + addformatter(formatters,"eyear", [[toeyear(%s)]], { toeyear = toeyear }) + addformatter(formatters,"emonth", [[toemonth(%s)]], { toemonth = toemonth }) + addformatter(formatters,"eday", [[toeday(%s)]], { toeday = toeday }) + addformatter(formatters,"eweek", [[toeweek(%s)]], { toeweek = toeweek }) + addformatter(formatters,"eminute", [[toeminute(%s)]], { toeminute = toeminute }) + addformatter(formatters,"esecond", [[toesecond(%s)]], { toesecond = toesecond }) + + addformatter(formatters,"emonthlong", [[toemonthlong(%s)]], { toemonthlong = toemonthlong }) + addformatter(formatters,"emonthshort", [[toemonthshort(%s)]], { toemonthshort = toemonthshort }) + addformatter(formatters,"eweekday", [[toeweekday(%s)]], { toeweekday = toeweekday }) + + addformatter(formatters,"edate", [[toedate(%s,%s)]], { toedate = toedate }) + +end -- a prelude to a function that we can use at the lua end @@ -1287,125 +1354,146 @@ local variants = { jalali = setmetatableindex(function(t,k) return months[k] .. ":jalali" end), } -local function currentdate(str,currentlanguage) -- second argument false : no label - local list = utilities.parsers.settings_to_array(str) - local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right - local year = tex.year - local month = tex.month - local day = tex.day - local auto = true - if currentlanguage == "" then - currentlanguage = false - end - for i=1,#list do - local entry = list[i] - local convert = dateconverters[entry] - if convert then - year, month, day = convert(year,month,day) - else - local tag, plus = splitlabel(entry) - local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false - if not tag then - tag = entry - elseif plus == "+" or plus == "ord" then - ordinal = true - elseif plus == "++" or plus == "highord" then - ordinal = true - highordinal = true - -- elseif plus == "mnem" then - -- mnemonic = true - elseif plus then -- elseif plus == "mnem" then - mnemonic = variants[plus] - end - if not auto and spaced[tag] then - ctx_space() - end - auto = false - if tag == v_year or tag == "y" or tag == "Y" then - context(year) - elseif tag == "yy" or tag == "YY" then - context("%02i",year % 100) - elseif tag == v_month or tag == "m" then - if currentlanguage == false then - context(Word(months[month])) - elseif mnemonic then - ctx_labeltext(variables[mnemonic[month]]) - else - ctx_labeltext(variables[months[month]]) +do + + local function currentdate(str,currentlanguage,year,month,day) -- second argument false : no label + local list = utilities.parsers.settings_to_array(str) + local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right + -- local year = tex.year + -- local month = tex.month + -- local day = tex.day + local auto = true + if currentlanguage == "" then + currentlanguage = false + end + for i=1,#list do + local entry = list[i] + local convert = dateconverters[entry] + if convert then + year, month, day = convert(year,month,day) + else + local tag, plus = splitlabel(entry) + local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false + if not tag then + tag = entry + elseif plus == "+" or plus == "ord" then + ordinal = true + elseif plus == "++" or plus == "highord" then + ordinal = true + highordinal = true + -- elseif plus == "mnem" then + -- mnemonic = true + elseif plus then -- elseif plus == "mnem" then + mnemonic = variants[plus] end - elseif tag == v_MONTH then - if currentlanguage == false then - context(Word(variables[months[month]])) - elseif mnemonic then - ctx_LABELTEXT(variables[mnemonic[month]]) - else - ctx_LABELTEXT(variables[months[month]]) + if not auto and spaced[tag] then + ctx_space() end - elseif tag == "mm" then - context("%02i",month) - elseif tag == "M" then - context(month) - elseif tag == v_day or tag == "d" then - if currentlanguage == false then + auto = false + if tag == v_year or tag == "y" or tag == "Y" then + context(year) + elseif tag == "yy" or tag == "YY" then + context("%02i",year % 100) + elseif tag == v_month or tag == "m" then + if currentlanguage == false then + context(Word(months[month])) + elseif mnemonic then + ctx_labeltext(variables[mnemonic[month]]) + else + ctx_labeltext(variables[months[month]]) + end + elseif tag == v_MONTH then + if currentlanguage == false then + context(Word(variables[months[month]])) + elseif mnemonic then + ctx_LABELTEXT(variables[mnemonic[month]]) + else + ctx_LABELTEXT(variables[months[month]]) + end + elseif tag == "mm" then + context("%02i",month) + elseif tag == "M" then + context(month) + elseif tag == v_day or tag == "d" then + if currentlanguage == false then + context(day) + else + ctx_convertnumber(v_day,day) -- why not direct + end + whatordinal = day + elseif tag == "dd" then + context("%02i",day) + whatordinal = day + elseif tag == "D" then context(day) - else - ctx_convertnumber(v_day,day) -- why not direct + whatordinal = day + elseif tag == v_weekday or tag == "w" then + local wd = weekday(day,month,year) + if currentlanguage == false then + context(Word(days[wd])) + else + ctx_labeltext(variables[days[wd]]) + end + elseif tag == v_WEEKDAY then + local wd = weekday(day,month,year) + if currentlanguage == false then + context(Word(days[wd])) + else + ctx_LABELTEXT(variables[days[wd]]) + end + elseif tag == "W" then + context(weekday(day,month,year)) + elseif tag == v_referral then + context("%04i%02i%02i",year,month,day) + elseif tag == v_space or tag == "\\ " then + ctx_space() + auto = true + elseif tag ~= "" then + context(tag) + auto = true end - whatordinal = day - elseif tag == "dd" then - context("%02i",day) - whatordinal = day - elseif tag == "D" then - context(day) - whatordinal = day - elseif tag == v_weekday or tag == "w" then - local wd = weekday(day,month,year) - if currentlanguage == false then - context(Word(days[wd])) - else - ctx_labeltext(variables[days[wd]]) - end - elseif tag == v_WEEKDAY then - local wd = weekday(day,month,year) - if currentlanguage == false then - context(Word(days[wd])) - else - ctx_LABELTEXT(variables[days[wd]]) - end - elseif tag == "W" then - context(weekday(day,month,year)) - elseif tag == v_referral then - context("%04i%02i%02i",year,month,day) - elseif tag == v_space or tag == "\\ " then - ctx_space() - auto = true - elseif tag ~= "" then - context(tag) - auto = true - end - if ordinal and whatordinal then - if currentlanguage == false then - -- ignore - else - context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + if ordinal and whatordinal then + if currentlanguage == false then + -- ignore + else + context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + end end end end end -end + implement { + name = "currentdate", + arguments = { "string", "string", "string", "integer", "integer", "integer" }, + actions = function(pattern,default,language,year,month,day) + currentdate( + pattern == "" and default or pattern, + language == "" and false or language, + year, month, day + ) + end, + } + + local function todate(s,y,m,d) + if y or m or d then + return formatters["\\date[y=%s,m=%s,d=%s][%s]\\relax"](y or "",m or "",d or "",s or "") + else + return formatters["\\currentdate[%s]\\relax"](s) + end + end + + addformatter(formatters,"date", [[todate(...)]], { todate = todate }) + -- context("one: %4!date!","MONTH",2020,12,11) context.par() + -- context("one: %4!date!","month",2020,12,11) context.par() + -- context("one: %4!date!","year,-,mm,-,dd",2020,12,11) context.par() -implement { - name = "currentdate", - arguments = "3 strings", - actions = function(pattern,default,language) - currentdate( - pattern == "" and default or pattern, - language == "" and false or language - ) - end, -} + -- context("two: %3!date!","MONTH",false,12) context.par() + -- context("two: %3!date!","month",false,12) context.par() + -- context("two: %3!date!","year,-,mm,-,dd",false,12) context.par() + +end implement { name = "unihex", @@ -1586,3 +1674,4 @@ implement { } } } + diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-con.mkiv b/Master/texmf-dist/tex/context/base/mkiv/core-con.mkiv index b4f247fcb28..303fb12910f 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-con.mkiv +++ b/Master/texmf-dist/tex/context/base/mkiv/core-con.mkiv @@ -190,10 +190,10 @@ %D want to use as meaningful commands as possible, and because \TEX\ already %D uses up some of those, we save the original meanings. -\savenormalmeaning\time -\savenormalmeaning\year -\savenormalmeaning\month -\savenormalmeaning\day +% \savenormalmeaning\time +% \savenormalmeaning\year +% \savenormalmeaning\month +% \savenormalmeaning\day %D \macros %D {month,MONTH} @@ -218,7 +218,7 @@ %D \showsetup{month} %D \showsetup{MONTH} -\let\month \monthlong +\let\month\monthlong \unexpanded\def\MONTH #1{\WORD{\month {#1}}} \unexpanded\def\MONTHLONG #1{\WORD{\monthlong {#1}}} @@ -414,30 +414,43 @@ {\dosingleempty\syst_converters_current_date} \def\syst_converters_current_date[#1]% - {\begingroup + {\dontleavehmode + \begingroup \the\everycurrentdate - \clf_currentdate{#1}{\currentdatespecification}{\labellanguage}% + \clf_currentdate + {#1}{\currentdatespecification}{\labellanguage}% + \normalyear\normalmonth\normalday \endgroup} \unexpanded\def\date {\dodoubleempty\syst_converters_date} \def\syst_converters_date[#1][#2]% - {\begingroup + {\dontleavehmode + \begingroup + \scratchcounterone \normalyear + \scratchcountertwo \normalmonth + \scratchcounterthree\normalday \iffirstargument - \letdummyparameter\c!d\normalday - \letdummyparameter\c!m\normalmonth - \letdummyparameter\c!y\normalyear + \letdummyparameter\c!y\empty + \letdummyparameter\c!m\empty + \letdummyparameter\c!d\empty \getdummyparameters[#1]% - \normalday \directdummyparameter\c!d\relax - \normalmonth\directdummyparameter\c!m\relax - \normalyear \directdummyparameter\c!y\relax + \edef\temp{\dummyparameter\c!y}\ifx\temp\empty\else\scratchcounterone \temp\fi + \edef\temp{\dummyparameter\c!m}\ifx\temp\empty\else\scratchcountertwo \temp\fi + \edef\temp{\dummyparameter\c!d}\ifx\temp\empty\else\scratchcounterthree\temp\fi + \relax \fi - \syst_converters_current_date[#2]% + \the\everycurrentdate + \clf_currentdate + {#2}{\currentdatespecification}{\labellanguage}% + \scratchcounterone\scratchcountertwo\scratchcounterthree \endgroup} \def\rawdate[#1]% expandable and no labels - {\clf_currentdate{#1}{\currentdatespecification}{}} + {\clf_currentdate + {#1}{\currentdatespecification}{}% + \normalyear\normalmonth\normalday} %D \macros %D {currenttime} @@ -454,7 +467,7 @@ \let\currentminute\!!plusone \let\currentsecond\!!plusone -\def\currenttimespecification{h,:,m} +% \def\currenttimespecification{h,:,m} \unexpanded\def\currenttime {\doifelsenextoptional\syst_converters_current_time_yes\syst_converters_current_time_nop} @@ -805,61 +818,119 @@ \ifdefined\symbol \else \def\symbol[#1]{#1} \fi % todo +% \defineconversion +% [set 0] +% [{\symbol[bullet]}, +% {\symbol[dash]}, +% {\symbol[star]}, +% {\symbol[triangle]}, +% {\symbol[circle]}, +% {\symbol[medcircle]}, +% {\symbol[bigcircle]}, +% {\symbol[square]}, +% {\symbol[checkmark]}] + +% \defineconversion +% [set 1] +% [\mathematics{\star}, +% \mathematics{\star\star}, +% \mathematics{\star\star\star}, +% \mathematics{\ddagger}, +% \mathematics{\ddagger\ddagger}, +% \mathematics{\ddagger\ddagger\ddagger}, +% \mathematics{\ast}, +% \mathematics{\ast\ast}, +% \mathematics{\ast\ast\ast}] +% +% \defineconversion +% [set 2] +% [\mathematics{\ast}, +% \mathematics{\dag}, +% \mathematics{\ddag}, +% \mathematics{\ast\ast}, +% \mathematics{\dag\dag}, +% \mathematics{\ddag\ddag}, +% \mathematics{\ast\ast\ast}, +% \mathematics{\dag\dag\dag}, +% \mathematics{\ddag\ddag\ddag}, +% \mathematics{\ast\ast\ast\ast}, +% \mathematics{\dag\dag\dag\dag}, +% \mathematics{\ddag\ddag\ddag\ddag}] +% +% \defineconversion +% [set 3] +% [\mathematics{\star}, +% \mathematics{\star\star}, +% \mathematics{\star\star\star}, +% \mathematics{\ddagger}, +% \mathematics{\ddagger\ddagger}, +% \mathematics{\ddagger\ddagger\ddagger}, +% \mathematics{\P}, +% \mathematics{\P\P}, +% \mathematics{\P\P\P}, +% \mathematics{\S}, +% \mathematics{\S\S}, +% \mathematics{\S\S\S}, +% \mathematics{\ast}, +% \mathematics{\ast\ast}, +% \mathematics{\ast\ast\ast}] + \defineconversion [set 0] - [{\symbol[bullet]}, - {\symbol[dash]}, - {\symbol[star]}, - {\symbol[triangle]}, - {\symbol[circle]}, - {\symbol[medcircle]}, - {\symbol[bigcircle]}, - {\symbol[square]}] + [\symbol{bullet}, + \symbol{dash}, + \symbol{star}, + \symbol{triangle}, + \symbol{circle}, + \symbol{medcircle}, + \symbol{bigcircle}, + \symbol{square}, + \symbol{checkmark}] \defineconversion [set 1] - [\mathematics{\star}, - \mathematics{\star\star}, - \mathematics{\star\star\star}, - \mathematics{\ddagger}, - \mathematics{\ddagger\ddagger}, - \mathematics{\ddagger\ddagger\ddagger}, - \mathematics{\ast}, - \mathematics{\ast\ast}, - \mathematics{\ast\ast\ast}] + [\textormathchars{⋆}, + \textormathchars{⋆⋆}, + \textormathchars{⋆⋆⋆}, + \textormathchars{‡}, + \textormathchars{‡‡}, + \textormathchars{‡‡‡}, + \textormathchars{∗}, + \textormathchars{∗∗}, + \textormathchars{∗∗∗}] \defineconversion [set 2] - [\mathematics{*}, - \mathematics{\dag}, - \mathematics{\ddag}, - \mathematics{**}, - \mathematics{\dag\dag}, - \mathematics{\ddag\ddag}, - \mathematics{***}, - \mathematics{\dag\dag\dag}, - \mathematics{\ddag\ddag\ddag}, - \mathematics{****}, - \mathematics{\dag\dag\dag\dag}, - \mathematics{\ddag\ddag\ddag\ddag}] + [\textormathchars{∗}, + \textormathchars{†}, + \textormathchars{‡}, + \textormathchars{∗∗}, + \textormathchars{††}, + \textormathchars{‡‡}, + \textormathchars{∗∗∗}, + \textormathchars{†††}, + \textormathchars{‡‡‡}, + \textormathchars{∗∗∗∗}, + \textormathchars{††††}, + \textormathchars{‡‡‡‡}] \defineconversion [set 3] - [\mathematics{\star}, - \mathematics{\star\star}, - \mathematics{\star\star\star}, - \mathematics{\ddagger}, - \mathematics{\ddagger\ddagger}, - \mathematics{\ddagger\ddagger\ddagger}, - \mathematics{\P}, - \mathematics{\P\P}, - \mathematics{\P\P\P}, - \mathematics{\S}, - \mathematics{\S\S}, - \mathematics{\S\S\S}, - \mathematics{\ast}, - \mathematics{\ast\ast}, - \mathematics{\ast\ast\ast}] + [\textormathchars{⋆}, + \textormathchars{⋆⋆}, + \textormathchars{⋆⋆⋆}, + \textormathchars{‡}, + \textormathchars{‡‡}, + \textormathchars{‡‡‡}, + \textormathchars{¶}, + \textormathchars{¶¶}, + \textormathchars{¶¶¶}, + \textormathchars{§}, + \textormathchars{§§}, + \textormathchars{§§§}, + \textormathchars{∗}, + \textormathchars{∗∗}, + \textormathchars{∗∗∗}] %D Iteration of suggestion by WS on mailinglist 2010.12.22: %D @@ -888,4 +959,23 @@ data {#1}% \relax} +%D For those who sart counting at zero: +%D +%D \starttyping +%D \defineconversionset [zero] [n,zero] [n] +%D +%D \setuphead [sectionconversionset=zero] +%D +%D \starttext +%D \startchapter [title=Introduction] +%D \startsection [title=First topic] \stopsection +%D \startsection [title=Second topic] \stopsection +%D \stopchapter +%D \stoptext +%D \stoptyping + +\def\zeronumberconversion#1{\number\numexpr#1-\plusone\relax} + +\defineconversion [zero] [\zeronumberconversion] + \protect \endinput diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-dat.lua b/Master/texmf-dist/tex/context/base/mkiv/core-dat.lua index fa4d089d057..b497501598b 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-dat.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/core-dat.lua @@ -15,6 +15,7 @@ local tonumber, tostring, type = tonumber, tostring, type local context = context local commands = commands +local ctx_latelua = context.latelua local trace_datasets = false trackers.register("job.datasets" , function(v) trace_datasets = v end) local trace_pagestates = false trackers.register("job.pagestates", function(v) trace_pagestates = v end) @@ -35,6 +36,7 @@ local v_yes = interfaces.variables.yes local new_latelua = nodes.pool.latelua local implement = interfaces.implement +local getnamespace = interfaces.getnamespace local collected = allocate() local tobesaved = allocate() @@ -106,6 +108,9 @@ end datasets.setdata = setdata function datasets.extend(name,tag) + if type(name) == "table" then + name, tag = name.name, name.tag + end local set = sets[name] local order = set.order + 1 local realpage = texgetcount("realpageno") @@ -146,10 +151,8 @@ local function setdataset(settings) local name, tag = setdata(settings) if settings.delay ~= v_yes then -- - elseif type(tag) == "number" then - context(new_latelua(formatters["job.datasets.extend(%q,%i)"](name,tag))) else - context(new_latelua(formatters["job.datasets.extend(%q,%q)"](name,tag))) + context(new_latelua { action = job.datasets.extend, name = name, tag = tag }) end end @@ -242,9 +245,7 @@ local function setstate(settings) return name, tag, data end -pagestates.setstate = setstate - -function pagestates.extend(name,tag) +local function extend(name,tag) local realpage = texgetcount("realpageno") if trace_pagestates then report_pagestate("action %a, name %a, tag %a, preset %a","synchronize",name,tag,realpage) @@ -252,7 +253,7 @@ function pagestates.extend(name,tag) tobesaved[name][tag] = realpage end -function pagestates.realpage(name,tag,default) +local function realpage(name,tag,default) local t = collected[name] if t then t = t[tag] or t[tonumber(tag)] @@ -267,21 +268,36 @@ function pagestates.realpage(name,tag,default) return default end -local function setpagestate(settings) - local name, tag, data = setstate(settings) - if type(tag) == "number" then - context(new_latelua(formatters["job.pagestates.extend(%q,%i)"](name,tag))) - else - context(new_latelua(formatters["job.pagestates.extend(%q,%q)"](name,tag))) - end -end - -local function pagestaterealpage(name,tag) +local function realpageorder(name,tag) local t = collected[name] - t = t and (t[tag] or t[tonumber(tag)]) if t then - context(t) + local p = t[tag] + if p then + local n = 1 + for i=tag-1,1,-1 do + if t[i] == p then + n = n +1 + end + end + return n + end end + return 0 +end + +pagestates.setstate = setstate +pagestates.extend = extend +pagestates.realpage = realpage +pagestates.realpageorder = realpageorder + +function pagestates.countervalue(name) + return name and texgetcount(getnamespace("pagestatecounter") .. name) or 0 +end + +local function setpagestate(settings) + local name, tag = setstate(settings) + -- context(new_latelua(function() extend(name,tag) end)) + ctx_latelua(function() extend(name,tag) end) end local function setpagestaterealpageno(name,tag) @@ -304,7 +320,7 @@ implement { implement { name = "pagestaterealpage", - actions = pagestaterealpage, + actions = { realpage, context }, arguments = "2 strings", } @@ -313,3 +329,9 @@ implement { actions = setpagestaterealpageno, arguments = "2 strings", } + +implement { + name = "pagestaterealpageorder", + actions = { realpageorder, context }, + arguments = { "string", "integer" } +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-dat.mkiv b/Master/texmf-dist/tex/context/base/mkiv/core-dat.mkiv index 3bb923af424..9f4344b99d4 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-dat.mkiv +++ b/Master/texmf-dist/tex/context/base/mkiv/core-dat.mkiv @@ -73,9 +73,18 @@ {\clf_datasetvariable{#1}{#2}{#3}} \installcorenamespace{pagestate} +\installcorenamespace{pagestatecounter} \installcommandhandler \??pagestate {pagestate} \??pagestate +\def\syst_pagestates_allocate + {\expandafter\newcount\csname\??pagestatecounter\currentpagestate\endcsname + \expandafter\let\expandafter\c_syst_pagestate\csname\??pagestatecounter\currentpagestate\endcsname} + +\appendtoks + \syst_pagestates_allocate +\to \everydefinepagestate + \setuppagestate [\c!delay=\v!yes] @@ -85,17 +94,31 @@ \def\syst_pagestates_set[#1][#2]% {\begingroup \edef\currentpagestate{#1}% + \ifcsname\??pagestatecounter\currentpagestate\endcsname + \let\c_syst_pagestate\lastnamedcs + \else + \syst_pagestates_allocate + \fi + \global\advance\c_syst_pagestate\plusone + \scratchcounter\lastnamedcs \clf_setpagestate name {\currentpagestate}% - tag {#2}% + tag {\ifsecondargument#2\else\number\c_syst_pagestate\fi}% delay {\pagestateparameter\c!delay}% \relax \endgroup} -\def\pagestaterealpage#1#2% - {\clf_pagestaterealpage{#1}{#2}} +\unexpanded\def\autosetpagestate#1% + {\secondargumentfalse\syst_pagestates_set[#1]} + +\def\autopagestatenumber#1{\begincsname\??pagestatecounter#1\endcsname} + +\def\pagestaterealpage #1#2{\clf_pagestaterealpage {#1}{#2}} +\def\setpagestaterealpageno#1#2{\clf_setpagestaterealpageno{#1}{#2}} +\def\pagestaterealpageorder#1#2{\clf_pagestaterealpageorder{#1}#2\relax} -\def\setpagestaterealpageno#1#2% - {\clf_setpagestaterealpageno{#1}{#2}} +\def\autopagestaterealpage #1{\clf_pagestaterealpage {#1}{\number\autopagestatenumber{#1}}} +\def\setautopagestaterealpageno#1{\clf_setpagestaterealpageno{#1}{\number\autopagestatenumber{#1}}} +\def\autopagestaterealpageorder#1{\clf_pagestaterealpageorder{#1}\numexpr\autopagestatenumber{#1}\relax} \protect diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-def.mkiv b/Master/texmf-dist/tex/context/base/mkiv/core-def.mkiv index 9dbb16f5cab..95f7f2577d0 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-def.mkiv +++ b/Master/texmf-dist/tex/context/base/mkiv/core-def.mkiv @@ -39,7 +39,7 @@ % \flushcommentanchors \flushnotes \synchronizenotes - \OTRSETshowstatus + % \OTRSETshowstatus \registerparoptions % \flushsyncpositions \flushpostponednodedata diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-env.lua b/Master/texmf-dist/tex/context/base/mkiv/core-env.lua index 0ef37a6d6b2..50759dd1941 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-env.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/core-env.lua @@ -26,6 +26,7 @@ local setmetatablenewindex = table.setmetatablenewindex local setmetatablecall = table.setmetatablecall local createtoken = token.create +local isdefined = tokens.isdefined texmodes = allocate { } tex.modes = texmodes texsystemmodes = allocate { } tex.systemmodes = texsystemmodes @@ -40,18 +41,27 @@ local systemmodes = { } -- we could use the built-in tex.is[count|dimen|skip|toks] here but caching -- at the lua end is not that bad (and we need more anyway) --- undefined: mode == 0 or cmdname = "undefined_cs" - -local cache = setmetatableindex(function(t,k) - local v = createtoken(k) - t[k] = v - return v -end) +local cache = tokens.cache -- we can have a modes cache too -local iftrue = cache["iftrue"].mode -local undefined = cache["*undefined*crap*"].mode -- is this ok? +local iftrue = cache["iftrue"].mode + +local dimencode = cache["scratchdimen"] .command +local countcode = cache["scratchcounter"] .command +local tokencode = cache["scratchtoken"] .command +local skipcode = cache["scratchskip"] .command +local muskipcode = cache["scratchmuskip"] .command +----- attributecode = cache["scratchattribute"].command + +local types = { + [dimencode] = "dimen", + [countcode] = "count", + [tokencode] = "token", + [skipcode] = "skip", + [muskipcode] = "muskip", + -- [attributecode] = "attribute", +} setmetatableindex(texmodes, function(t,k) local m = modes[k] @@ -59,16 +69,17 @@ setmetatableindex(texmodes, function(t,k) return m() elseif k then local n = "mode>" .. k - if cache[n].mode == 0 then - return false - else + if isdefined(n) then rawset(modes,k, function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented + else + return false end else return false end end) + setmetatablenewindex(texmodes, function(t,k) report_mode("you cannot set the %s named %a this way","mode",k) end) @@ -79,11 +90,11 @@ setmetatableindex(texsystemmodes, function(t,k) return m() else local n = "mode>*" .. k - if cache[n].mode == 0 then - return false - else + if isdefined(n) then rawset(systemmodes,k,function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented + else + return false end end end) @@ -112,31 +123,7 @@ setmetatablenewindex(texifs, function(t,k) -- just ignore end) -setmetatableindex(texisdefined, function(t,k) - return k and cache[k].mode ~= 0 -end) -setmetatablecall(texisdefined, function(t,k) - return k and cache[k].mode ~= 0 -end) -setmetatablenewindex(texisdefined, function(t,k) - -- just ignore -end) - -local dimencode = cache["scratchdimen"] .command -local countcode = cache["scratchcounter"] .command -local tokencode = cache["scratchtoken"] .command -local skipcode = cache["scratchskip"] .command -local muskipcode = cache["scratchmuskip"] .command ----- attributecode = cache["scratchattribute"].command - -local types = { - [dimencode] = "dimen", - [countcode] = "count", - [tokencode] = "token", - [skipcode] = "skip", - [muskipcode] = "muskip", - -- [attributecode] = "attribute", -} +tex.isdefined = isdefined function tex.isdimen(name) local hit = cache[name] diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-env.mkiv b/Master/texmf-dist/tex/context/base/mkiv/core-env.mkiv index c93350db04f..758ee126d1a 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-env.mkiv +++ b/Master/texmf-dist/tex/context/base/mkiv/core-env.mkiv @@ -68,6 +68,14 @@ {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi \lastnamedcs\disabledmode} +\unexpanded\def\globalsetmode#1% + {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi + \global\lastnamedcs\enabledmode} + +\unexpanded\def\globalresetmode#1% + {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi + \global\lastnamedcs\disabledmode} + \unexpanded\def\newsystemmode#1% {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi} @@ -79,6 +87,14 @@ {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi \lastnamedcs\disabledmode} +\unexpanded\def\globalsetsystemmode#1% + {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi + \global\lastnamedcs\enabledmode} + +\unexpanded\def\globalresetsystemmode#1% + {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi + \global\lastnamedcs\disabledmode} + % \def\dosetsystemmode#1% % {\csname\??mode\systemmodeprefix#1\endcsname\enabledmode} % @@ -87,16 +103,18 @@ % demo: trialtypesetting is a systemmode as well as an if -\newsystemmode{trialtypesetting} % the name of \@@trialtypesetting might change (also at the lua end) +\newsystemmode{trialtypesetting} -\expandafter\let\expandafter\@@trialtypesetting\csname\??mode\systemmodeprefix trialtypesetting\endcsname % private ! +\expandafter\let\csname\??mode\systemmodeprefix trialtypesetting\endcsname\trialtypesettingstate \appendtoks - \@@trialtypesetting\enabledmode + \trialtypesettingstate\enabledmode + \luacopyinputnodes\plusone \to \everysettrialtypesetting \appendtoks - \@@trialtypesetting\disabledmode + \trialtypesettingstate\disabledmode + \luacopyinputnodes\zerocount \to \everyresettrialtypesetting % user ones @@ -661,6 +679,24 @@ \dodoglobal\undefinevalue{\??setup:#1}% \fi} +% \unexpanded\def\resetsetups[#1]% see x-fo for usage +% {\dodoglobal\expandafter\let\csname\??setup +% \ifgridsnapping\ifcsname\??setup\v!grid:#1\endcsname\v!grid\fi +% :#1\endcsname\undefined} + +\unexpanded\def\copysetups + {\dodoubleargument\syst_setups_copy} + +% \def\syst_setups_copy[#1][#2]% +% {\ifcsname\??setup:#2\endcsname +% \expandafter\let\csname\??setup:#1\expandafter\endcsname\csname\??setup:#2\endcsname +% \fi} + +\def\syst_setups_copy[#1][#2]% + {\ifcsname\??setup:#2\endcsname + \expandafter\let\csname\??setup:#1\expandafter\endcsname\lastnamedcs + \fi} + \unexpanded\def\showsetupsdefinition[#1]% {\showvalue{\??setup:#1}} % temp hack for debugging @@ -777,7 +813,7 @@ %{\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}% {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}% \ifx\m_syst_string_one\empty - \expandafter\firstoffourarguments + \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-lmt.lua b/Master/texmf-dist/tex/context/base/mkiv/core-lmt.lua new file mode 100644 index 00000000000..700ce47211e --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/core-lmt.lua @@ -0,0 +1,34 @@ +if not modules then modules = { } end modules ['core-lmt'] = { + version = 1.001, + comment = "companion to core-lmt.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local implement = interfaces.implement +local scankeyword = tokens.scanners.keyword + +local settextdir = tex.settextdir +local setlinedir = tex.setlinedir +local setpardir = tex.setpardir +local setboxdir = tex.setboxdir + +local function scandir(what) + if scankeyword("tlt") then + what(0) + elseif scankeyword("trt") then + what(1) + -- elseif scankeyword("rtt") then + -- what(2) + -- elseif scankeyword("ltl") then + -- what(3) + else + what(0) + end +end + +implement { name = "textdir", public = true, protected = true, actions = function() scandir(settextdir) end } +implement { name = "linedir", public = true, protected = true, actions = function() scandir(setlinedir) end } +implement { name = "pardir", public = true, protected = true, actions = function() scandir(setpardir) end } +implement { name = "boxdir", public = true, protected = true, actions = function() scandir(setboxdir) end } diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-lmt.mkiv b/Master/texmf-dist/tex/context/base/mkiv/core-lmt.mkiv new file mode 100644 index 00000000000..eda66796918 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/core-lmt.mkiv @@ -0,0 +1,32 @@ +%D \module +%D [ file=core-lmt, +%D version=2010.08.2, +%D title=\CONTEXT\ System Macros, +%D subtitle=Primitives, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\ifcase\contextlmtxmode\expandafter\endinput\fi + +\writestatus{loading}{ConTeXt System Macros / Primitives} + +\ifdefined\textdir \else + \registerctxluafile{core-lmt}{} +\fi + +\unprotect + +% nothing yet + +\protect \endinput + +% \starttext +% abc{\textdir TRTdef}ghi +% abc{\textdir trtdef}ghi +% \boxdirection0=1 +% \stoptext diff --git a/Master/texmf-dist/tex/context/base/mkiv/core-sys.lua b/Master/texmf-dist/tex/context/base/mkiv/core-sys.lua index 26229235b44..4078ab8a8a9 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/core-sys.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/core-sys.lua @@ -73,13 +73,13 @@ implement { name = "outputfilename", actions = function() context(environme statistics.register("result saved in file", function() -- suffix will be fetched from backend local outputfilename = environment.outputfilename or environment.jobname or tex.jobname or "Beware, the boundingbox is passed as reference so we may not overwrite it
in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
@@ -407,7 +426,10 @@ function constructors.scale(tfmdata,specification)
targetparameters.forcedsize = forcedsize -- context specific
targetparameters.extrafactor = extrafactor -- context specific
--
+ local addtounicode = constructors.addtounicode
+ --
local tounicode = fonts.mappings.tounicode
+ local unknowncode = tounicode(0xFFFD)
--
local defaultwidth = resources.defaultwidth or 0
local defaultheight = resources.defaultheight or 0
@@ -455,7 +477,8 @@ function constructors.scale(tfmdata,specification)
local psname = properties.psname or tfmdata.psname
local name = properties.name or tfmdata.name
--
- -- the psname used in pdf file as well as for selecting subfont in ttc
+ -- The psname used in pdf file as well as for selecting subfont in ttc although
+ -- we don't need that subfont look up here (mapfile stuff).
--
local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename))
--
@@ -477,20 +500,28 @@ function constructors.scale(tfmdata,specification)
target.shrink = expansion.shrink
target.step = expansion.step
end
+ -- slanting
+ local slantfactor = parameters.slantfactor or 0
+ if slantfactor ~= 0 then
+ target.slant = slantfactor * 1000
+ else
+ target.slant = 0
+ end
-- widening
local extendfactor = parameters.extendfactor or 0
if extendfactor ~= 0 and extendfactor ~= 1 then
hdelta = hdelta * extendfactor
- target.extend = extendfactor * 1000 -- extent ?
+ target.extend = extendfactor * 1000
else
target.extend = 1000 -- extent ?
end
- -- slanting
- local slantfactor = parameters.slantfactor or 0
- if slantfactor ~= 0 then
- target.slant = slantfactor * 1000
+ -- squeezing
+ local squeezefactor = parameters.squeezefactor or 0
+ if squeezefactor ~= 0 and squeezefactor ~= 1 then
+ vdelta = vdelta * squeezefactor
+ target.squeeze = squeezefactor * 1000
else
- target.slant = 0
+ target.squeeze = 1000 -- extent ?
end
-- effects
local mode = parameters.mode or 0
@@ -499,7 +530,7 @@ function constructors.scale(tfmdata,specification)
end
local width = parameters.width or 0
if width ~= 0 then
- target.width = width
+ target.width = width * delta * 1000 / 655360
end
--
targetparameters.factor = delta
@@ -565,6 +596,7 @@ function constructors.scale(tfmdata,specification)
targetparameters.descender = delta * descender
end
--
+-- inspect(targetparameters)
constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual
--
local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0
@@ -708,11 +740,19 @@ function constructors.scale(tfmdata,specification)
end
end
local isunicode = description.unicode
- if isunicode then
- chr.unicode = isunicode
- chr.tounicode = tounicode(isunicode)
- -- in luatex > 0.85 we can do this:
- -- chr.tounicode = isunicode
+ if addtounicode then
+ if isunicode then
+ chr.unicode = isunicode
+ chr.tounicode = tounicode(isunicode)
+ -- in luatex > 0.85 we can do this:
+ -- chr.tounicode = isunicode
+ else
+ chr.tounicode = unknowncode
+ end
+ else
+ if isunicode then
+ chr.unicode = isunicode
+ end
end
if hasquality then
-- we could move these calculations elsewhere (saves calculations)
@@ -742,12 +782,15 @@ function constructors.scale(tfmdata,specification)
local t = { }
for i=1,#vv do
local vvi = vv[i]
- t[i] = {
- ["start"] = (vvi["start"] or 0)*vdelta,
- ["end"] = (vvi["end"] or 0)*vdelta,
- ["advance"] = (vvi["advance"] or 0)*vdelta,
- ["extender"] = vvi["extender"],
- ["glyph"] = vvi["glyph"],
+ local s = vvi["start"] or 0
+ local e = vvi["end"] or 0
+ local a = vvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * vdelta,
+ ["end"] = e == 0 and 0 or e * vdelta,
+ ["advance"] = a == 0 and 0 or a * vdelta,
+ ["extender"] = vvi["extender"],
+ ["glyph"] = vvi["glyph"],
}
end
chr.vert_variants = t
@@ -757,12 +800,15 @@ function constructors.scale(tfmdata,specification)
local t = { }
for i=1,#hv do
local hvi = hv[i]
- t[i] = {
- ["start"] = (hvi["start"] or 0)*hdelta,
- ["end"] = (hvi["end"] or 0)*hdelta,
- ["advance"] = (hvi["advance"] or 0)*hdelta,
- ["extender"] = hvi["extender"],
- ["glyph"] = hvi["glyph"],
+ local s = hvi["start"] or 0
+ local e = hvi["end"] or 0
+ local a = hvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * hdelta,
+ ["end"] = e == 0 and 0 or e * hdelta,
+ ["advance"] = a == 0 and 0 or a * hdelta,
+ ["extender"] = hvi["extender"],
+ ["glyph"] = hvi["glyph"],
}
end
chr.horiz_variants = t
@@ -781,7 +827,10 @@ function constructors.scale(tfmdata,specification)
if stackmath then
local mk = character.mathkerns
if mk then
- local tr, tl, br, bl = mk.topright, mk.topleft, mk.bottomright, mk.bottomleft
+ local tr = mk.topright
+ local tl = mk.topleft
+ local br = mk.bottomright
+ local bl = mk.bottomleft
chr.mathkern = { -- singular -> should be patched in luatex !
top_right = tr and mathkerns(tr,vdelta) or nil,
top_left = tl and mathkerns(tl,vdelta) or nil,
@@ -876,7 +925,7 @@ function constructors.scale(tfmdata,specification)
else
chr.commands = vc
end
- chr.index = nil
+ -- chr.index = nil
end
end
targetcharacters[unicode] = chr
@@ -886,15 +935,14 @@ function constructors.scale(tfmdata,specification)
--
constructors.aftercopyingcharacters(target,tfmdata)
--
- constructors.trytosharefont(target,tfmdata)
+ constructors.trytosharefont(target,tfmdata)
--
-- catch inconsistencies
--
local vfonts = target.fonts
--- if isvirtual then
-if isvirtual or target.type == "virtual" or properties.virtualized then
+ if isvirtual or target.type == "virtual" or properties.virtualized then
properties.virtualized = true
-target.type = "virtual"
+ target.type = "virtual"
if not vfonts or #vfonts == 0 then
target.fonts = { { id = 0 } }
end
@@ -947,12 +995,16 @@ function constructors.finalize(tfmdata)
parameters.width = 0
end
--
+ if not parameters.slantfactor then
+ parameters.slantfactor = tfmdata.slant or 0
+ end
+ --
if not parameters.extendfactor then
parameters.extendfactor = tfmdata.extend or 0
end
--
- if not parameters.slantfactor then
- parameters.slantfactor = tfmdata.slant or 0
+ if not parameters.squeezefactor then
+ parameters.squeezefactor = tfmdata.squeeze or 0
end
--
local designsize = parameters.designsize
@@ -988,24 +1040,22 @@ function constructors.finalize(tfmdata)
properties.virtualized = tfmdata.type == "virtual"
end
--
- if not tfmdata.properties then
- tfmdata.properties = {
- fontname = tfmdata.fontname,
- filename = tfmdata.filename,
- fullname = tfmdata.fullname,
- name = tfmdata.name,
- psname = tfmdata.psname,
- --
- encodingbytes = tfmdata.encodingbytes or 1,
- embedding = tfmdata.embedding or "subset",
- tounicode = tfmdata.tounicode or 1,
- cidinfo = tfmdata.cidinfo or nil,
- format = tfmdata.format or "type1",
- direction = tfmdata.direction or 0,
- writingmode = tfmdata.writingmode or "horizontal",
- identity = tfmdata.identity or "horizontal",
- }
- end
+ properties.fontname = tfmdata.fontname
+ properties.filename = tfmdata.filename
+ properties.fullname = tfmdata.fullname
+ properties.name = tfmdata.name
+ properties.psname = tfmdata.psname
+ --
+ properties.encodingbytes = tfmdata.encodingbytes or 1
+ properties.embedding = tfmdata.embedding or "subset"
+ properties.tounicode = tfmdata.tounicode or 1
+ properties.cidinfo = tfmdata.cidinfo or nil
+ properties.format = tfmdata.format or "type1"
+ properties.direction = tfmdata.direction or 0
+ properties.writingmode = tfmdata.writingmode or "horizontal"
+ properties.identity = tfmdata.identity or "horizontal"
+ properties.usedbitmap = tfmdata.usedbitmap
+ --
if not tfmdata.resources then
tfmdata.resources = { }
end
@@ -1043,8 +1093,9 @@ function constructors.finalize(tfmdata)
tfmdata.stretch = nil
tfmdata.shrink = nil
tfmdata.step = nil
- tfmdata.extend = nil
tfmdata.slant = nil
+ tfmdata.extend = nil
+ tfmdata.squeeze = nil
tfmdata.mode = nil
tfmdata.width = nil
tfmdata.units = nil
@@ -1097,7 +1148,18 @@ hashmethods.normal = function(list)
-- no need to add to hash (maybe we need a skip list)
else
n = n + 1
- s[n] = k .. '=' .. tostring(v)
+ if type(v) == "table" then
+ -- table.sequenced
+ local t = { }
+ local m = 0
+ for k, v in next, v do
+ m = m + 1
+ t[m] = k .. '=' .. tostring(v)
+ end
+ s[n] = k .. '={' .. concat(t,",") .. "}"
+ else
+ s[n] = k .. '=' .. tostring(v)
+ end
end
end
if n > 0 then
@@ -1115,7 +1177,9 @@ loose our testcases for
When we implement functions that deal with features, most of them -will depend of the font format. Here we define the few that are kind -of neutral.
---ldx]]-- - -local handlers = fonts.handlers -local hashes = fonts.hashes -local otf = handlers.otf -local afm = handlers.afm - -local registerotffeature = otf.features.register -local registerafmfeature = afm.features.register - -local fontdata = hashes.identifiers -local fontproperties = hashes.properties - -local constructors = fonts.constructors -local getprivate = constructors.getprivate - -local allocate = utilities.storage.allocate -local settings_to_array = utilities.parsers.settings_to_array -local settings_to_hash = utilities.parsers.settings_to_hash -local getparameters = utilities.parsers.getparameters -local gettexdimen = tex.getdimen -local family_font = node.family_font - -local setmetatableindex = table.setmetatableindex - -local implement = interfaces.implement -local variables = interfaces.variables - - -local v_background = variables.background -local v_frame = variables.frame -local v_empty = variables.empty -local v_none = variables.none - --- -- -- -- -- -- --- shared --- -- -- -- -- -- - -local function get_class_and_vector(tfmdata,value,where) -- "expansions" - local g_where = tfmdata.goodies and tfmdata.goodies[where] - local f_where = fonts[where] - local g_classes = g_where and g_where.classes - local f_classes = f_where and f_where.classes - local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) - if class then - local class_vector = class.vector - local g_vectors = g_where and g_where.vectors - local f_vectors = f_where and f_where.vectors - local vector = (g_vectors and g_vectors[class_vector]) or (f_vectors and f_vectors[class_vector]) - return class, vector - end -end - --- -- -- -- -- -- --- expansion (hz) --- -- -- -- -- -- - -local expansions = fonts.expansions or allocate() - -fonts.expansions = expansions - -local classes = expansions.classes or allocate() -local vectors = expansions.vectors or allocate() - -expansions.classes = classes -expansions.vectors = vectors - --- beware, pdftex itself uses percentages * 10 --- --- todo: get rid of byte() here - -classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } - -classes['quality'] = { - stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1 -} - -vectors['default'] = { - [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, - [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, - [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, - [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, - [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, - [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, - [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, - [byte('w')] = 0.7, [byte('z')] = 0.7, - [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, -} - -vectors['quality'] = vectors['default'] -- metatable ? - -local function initializeexpansion(tfmdata,value) - if value then - local class, vector = get_class_and_vector(tfmdata,value,"expansions") - if class then - if vector then - local stretch = class.stretch or 0 - local shrink = class.shrink or 0 - local step = class.step or 0 - local factor = class.factor or 1 - if trace_expansion then - report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", - value,class.vector,factor,stretch,shrink,step) - end - tfmdata.parameters.expansion = { - stretch = 10 * stretch, - shrink = 10 * shrink, - step = 10 * step, - factor = factor, - } - local data = characters and characters.data - for i, chr in next, tfmdata.characters do - local v = vector[i] - if data and not v then -- we could move the data test outside (needed for plain) - local d = data[i] - if d then - local s = d.shcode - if not s then - -- sorry - elseif type(s) == "table" then - v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 - else - v = vector[s] or 0 - end - end - end - if v and v ~= 0 then - chr.expansion_factor = v*factor - else -- can be option - chr.expansion_factor = factor - end - end - elseif trace_expansion then - report_expansions("unknown vector %a in class %a",class.vector,value) - end - elseif trace_expansion then - report_expansions("unknown class %a",value) - end - end -end - -local expansion_specification = { - name = "expansion", - description = "apply hz optimization", - initializers = { - base = initializeexpansion, - node = initializeexpansion, - } -} - -registerotffeature(expansion_specification) -registerafmfeature(expansion_specification) - -fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) - -implement { - name = "setupfontexpansion", - arguments = "2 strings", - actions = function(class,settings) getparameters(classes,class,'preset',settings) end -} - --- -- -- -- -- -- --- protrusion --- -- -- -- -- -- - -fonts.protrusions = allocate() -local protrusions = fonts.protrusions - -protrusions.classes = allocate() -protrusions.vectors = allocate() - -local classes = protrusions.classes -local vectors = protrusions.vectors - --- the values need to be revisioned - -classes.preset = { factor = 1, left = 1, right = 1 } - -classes['pure'] = { - vector = 'pure', factor = 1 -} -classes['punctuation'] = { - vector = 'punctuation', factor = 1 -} -classes['alpha'] = { - vector = 'alpha', factor = 1 -} -classes['quality'] = { - vector = 'quality', factor = 1 -} - -vectors['pure'] = { - - [0x002C] = { 0, 1 }, -- comma - [0x002E] = { 0, 1 }, -- period - [0x003A] = { 0, 1 }, -- colon - [0x003B] = { 0, 1 }, -- semicolon - [0x002D] = { 0, 1 }, -- hyphen - [0x00AD] = { 0, 1 }, -- also hyphen - [0x2013] = { 0, 0.50 }, -- endash - [0x2014] = { 0, 0.33 }, -- emdash - [0x3001] = { 0, 1 }, -- ideographic comma 、 - [0x3002] = { 0, 1 }, -- ideographic full stop 。 - [0x060C] = { 0, 1 }, -- arabic comma ، - [0x061B] = { 0, 1 }, -- arabic semicolon ؛ - [0x06D4] = { 0, 1 }, -- arabic full stop ۔ - -} - -vectors['punctuation'] = { - - [0x003F] = { 0, 0.20 }, -- ? - [0x00BF] = { 0, 0.20 }, -- ¿ - [0x0021] = { 0, 0.20 }, -- ! - [0x00A1] = { 0, 0.20 }, -- ¡ - [0x0028] = { 0.05, 0 }, -- ( - [0x0029] = { 0, 0.05 }, -- ) - [0x005B] = { 0.05, 0 }, -- [ - [0x005D] = { 0, 0.05 }, -- ] - [0x002C] = { 0, 0.70 }, -- comma - [0x002E] = { 0, 0.70 }, -- period - [0x003A] = { 0, 0.50 }, -- colon - [0x003B] = { 0, 0.50 }, -- semicolon - [0x002D] = { 0, 0.70 }, -- hyphen - [0x00AD] = { 0, 0.70 }, -- also hyphen - [0x2013] = { 0, 0.30 }, -- endash - [0x2014] = { 0, 0.20 }, -- emdash - [0x060C] = { 0, 0.70 }, -- arabic comma - [0x061B] = { 0, 0.50 }, -- arabic semicolon - [0x06D4] = { 0, 0.70 }, -- arabic full stop - [0x061F] = { 0, 0.20 }, -- ؟ - - -- todo: left and right quotes: .5 double, .7 single - - [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ - [0x203A] = { 0.70, 0.70 }, -- right single guillemet › - [0x00AB] = { 0.50, 0.50 }, -- left guillemet « - [0x00BB] = { 0.50, 0.50 }, -- right guillemet » - - [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ - [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ - [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , - [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ - [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ - [0x201D] = { 0, 0.50 }, -- right double quotation mark ” - [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ - [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ - -} - -vectors['alpha'] = { - - [byte("A")] = { .05, .05 }, - [byte("F")] = { 0, .05 }, - [byte("J")] = { .05, 0 }, - [byte("K")] = { 0, .05 }, - [byte("L")] = { 0, .05 }, - [byte("T")] = { .05, .05 }, - [byte("V")] = { .05, .05 }, - [byte("W")] = { .05, .05 }, - [byte("X")] = { .05, .05 }, - [byte("Y")] = { .05, .05 }, - - [byte("k")] = { 0, .05 }, - [byte("r")] = { 0, .05 }, - [byte("t")] = { 0, .05 }, - [byte("v")] = { .05, .05 }, - [byte("w")] = { .05, .05 }, - [byte("x")] = { .05, .05 }, - [byte("y")] = { .05, .05 }, - -} - -vectors['quality'] = table.merged( - vectors['punctuation'], - vectors['alpha'] -) - --- As this is experimental code, users should not depend on it. The implications are still --- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the --- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The --- double trick should not be needed it proper hanging punctuation is used in which case --- values < 1 can be used. --- --- preferred (in context, usine vectors): --- --- \definefontfeature[whatever][default][mode=node,protrusion=quality] --- --- using lfbd and rtbd, with possibibility to enable only one side : --- --- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] --- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] --- --- idem, using multiplier --- --- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] --- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] --- --- idem, using named feature file (less frozen): --- --- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] - -classes['double'] = { -- for testing opbd - factor = 2, left = 1, right = 1, -} - -local function map_opbd_onto_protrusion(tfmdata,value,opbd) - local characters = tfmdata.characters - local descriptions = tfmdata.descriptions - local properties = tfmdata.properties - local resources = tfmdata.resources - local rawdata = tfmdata.shared.rawdata - local lookuphash = rawdata.lookuphash - local lookuptags = resources.lookuptags - local script = properties.script - local language = properties.language - local done, factor, left, right = false, 1, 1, 1 - local class = classes[value] - if class then - factor = class.factor or 1 - left = class.left or 1 - right = class.right or 1 - else - factor = tonumber(value) or 1 - end - if opbd ~= "right" then - local validlookups, lookuplist = otf.collectlookups(rawdata,"lfbd",script,language) - if validlookups then - for i=1,#lookuplist do - local lookup = lookuplist[i] - local steps = lookup.steps - if steps then - if trace_protrusion then - report_protrusions("setting left using lfbd") - end - for i=1,#steps do - local step = steps[i] - local coverage = step.coverage - if coverage then - for k, v in next, coverage do - -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same - local p = - (v[1] / 1000) * factor * left - characters[k].left_protruding = p - if trace_protrusion then - report_protrusions("lfbd -> %C -> %p",k,p) - end - end - end - end - done = true - end - end - end - end - if opbd ~= "left" then - local validlookups, lookuplist = otf.collectlookups(rawdata,"rtbd",script,language) - if validlookups then - for i=1,#lookuplist do - local lookup = lookuplist[i] - local steps = lookup.steps - if steps then - if trace_protrusion then - report_protrusions("setting right using rtbd") - end - for i=1,#steps do - local step = steps[i] - local coverage = step.coverage - if coverage then - for k, v in next, coverage do - -- local p = v[3] / descriptions[k].width -- or 3 - local p = (v[1] / 1000) * factor * right - characters[k].right_protruding = p - if trace_protrusion then - report_protrusions("rtbd -> %C -> %p",k,p) - end - end - end - end - end - done = true - end - end - end -end - --- The opbd test is just there because it was discussed on the context development list. However, --- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported --- till we have a proper test font. - -local function initializeprotrusion(tfmdata,value) - if value then - local opbd = tfmdata.shared.features.opbd - if opbd then - -- possible values: left right both yes no (experimental) - map_opbd_onto_protrusion(tfmdata,value,opbd) - else - local class, vector = get_class_and_vector(tfmdata,value,"protrusions") - if class then - if vector then - local factor = class.factor or 1 - local left = class.left or 1 - local right = class.right or 1 - if trace_protrusion then - report_protrusions("setting class %a, vector %a, factor %a, left %a, right %a", - value,class.vector,factor,left,right) - end - local data = characters.data - local emwidth = tfmdata.parameters.quad - tfmdata.parameters.protrusion = { - factor = factor, - left = left, - right = right, - } - for i, chr in next, tfmdata.characters do - local v, pl, pr = vector[i], nil, nil - if v then - pl, pr = v[1], v[2] - else - local d = data[i] - if d then - local s = d.shcode - if not s then - -- sorry - elseif type(s) == "table" then - local vl, vr = vector[s[1]], vector[s[#s]] - if vl then pl = vl[1] end - if vr then pr = vr[2] end - else - v = vector[s] - if v then - pl, pr = v[1], v[2] - end - end - end - end - if pl and pl ~= 0 then - chr.left_protruding = left *pl*factor - end - if pr and pr ~= 0 then - chr.right_protruding = right*pr*factor - end - end - elseif trace_protrusion then - report_protrusions("unknown vector %a in class %a",class.vector,value) - end - elseif trace_protrusion then - report_protrusions("unknown class %a",value) - end - end - end -end - -local protrusion_specification = { - name = "protrusion", - description = "l/r margin character protrusion", - initializers = { - base = initializeprotrusion, - node = initializeprotrusion, - } -} - -registerotffeature(protrusion_specification) -registerafmfeature(protrusion_specification) - -fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) - -implement { - name = "setupfontprotrusion", - arguments = "2 strings", - actions = function(class,settings) getparameters(classes,class,'preset',settings) end -} - --- -- -- - -local function initializenostackmath(tfmdata,value) - tfmdata.properties.nostackmath = value and true -end - -registerotffeature { - name = "nostackmath", - description = "disable math stacking mechanism", - initializers = { - base = initializenostackmath, - node = initializenostackmath, - } -} - -local function initializerealdimensions(tfmdata,value) - tfmdata.properties.realdimensions = value and true -end - -registerotffeature { - name = "realdimensions", - description = "accept negative dimenions", - initializers = { - base = initializerealdimensions, - node = initializerealdimensions, - } -} - -local function initializeitlc(tfmdata,value) -- hm, always value - if value then - -- the magic 40 and it formula come from Dohyun Kim but we might need another guess - local parameters = tfmdata.parameters - local italicangle = parameters.italicangle - if italicangle and italicangle ~= 0 then - local properties = tfmdata.properties - local factor = tonumber(value) or 1 - properties.hasitalics = true - properties.autoitalicamount = factor * (parameters.uwidth or 40)/2 - end - end -end - -local italic_specification = { - name = "itlc", - description = "italic correction", - initializers = { - base = initializeitlc, - node = initializeitlc, - } -} - -registerotffeature(italic_specification) -registerafmfeature(italic_specification) - -local function initializetextitalics(tfmdata,value) -- yes no delay - tfmdata.properties.textitalics = toboolean(value) -end - -local textitalics_specification = { - name = "textitalics", - description = "use alternative text italic correction", - initializers = { - base = initializetextitalics, - node = initializetextitalics, - } -} - -registerotffeature(textitalics_specification) -registerafmfeature(textitalics_specification) - --- local function initializemathitalics(tfmdata,value) -- yes no delay --- tfmdata.properties.mathitalics = toboolean(value) --- end --- --- local mathitalics_specification = { --- name = "mathitalics", --- description = "use alternative math italic correction", --- initializers = { --- base = initializemathitalics, --- node = initializemathitalics, --- } --- } - --- registerotffeature(mathitalics_specification) --- registerafmfeature(mathitalics_specification) - --- slanting - -local function initializeslant(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 1 then - value = 1 - elseif value < -1 then - value = -1 - end - tfmdata.parameters.slantfactor = value -end - -local slant_specification = { - name = "slant", - description = "slant glyphs", - initializers = { - base = initializeslant, - node = initializeslant, - } -} - -registerotffeature(slant_specification) -registerafmfeature(slant_specification) - -local function initializeextend(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 10 then - value = 10 - elseif value < -10 then - value = -10 - end - tfmdata.parameters.extendfactor = value -end - -local extend_specification = { - name = "extend", - description = "scale glyphs horizontally", - initializers = { - base = initializeextend, - node = initializeextend, - } -} - -registerotffeature(extend_specification) -registerafmfeature(extend_specification) - --- For Wolfgang Schuster: --- --- \definefontfeature[thisway][default][script=hang,language=zhs,dimensions={2,2,2}] --- \definedfont[file:kozminpr6nregular*thisway] --- --- For the moment we don't mess with the descriptions. - -local function manipulatedimensions(tfmdata,key,value) - if type(value) == "string" and value ~= "" then - local characters = tfmdata.characters - local parameters = tfmdata.parameters - local emwidth = parameters.quad - local exheight = parameters.xheight - local newwidth = false - local newheight = false - local newdepth = false - if value == "strut" then - newheight = gettexdimen("strutht") - newdepth = gettexdimen("strutdp") - elseif value == "mono" then - newwidth = emwidth - else - local spec = settings_to_array(value) - newwidth = tonumber(spec[1]) - newheight = tonumber(spec[2]) - newdepth = tonumber(spec[3]) - if newwidth then newwidth = newwidth * emwidth end - if newheight then newheight = newheight * exheight end - if newdepth then newdepth = newdepth * exheight end - end - if newwidth or newheight or newdepth then - local additions = { } - for unicode, old_c in next, characters do - local oldwidth = old_c.width - local oldheight = old_c.height - local olddepth = old_c.depth - local width = newwidth or oldwidth or 0 - local height = newheight or oldheight or 0 - local depth = newdepth or olddepth or 0 - if oldwidth ~= width or oldheight ~= height or olddepth ~= depth then - local private = getprivate(tfmdata) - local newslot = { "slot", 1, private } -- { "slot", 0, private } - local new_c - local commands = oldwidth ~= width and { - { "right", (width - oldwidth) / 2 }, - newslot, - } or { - newslot, - } - if height > 0 then - if depth > 0 then - new_c = { - width = width, - height = height, - depth = depth, - commands = commands, - } - else - new_c = { - width = width, - height = height, - commands = commands, - } - end - else - if depth > 0 then - new_c = { - width = width, - depth = depth, - commands = commands, - } - else - new_c = { - width = width, - commands = commands, - } - end - end - setmetatableindex(new_c,old_c) - characters[unicode] = new_c - additions[private] = old_c - end - end - for k, v in next, additions do - characters[k] = v - end - -- elseif height > 0 and depth > 0 then - -- for unicode, old_c in next, characters do - -- old_c.height = height - -- old_c.depth = depth - -- end - -- elseif height > 0 then - -- for unicode, old_c in next, characters do - -- old_c.height = height - -- end - -- elseif depth > 0 then - -- for unicode, old_c in next, characters do - -- old_c.depth = depth - -- end - end - end -end - -local dimensions_specification = { - name = "dimensions", - description = "force dimensions", - manipulators = { - base = manipulatedimensions, - node = manipulatedimensions, - } -} - -registerotffeature(dimensions_specification) -registerafmfeature(dimensions_specification) - --------------------------------------------------------------------------------------------------------------- - --- local function fakemonospace(tfmdata) --- local resources = tfmdata.resources --- local gposfeatures = resources.features.gpos --- local characters = tfmdata.characters --- local descriptions = tfmdata.descriptions --- local sequences = resources.sequences --- local coverage = { } --- local units = tfmdata.shared.rawdata.metadata.units --- for k, v in next, characters do --- local w = descriptions[k].width --- local d = units - w --- coverage[k] = { -d/2, 0, units, 0 } --- end --- local f = { dflt = { dflt = true } } --- local s = #sequences + 1 --- local t = { --- features = { fakemono = f }, --- flags = { false, false, false, false }, --- index = s, --- name = "p_s_" .. s, --- nofsteps = 1, --- order = { "fakemono" }, --- skiphash = false, --- type = "gpos_single", --- steps = { --- { --- format = "single", --- coverage = coverage, --- } --- } --- } --- gposfeatures["fakemono"] = f --- sequences[s] = t --- end --- --- fonts.constructors.features.otf.register { --- name = "fakemono", --- description = "fake monospaced", --- initializers = { --- node = fakemonospace, --- }, --- } - --------------------------------------------------------------------------------------------------------------- - --- for zhichu chen (see mailing list archive): we might add a few more variants --- in due time --- --- \definefontfeature[boxed][default][boundingbox=yes] % paleblue --- --- maybe: --- --- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression --- --- local gray = { "pdf", "origin", "/Tr1 gs .75 g" } --- local black = { "pdf", "origin", "/Tr0 gs 0 g" } - - --- boundingbox={yes|background|frame|empty|This is very experimental code!
--ldx]]-- -local trace_combining_visualize = false trackers.register("fonts.composing.visualize", function(v) trace_combining_visualize = v end) -local trace_combining_define = false trackers.register("fonts.composing.define", function(v) trace_combining_define = v end) +local trace_visualize = false trackers.register("fonts.composing.visualize", function(v) trace_visualize = v end) +local trace_define = false trackers.register("fonts.composing.define", function(v) trace_define = v end) -trackers.register("fonts.combining", "fonts.composing.define") -- for old times sake (and manuals) -trackers.register("fonts.combining.all", "fonts.composing.*") -- for old times sake (and manuals) - -local report_combining = logs.reporter("fonts","combining") - -local force_combining = false -- just for demo purposes (see mk) +local report = logs.reporter("fonts","combining") local allocate = utilities.storage.allocate local fonts = fonts local handlers = fonts.handlers local constructors = fonts.constructors +local helpers = fonts.helpers local otf = handlers.otf local afm = handlers.afm local registerotffeature = otf.features.register local registerafmfeature = afm.features.register +local addotffeature = otf.addfeature + local unicodecharacters = characters.data local unicodefallbacks = characters.fallbacks -local vf = handlers.vf -local commands = vf.combiner.commands -local push = vf.predefined.push -local pop = vf.predefined.pop +local vfcommands = helpers.commands +local charcommand = vfcommands.char +local rightcommand = vfcommands.right +local downcommand = vfcommands.down +local upcommand = vfcommands.up +local push = vfcommands.push +local pop = vfcommands.pop -local force_composed = false -local cache = { } -- we could make these weak -local fraction = 0.15 -- 30 units for lucida +local force_combining = false -- just for demo purposes (see mk) +local fraction = 0.15 -- 30 units for lucida -- todo: we also need to update the feature hashes ... i'll do that when i'm in the mood -- and/or when i need it @@ -65,15 +65,15 @@ local function composecharacters(tfmdata) local italicfactor = parameters.italicfactor or 0 local vfspecials = backends.tables.vfspecials --brr local red, green, blue, black - if trace_combining_visualize then + if trace_visualize then red = vfspecials.startcolor("red") green = vfspecials.startcolor("green") blue = vfspecials.startcolor("blue") black = vfspecials.stopcolor end local compose = fonts.goodies.getcompositions(tfmdata) - if compose and trace_combining_visualize then - report_combining("using compose information from goodies file") + if compose and trace_visualize then + report("using compose information from goodies file") end local done = false for i, c in next, unicodecharacters do -- loop over all characters ... not that efficient but a specials hash takes memory @@ -105,31 +105,25 @@ local function composecharacters(tfmdata) acc = unicodefallbacks[acc] charsacc = acc and characters[acc] end - local chr_t = cache[chr] - if not chr_t then - -- chr_t = { "slot", 1, chr } - -- chr_t = { "slot", 0, chr } - chr_t = { "char", chr } - cache[chr] = chr_t - end + local chr_t = charcommand[chr] if charsacc then - if trace_combining_define then - report_combining("composed %C, base %C, accent %C",i,chr,acc) - end - local acc_t = cache[acc] - if not acc_t then - -- acc_t = { "slot", 1, acc } - -- acc_t = { "slot", 0, acc } - acc_t = { "char", acc } - cache[acc] = acc_t + if trace_define then + report("composed %C, base %C, accent %C",i,chr,acc) end + local acc_t = charcommand[acc] local cb = descriptions[chr].boundingbox local ab = descriptions[acc].boundingbox -- todo: adapt height if cb and ab then - local c_llx, c_lly, c_urx, c_ury = scale*cb[1], scale*cb[2], scale*cb[3], scale*cb[4] - local a_llx, a_lly, a_urx, a_ury = scale*ab[1], scale*ab[2], scale*ab[3], scale*ab[4] - local done = false + local c_llx = scale*cb[1] + local c_lly = scale*cb[2] + local c_urx = scale*cb[3] + local c_ury = scale*cb[4] + local a_llx = scale*ab[1] + local a_lly = scale*ab[2] + local a_urx = scale*ab[3] + local a_ury = scale*ab[4] + local done = false if compose then local i_compose = compose[i] local i_anchored = i_compose and i_compose.anchored @@ -148,26 +142,30 @@ local function composecharacters(tfmdata) local ay = a_anchor.y or 0 local dx = cx - ax local dy = cy - ay - if trace_combining_define then - report_combining("building %C from %C and %C",i,chr,acc) - report_combining(" boundingbox:") - report_combining(" chr: %3i %3i %3i %3i",unpack(cb)) - report_combining(" acc: %3i %3i %3i %3i",unpack(ab)) - report_combining(" anchors:") - report_combining(" chr: %3i %3i",cx,cy) - report_combining(" acc: %3i %3i",ax,ay) - report_combining(" delta:") - report_combining(" %s: %3i %3i",i_anchored,dx,dy) + if trace_define then + report("building %C from %C and %C",i,chr,acc) + report(" boundingbox:") + report(" chr: %3i %3i %3i %3i",unpack(cb)) + report(" acc: %3i %3i %3i %3i",unpack(ab)) + report(" anchors:") + report(" chr: %3i %3i",cx,cy) + report(" acc: %3i %3i",ax,ay) + report(" delta:") + report(" %s: %3i %3i",i_anchored,dx,dy) end - if trace_combining_visualize then - t.commands = { push, {"right", scale*dx}, {"down",-scale*dy}, green, acc_t, black, pop, chr_t } - -- t.commands = { - -- push, {"right", scale*cx}, {"down", -scale*cy}, red, {"rule",10000,10000,10000}, pop, - -- push, {"right", scale*ax}, {"down", -scale*ay}, blue, {"rule",10000,10000,10000}, pop, - -- push, {"right", scale*dx}, {"down", -scale*dy}, green, acc_t, black, pop, chr_t - -- } + local right = rightcommand[scale*dx] + local down = upcommand[scale*dy] + if trace_visualize then + t.commands = { + push, right, down, + green, acc_t, black, + pop, chr_t, + } else - t.commands = { push, {"right", scale*dx}, {"down",-scale*dy}, acc_t, pop, chr_t } + t.commands = { + push, right, down, + acc_t, pop, chr_t, + } end done = true end @@ -179,10 +177,17 @@ local function composecharacters(tfmdata) local dx = (c_urx - a_urx - a_llx + c_llx)/2 local dd = (c_urx - c_llx)*italicfactor if a_ury < 0 then - if trace_combining_visualize then - t.commands = { push, {"right", dx-dd}, red, acc_t, black, pop, chr_t } + local right = rightcommand[dx-dd] + if trace_visualize then + t.commands = { + push, right, red, acc_t, + black, pop, chr_t, + } else - t.commands = { push, {"right", dx-dd}, acc_t, pop, chr_t } + t.commands = { + push, right, acc_t, pop, + chr_t, + } end elseif c_ury > a_lly then -- messy test local dy @@ -214,27 +219,46 @@ local function composecharacters(tfmdata) else dy = - deltaxheight + extraxheight end - if trace_combining_visualize then - t.commands = { push, { "right", dx+dd }, { "down", dy }, green, acc_t, black, pop, chr_t } + local right = rightcommand[dx+dd] + local down = downcommand[dy] + if trace_visualize then + t.commands = { + push, right, down, green, + acc_t, black, pop, chr_t, + } else - t.commands = { push, { "right", dx+dd }, { "down", dy }, acc_t, pop, chr_t } + t.commands = { + push, right, down, acc_t, + pop, chr_t, + } end else - if trace_combining_visualize then - t.commands = { push, { "right", dx+dd }, blue, acc_t, black, pop, chr_t } + local right = rightcommand[dx+dd] + if trace_visualize then + t.commands = { + push, right, blue, acc_t, + black, pop, chr_t, + } else - t.commands = { push, { "right", dx+dd }, acc_t, pop, chr_t } + t.commands = { + push, right, acc_t, pop, + chr_t, + } end end end else - t.commands = { chr_t } -- else index mess + t.commands = { + chr_t, -- else index mess + } end else - if trace_combining_define then - report_combining("%C becomes simplified %C",i,chr) + if trace_define then + report("%C becomes simplified %C",i,chr) end - t.commands = { chr_t } -- else index mess + t.commands = { + chr_t, -- else index mess + } end done = true characters[i] = t @@ -254,7 +278,7 @@ local function composecharacters(tfmdata) end end -local compose_specification = { +local specification = { name = "compose", description = "additional composed characters", manipulators = { @@ -263,75 +287,71 @@ local compose_specification = { } } -registerotffeature(compose_specification) -registerafmfeature(compose_specification) +registerotffeature(specification) +registerafmfeature(specification) -vf.helpers.composecharacters = composecharacters +addotffeature { + name = "char-ligatures", + type = "ligature", + data = characters.splits.char, + order = { "char-ligatures" }, + prepend = true, +} --- This installs the builder into the regular virtual font builder, --- which only makes sense as demo. +addotffeature { + name = "compat-ligatures", + type = "ligature", + data = characters.splits.compat, + order = { "compat-ligatures" }, + prepend = true, +} -commands["compose.trace.enable"] = function() - trace_combining_visualize = true -end +registerotffeature { + name = 'char-ligatures', + description = 'unicode char specials to ligatures', +} -commands["compose.trace.disable"] = function() - trace_combining_visualize = false -end +registerotffeature { + name = 'compat-ligatures', + description = 'unicode compat specials to ligatures', +} -commands["compose.force.enable"] = function() - force_combining = true -end +do -commands["compose.force.disable"] = function() - force_combining = false -end + -- This installs the builder into the regular virtual font builder, + -- which only makes sense as demo. -commands["compose.trace.set"] = function(g,v) - if v[2] == nil then - trace_combining_visualize = true - else - trace_combining_visualize = v[2] - end -end - -commands["compose.apply"] = function(g,v) - composecharacters(g) -end + local vf = handlers.vf + local commands = vf.combiner.commands --- vf builder + vf.helpers.composecharacters = composecharacters --- { "pdf", "origin", "q " .. s .. " 0 0 " .. s .. " 0 0 cm" }, --- { "pdf", "origin", "q 1 0 0 1 " .. -w .. " " .. -h .. " cm" }, --- { "pdf", "origin", "/Fm\XX\space Do" }, --- { "pdf", "origin", "Q" }, --- { "pdf", "origin", "Q" }, + commands["compose.trace.enable"] = function() + trace_visualize = true + end --- new and experimental + commands["compose.trace.disable"] = function() + trace_visualize = false + end -local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } -local noflags = { } + commands["compose.force.enable"] = function() + force_combining = true + end -local char_specification = { - type = "ligature", - features = everywhere, - data = characters.splits.char, - order = { "char-ligatures" }, - flags = noflags, - prepend = true, -} + commands["compose.force.disable"] = function() + force_combining = false + end -local compat_specification = { - type = "ligature", - features = everywhere, - data = characters.splits.compat, - order = { "compat-ligatures" }, - flags = noflags, - prepend = true, -} + commands["compose.trace.set"] = function(g,v) + if v[2] == nil then + trace_visualize = true + else + trace_visualize = v[2] + end + end -otf.addfeature("char-ligatures", char_specification) -- xlig (extra) -otf.addfeature("compat-ligatures",compat_specification) -- plig (pseudo) + commands["compose.apply"] = function(g,v) + composecharacters(g) + end -registerotffeature { name = 'char-ligatures', description = 'unicode char specials to ligatures' } -registerotffeature { name = 'compat-ligatures', description = 'unicode compat specials to ligatures' } +end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-fea.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-fea.mkvi index 5f65543ab9e..4a5356090e9 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-fea.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-fea.mkvi @@ -368,11 +368,19 @@ % \doifelsecurrentfonthasfeature{crap}{YES}{NO} % \doifelsecurrentfonthasfeature{kern}{YES}{NO} -\def\doifelsecurrentfonthasfeature#feature% +\def\doifelsecurrentfonthasfeature#feature% expandable {\clf_doifelsecurrentfonthasfeature{#feature}} \let\doifcurrentfonthasfeatureelse\doifelsecurrentfonthasfeature +\def\doifelsefontfeature#feature% expandable + {\clf_doifelsefontfeature{#feature}} + +\let\doiffontfeatureelse\doifelsefontfeature + +\def\doifunknownfontfeature#feature% expandable + {\clf_doifunknownfontfeature{#feature}} + % new: \clf_registerlanguagefeatures diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-fil.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-fil.mkvi index 01fa4a3380e..16ce57f8ad9 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-fil.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-fil.mkvi @@ -42,19 +42,17 @@ % % \setupbodyfont[palatino] -\let\fontclass\empty - \unexpanded\def\startfontclass {\dosingleempty\font_basics_start_font_class} \def\font_basics_start_font_class[#class]% - {\pushmacro\fontclass + {\push_macro_fontclass \doifelse{#class}\v!each {\let\fontclass\empty} {\doifsomething{#class}{\def\fontclass{#class}}}} \unexpanded\def\stopfontclass - {\popmacro\fontclass} + {\pop_macro_fontclass} \def\classfont#class#name{#class#name} % \definefont[whatever][\classfont{xx}{yy} at 10pt] @@ -109,11 +107,14 @@ \let\p_designsize\undefined \expandafter\font_basics_get_font_parameter_yes#specification,]=,} +% todo: check if we can use \edef but then we need to protect \mathsizesuffix .. in fact that +% can be default then: \let\mathsizesuffix\relax .. i need to play with it first + \def\font_basics_get_font_parameter_nop#key=#value,% {\if]#key% \font_basics_get_font_parameter_nop_finish \else - \expandafter\normaldef\csname p_#key\endcsname{#value}% + \expandafter\normaldef\csname p_#key\endcsname{#value}% % no edef as we need to keep \mathsizesuffix \expandafter\font_basics_get_font_parameter_nop \fi} @@ -121,13 +122,13 @@ {\if]#key% \font_basics_get_font_parameter_yes_finish \else - \expandafter\normaldef\csname p_#key\endcsname{#value}% + \expandafter\normaldef\csname p_#key\endcsname{#value}% % no edef as we need to keep \mathsizesuffix \expandafter\font_basics_get_font_parameter_yes \fi} % helpers, some day these will be toks and counts -% \def\fntsetdefname {\global\let\somefontname\defaultfontfile} +% \def\fntsetdefname {\glet\somefontname\defaultfontfile} % \def\fntsetsomename{\gdef\somefontname} % takes argument % \def\fntsetnopsize {\let\somefontsize\empty} % \def\fntsetsomesize{\def\somefontsize} % takes argument @@ -145,10 +146,10 @@ \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\undefined} \def\font_basics_define_font_synonym_yes_nil - {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\undefined} + {\expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\undefined} \def\font_basics_get_font_parameter_nop_finish {\expandafter\let\csname\??fontfile\m_font_name\s!features \endcsname\p_features @@ -157,10 +158,10 @@ \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\p_designsize} \def\font_basics_get_font_parameter_yes_finish - {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\p_features - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\p_fallbacks - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\p_goodies - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\p_designsize} + {\expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\p_features + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\p_fallbacks + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\p_goodies + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\p_designsize} %\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}] % @@ -306,6 +307,8 @@ #2% \fi\fi} +\installmacrostack\fontclass + %D Files or names can have properties and these need to be consulted %D at some point. They can inherit them. diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-gbn.lua b/Master/texmf-dist/tex/context/base/mkiv/font-gbn.lua deleted file mode 100644 index 8f1acac65a5..00000000000 --- a/Master/texmf-dist/tex/context/base/mkiv/font-gbn.lua +++ /dev/null @@ -1,262 +0,0 @@ -if not modules then modules = { } end modules ['font-gbn'] = { - version = 1.001, - comment = "companion to luatex-*.tex", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- generic [base|node] mode handler - -if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() -end - -local next = next - -local fonts = fonts -local nodes = nodes - -local nuts = nodes.nuts -- context abstraction of direct nodes - -local traverse_id = nuts.traverse_id -local flush_node = nuts.flush_node - -local glyph_code = nodes.nodecodes.glyph -local disc_code = nodes.nodecodes.disc - -local tonode = nuts.tonode -local tonut = nuts.tonut - -local getfont = nuts.getfont -local getchar = nuts.getchar -local getid = nuts.getid -local getboth = nuts.getboth -local getprev = nuts.getprev -local getnext = nuts.getnext -local getdisc = nuts.getdisc -local setchar = nuts.setchar -local setlink = nuts.setlink -local setprev = nuts.setprev - --- from now on we apply ligaturing and kerning here because it might interfere with complex --- opentype discretionary handling where the base ligature pass expect some weird extra --- pointers (which then confuse the tail slider that has some checking built in) - -local n_ligaturing = node.ligaturing -local n_kerning = node.kerning - -local ligaturing = nuts.ligaturing -local kerning = nuts.kerning - -local basemodepass = true - -local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning = nil end -local function k_warning() texio.write_nl("warning: node.kerning called directly") k_warning = nil end - -function node.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return n_ligaturing(...) -end - -function node.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return n_kerning(...) -end - -function nodes.handlers.setbasemodepass(v) - basemodepass = v -end - --------- nodes.handlers.nodepass(head) -function nodes.handlers.nodepass(head,groupcode,size,packtype,direction) - local fontdata = fonts.hashes.identifiers - if fontdata then - local nuthead = tonut(head) - local usedfonts = { } - local basefonts = { } - local prevfont = nil - local basefont = nil - local variants = nil - local redundant = nil - local nofused = 0 - for n in traverse_id(glyph_code,nuthead) do - local font = getfont(n) - if font ~= prevfont then - if basefont then - basefont[2] = getprev(n) - end - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] -- - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - nofused = nofused + 1 - elseif basemodepass then - basefont = { n, nil } - basefonts[#basefonts+1] = basefont - end - end - local resources = tfmdata.resources - variants = resources and resources.variants - variants = variants and next(variants) and variants or false - end - else - local tfmdata = fontdata[prevfont] - if tfmdata then - local resources = tfmdata.resources - variants = resources and resources.variants - variants = variants and next(variants) and variants or false - end - end - end - if variants then - local char = getchar(n) - if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then - local hash = variants[char] - if hash then - local p = getprev(n) - if p and getid(p) == glyph_code then - local variant = hash[getchar(p)] - if variant then - setchar(p,variant) - end - end - end - -- per generic user request we always remove selectors - if not redundant then - redundant = { n } - else - redundant[#redundant+1] = n - end - end - end - end - local nofbasefonts = #basefonts - if redundant then - for i=1,#redundant do - local r = redundant[i] - local p, n = getboth(r) - if r == nuthead then - nuthead = n - setprev(n) - else - setlink(p,n) - end - if nofbasefonts > 0 then - for i=1,nofbasefonts do - local bi = basefonts[i] - if r == bi[1] then - bi[1] = n - end - if r == bi[2] then - bi[2] = n - end - end - end - flush_node(r) - end - end - for d in traverse_id(disc_code,nuthead) do - local _, _, r = getdisc(d) - if r then - for n in traverse_id(glyph_code,r) do - local font = getfont(n) - if font ~= prevfont then - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] -- - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - nofused = nofused + 1 - end - end - end - end - end - end - end - end - if next(usedfonts) then - for font, processors in next, usedfonts do - for i=1,#processors do - head = processors[i](head,font,0,direction,nofused) or head - end - end - end - if basemodepass and nofbasefonts > 0 then - for i=1,nofbasefonts do - local range = basefonts[i] - local start = range[1] - local stop = range[2] - if start then - local front = nuthead == start - local prev, next - if stop then - next = getnext(stop) - start, stop = ligaturing(start,stop) - start, stop = kerning(start,stop) - else - prev = getprev(start) - start = ligaturing(start) - start = kerning(start) - end - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - if front and nuthead ~= start then - head = tonode(start) - end - end - end - end - return head, true - else - return head, false - end -end - -function nodes.handlers.basepass(head) - if basemodepass then - head = n_ligaturing(head) - head = n_kerning(head) - end - return head, true -end - -local nodepass = nodes.handlers.nodepass -local basepass = nodes.handlers.basepass -local injectpass = nodes.injections.handler -local protectpass = nodes.handlers.protectglyphs - -function nodes.simple_font_handler(head,groupcode,size,packtype,direction) - if head then - head = nodepass(head,groupcode,size,packtype,direction) - head = injectpass(head) - if not basemodepass then - head = basepass(head) - end - protectpass(head) - return head, true - else - return head, false - end -end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-gds.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-gds.mkvi index 549ede46f6c..05cf087903c 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-gds.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-gds.mkvi @@ -62,7 +62,7 @@ % % \definedfont[husayni*husayni-colored at 36pt] % -% \starttext \pardir TRT \textdir TRT +% \starttext \righttoleft % % \setfontcolorscheme[1] % diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua b/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua index 60a27c043b8..8d1e85145fb 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua @@ -18,48 +18,50 @@ fonts.hashes = hashes -- todo: autoallocate ... just create on the fly .. use constructors.keys (problem: plurals) -local identifiers = hashes.identifiers or allocate() -local characters = hashes.characters or allocate() -- chardata -local descriptions = hashes.descriptions or allocate() -local parameters = hashes.parameters or allocate() -local properties = hashes.properties or allocate() -local resources = hashes.resources or allocate() -local spacings = hashes.spacings or allocate() -local spaces = hashes.spaces or allocate() -local quads = hashes.quads or allocate() -- maybe also spacedata -local xheights = hashes.xheights or allocate() -local csnames = hashes.csnames or allocate() -- namedata -local features = hashes.features or allocate() -local marks = hashes.marks or allocate() -local classes = hashes.classes or allocate() -local italics = hashes.italics or allocate() -local lastmathids = hashes.lastmathids or allocate() -local dynamics = hashes.dynamics or allocate() -local unicodes = hashes.unicodes or allocate() -local originals = hashes.originals or allocate() -local modes = hashes.modes or allocate() -local variants = hashes.variants or allocate() - -hashes.characters = characters -hashes.descriptions = descriptions -hashes.parameters = parameters -hashes.properties = properties -hashes.resources = resources -hashes.spacings = spacings -hashes.spaces = spaces -hashes.quads = quads hashes.emwidths = quads -hashes.xheights = xheights hashes.exheights = xheights -hashes.csnames = csnames -hashes.features = features -hashes.marks = marks -hashes.classes = classes -hashes.italics = italics -hashes.lastmathids = lastmathids -hashes.dynamics = dynamics -hashes.unicodes = unicodes -hashes.originals = originals -hashes.modes = modes -hashes.variants = variants +local identifiers = hashes.identifiers or allocate() +local characters = hashes.characters or allocate() -- chardata +local descriptions = hashes.descriptions or allocate() +local parameters = hashes.parameters or allocate() +local mathparameters = hashes.mathparameters or allocate() +local properties = hashes.properties or allocate() +local resources = hashes.resources or allocate() +local spacings = hashes.spacings or allocate() +local spaces = hashes.spaces or allocate() +local quads = hashes.quads or allocate() -- maybe also spacedata +local xheights = hashes.xheights or allocate() +local csnames = hashes.csnames or allocate() -- namedata +local features = hashes.features or allocate() +local marks = hashes.marks or allocate() +local classes = hashes.classes or allocate() +local italics = hashes.italics or allocate() +local lastmathids = hashes.lastmathids or allocate() +local dynamics = hashes.dynamics or allocate() +local unicodes = hashes.unicodes or allocate() +local originals = hashes.originals or allocate() +local modes = hashes.modes or allocate() +local variants = hashes.variants or allocate() + +hashes.characters = characters +hashes.descriptions = descriptions +hashes.parameters = parameters +hashes.mathparameters = mathparameters +hashes.properties = properties +hashes.resources = resources +hashes.spacings = spacings +hashes.spaces = spaces +hashes.quads = quads hashes.emwidths = quads +hashes.xheights = xheights hashes.exheights = xheights +hashes.csnames = csnames +hashes.features = features +hashes.marks = marks +hashes.classes = classes +hashes.italics = italics +hashes.lastmathids = lastmathids +hashes.dynamics = dynamics +hashes.unicodes = unicodes +hashes.originals = originals +hashes.modes = modes +hashes.variants = variants local nodepool = nodes and nodes.pool local dummyglyph = nodepool and nodepool.register(nodepool.glyph()) @@ -68,7 +70,9 @@ local nulldata = allocate { name = "nullfont", characters = { }, descriptions = { }, - properties = { }, + properties = { + designsize = 786432, + }, parameters = { -- lmromanregular @ 12pt slantperpoint = 0, spacing = { @@ -87,6 +91,7 @@ local nulldata = allocate { x_height = 338952, -- 5 quad = 786432, -- 6 extra_space = 85459, -- 7 + size = 786432, }, } @@ -148,6 +153,16 @@ setmetatableindex(parameters, function(t,k) end end) +setmetatableindex(mathparameters, function(t,k) + if k == true then + return mathparameters[currentfont()] + else + local mathparameters = identifiers[k].mathparameters + t[k] = mathparameters + return mathparameters + end +end) + setmetatableindex(properties, function(t,k) if k == true then return properties[currentfont()] diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-dimensions.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-dimensions.lua new file mode 100644 index 00000000000..a7125625da7 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-dimensions.lua @@ -0,0 +1,115 @@ +if not modules then modules = { } end modules ['font-imp-dimensions'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber + +local fonts = fonts +local utilities = utilities + +local helpers = fonts.helpers +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char +local rightcommand = helpers.commands.right + +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm + +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local settings_to_array = utilities.parsers.settings_to_array +local gettexdimen = tex.getdimen + +-- For Wolfgang Schuster: +-- +-- \definefontfeature[thisway][default][script=hang,language=zhs,dimensions={2,2,2}] +-- \definedfont[file:kozminpr6nregular*thisway] + +local function initialize(tfmdata,key,value) + if type(value) == "string" and value ~= "" then + local characters = tfmdata.characters + local parameters = tfmdata.parameters + local emwidth = parameters.quad + local exheight = parameters.xheight + local newwidth = false + local newheight = false + local newdepth = false + if value == "strut" then + newheight = gettexdimen("strutht") + newdepth = gettexdimen("strutdp") + elseif value == "mono" then + newwidth = emwidth + else + local spec = settings_to_array(value) + newwidth = tonumber(spec[1]) + newheight = tonumber(spec[2]) + newdepth = tonumber(spec[3]) + if newwidth then newwidth = newwidth * emwidth end + if newheight then newheight = newheight * exheight end + if newdepth then newdepth = newdepth * exheight end + end + if newwidth or newheight or newdepth then + for unicode, character in next, characters do + local oldwidth = character.width + local oldheight = character.height + local olddepth = character.depth + local width = newwidth or oldwidth or 0 + local height = newheight or oldheight or 0 + local depth = newdepth or olddepth or 0 + if oldwidth ~= width or oldheight ~= height or olddepth ~= depth then + character.width = width + character.height = height + character.depth = depth + if oldwidth ~= width then + local commands = character.commands + local hshift = rightcommand[(width - oldwidth) / 2] + if commands then + character.commands = prependcommands ( + commands, + hshift + ) + else + character.commands = { + hshift, + charcommand[unicode], + } + end + end + end + end + end + end +end + +local specification = { + name = "dimensions", + description = "force dimensions", + manipulators = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initialize(tfmdata,value) + tfmdata.properties.realdimensions = value and true +end + +registerotffeature { + name = "realdimensions", + description = "accept negative dimenions", + initializers = { + base = initialize, + node = initialize, + } +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-effects.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-effects.lua new file mode 100644 index 00000000000..cc6e4c0bf88 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-effects.lua @@ -0,0 +1,414 @@ +if not modules then modules = { } end modules ['font-imp-effects'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: pickup from goodies: if type(effect) then ... + +local next, type, tonumber = next, type, tonumber +local is_boolean = string.is_boolean + +local fonts = fonts + +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local settings_to_hash = utilities.parsers.settings_to_hash_colon_too + +local helpers = fonts.helpers +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char +local leftcommand = helpers.commands.left +local rightcommand = helpers.commands.right +local upcommand = helpers.commands.up +local downcommand = helpers.commands.down +local dummycommand = helpers.commands.dummy + +----- constructors = fonts.constructors +----- getmathparameter = constructors.getmathparameter +----- setmathparameter = constructors.setmathparameter + +local report_effect = logs.reporter("fonts","effect") +local report_slant = logs.reporter("fonts","slant") +local report_extend = logs.reporter("fonts","extend") +local report_squeeze = logs.reporter("fonts","squeeze") + +local trace = false + +trackers.register("fonts.effect", function(v) trace = v end) +trackers.register("fonts.slant", function(v) trace = v end) +trackers.register("fonts.extend", function(v) trace = v end) +trackers.register("fonts.squeeze",function(v) trace = v end) + +local function initializeslant(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 1 then + value = 1 + elseif value < -1 then + value = -1 + end + if trace then + report_slant("applying %0.3f",value) + end + tfmdata.parameters.slantfactor = value +end + +local specification = { + name = "slant", + description = "slant glyphs", + initializers = { + base = initializeslant, + node = initializeslant, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializeextend(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + if trace then + report_extend("applying %0.3f",value) + end + tfmdata.parameters.extendfactor = value +end + +local specification = { + name = "extend", + description = "scale glyphs horizontally", + initializers = { + base = initializeextend, + node = initializeextend, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializesqueeze(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + if trace then + report_squeeze("applying %0.3f",value) + end + tfmdata.parameters.squeezefactor = value +end + +local specification = { + name = "squeeze", + description = "scale glyphs vertically", + initializers = { + base = initializesqueeze, + node = initializesqueeze, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local effects = { + inner = 0, + normal = 0, + outer = 1, + outline = 1, + both = 2, + hidden = 3, +} + +local function initializeeffect(tfmdata,value) + local spec + if type(value) == "number" then + spec = { width = value } + else + spec = settings_to_hash(value) + end + local effect = spec.effect or "both" + local width = tonumber(spec.width) or 0 + local mode = effects[effect] + if not mode then + report_effect("invalid effect %a",effect) + elseif width == 0 and mode == 0 then + report_effect("invalid width %a for effect %a",width,effect) + else + local parameters = tfmdata.parameters + local properties = tfmdata.properties + parameters.mode = mode + parameters.width = width * 1000 + if is_boolean(spec.auto) == true then + local squeeze = 1 - width/20 + local average = (1 - squeeze) * width * 100 + spec.squeeze = squeeze + spec.extend = 1 + width/2 + spec.wdelta = average + spec.hdelta = average/2 + spec.ddelta = average/2 + spec.vshift = average/2 + end + local factor = tonumber(spec.factor) or 0 + local hfactor = tonumber(spec.hfactor) or factor + local vfactor = tonumber(spec.vfactor) or factor + local delta = tonumber(spec.delta) or 1 + local wdelta = tonumber(spec.wdelta) or delta + local hdelta = tonumber(spec.hdelta) or delta + local ddelta = tonumber(spec.ddelta) or hdelta + local vshift = tonumber(spec.vshift) or 0 + local slant = spec.slant + local extend = spec.extend + local squeeze = spec.squeeze + if slant then + initializeslant(tfmdata,slant) + end + if extend then + initializeextend(tfmdata,extend) + end + if squeeze then + initializesqueeze(tfmdata,squeeze) + end + properties.effect = { + effect = effect, + width = width, + factor = factor, + hfactor = hfactor, + vfactor = vfactor, + wdelta = wdelta, + hdelta = hdelta, + ddelta = ddelta, + vshift = vshift, + slant = tfmdata.parameters.slantfactor, + extend = tfmdata.parameters.extendfactor, + squeeze = tfmdata.parameters.squeezefactor, + } + end +end + +local rules = { + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", +} + +-- local commands = char.commands +-- if commands then +-- local command = commands[1] +-- if command and command[1] == "right" then +-- commands[1] = rightcommand[command[2]-snap] +-- end +-- end + +local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dx) + end + end + end +end + +local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + + local function wdpatch(char) + if wsnap ~= 0 then + char.width = char.width + wdelta/2 + end + end + + local function htpatch(char) + if hsnap ~= 0 then + local height = char.height + if height then + char.height = char.height + 2 * dy + end + end + end + + local character = characters[0x221A] + + if character and character.next then +-- print("base char",0x221A,table.sequenced(character)) + local char = character + local next = character.next + wdpatch(char) + htpatch(char) + while next do + char = characters[next] + wdpatch(char) + htpatch(char) +-- print("next char",next,table.sequenced(char)) + next = char.next + end + if char then + local v = char.vert_variants + if v then + local top = v[#v] + if top then + local char = characters[top.glyph] +-- print("top char",top.glyph,table.sequenced(char)) + htpatch(char) + end + end + end + end +end + +-- local show_effect = { "lua", function(f,c) +-- report_effect("font id %i, char %C",f,c) +-- inspect(fonts.hashes.characters[f][c]) +-- end } + +-- local show_effect = { "lua", "print('!')" } + +local function manipulateeffect(tfmdata) + local effect = tfmdata.properties.effect + if effect then + local characters = tfmdata.characters + local parameters = tfmdata.parameters + local mathparameters = tfmdata.mathparameters + local multiplier = effect.width * 100 + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + local wdelta = effect.wdelta * hfactor * multiplier + local hdelta = effect.hdelta * vfactor * multiplier + local ddelta = effect.ddelta * vfactor * multiplier + local vshift = effect.vshift * vfactor * multiplier + local squeeze = effect.squeeze + local hshift = wdelta / 2 + local dx = multiplier * vfactor + local dy = vshift + local factor = (1 + effect.factor) * factor + local hfactor = (1 + effect.hfactor) * hfactor + local vfactor = (1 + effect.vfactor) * vfactor + local vshift = vshift ~= 0 and upcommand[vshift] or false + for unicode, character in next, characters do + local oldwidth = character.width + local oldheight = character.height + local olddepth = character.depth + if oldwidth and oldwidth > 0 then + character.width = oldwidth + wdelta + local commands = character.commands + local hshift = rightcommand[hshift] + if vshift then + if commands then + prependcommands ( commands, +-- show_effect, + hshift, + vshift + ) + else + character.commands = { +-- show_effect, + hshift, + vshift, + charcommand[unicode] + } + end + else + if commands then + prependcommands ( commands, +-- show_effect, + hshift + ) + else + character.commands = { +-- show_effect, + hshift, + charcommand[unicode] + } + end + end + end + if oldheight and oldheight > 0 then + character.height = oldheight + hdelta + end + if olddepth and olddepth > 0 then + character.depth = olddepth + ddelta + end + end + if mathparameters then + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + end + parameters.factor = factor + parameters.hfactor = hfactor + parameters.vfactor = vfactor + if trace then + report_effect("applying") + report_effect(" effect : %s", effect.effect) + report_effect(" width : %s => %s", effect.width, multiplier) + report_effect(" factor : %s => %s", effect.factor, factor ) + report_effect(" hfactor : %s => %s", effect.hfactor,hfactor) + report_effect(" vfactor : %s => %s", effect.vfactor,vfactor) + report_effect(" wdelta : %s => %s", effect.wdelta, wdelta) + report_effect(" hdelta : %s => %s", effect.hdelta, hdelta) + report_effect(" ddelta : %s => %s", effect.ddelta, ddelta) + end + end +end + +local specification = { + name = "effect", + description = "apply effects to glyphs", + initializers = { + base = initializeeffect, + node = initializeeffect, + }, + manipulators = { + base = manipulateeffect, + node = manipulateeffect, + }, +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializeoutline(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + else + value = tonumber(value) or 0 + end + local parameters = tfmdata.parameters + local properties = tfmdata.properties + parameters.mode = effects.outline + parameters.width = value * 1000 + properties.effect = { + effect = effect, + width = width, + } +end + +local specification = { + name = "outline", + description = "outline glyphs", + initializers = { + base = initializeoutline, + node = initializeoutline, + } +} + +registerotffeature(specification) +registerafmfeature(specification) diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-italics.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-italics.lua new file mode 100644 index 00000000000..83c785d3876 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-italics.lua @@ -0,0 +1,147 @@ +if not modules then modules = { } end modules ['font-imp-italics'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next + +local fonts = fonts +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local function initialize(tfmdata,key,value) + for unicode, character in next, tfmdata.characters do + local olditalic = character.italic + if olditalic and olditalic ~= 0 then + character.width = character.width + olditalic + character.italic = 0 + end + end +end + +local specification = { + name = "italicwidths", + description = "add italic to width", + manipulators = { + base = initialize, + node = initialize, -- only makes sense for math + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initialize(tfmdata,value) -- hm, always value + if value then + -- the magic 40 and it formula come from Dohyun Kim but we might need another guess + local parameters = tfmdata.parameters + local italicangle = parameters.italicangle + if italicangle and italicangle ~= 0 then + local properties = tfmdata.properties + local factor = tonumber(value) or 1 + properties.hasitalics = true + properties.autoitalicamount = factor * (parameters.uwidth or 40)/2 + end + end +end + +local specification = { + name = "itlc", + description = "italic correction", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +if context then + + local function initialize(tfmdata,value) -- yes no delay + tfmdata.properties.textitalics = toboolean(value) + end + + local specification = { + name = "textitalics", + description = "use alternative text italic correction", + initializers = { + base = initialize, + node = initialize, + } + } + + registerotffeature(specification) + registerafmfeature(specification) + +end + +-- no longer used + +-- if context then +-- +-- -- local function initializemathitalics(tfmdata,value) -- yes no delay +-- -- tfmdata.properties.mathitalics = toboolean(value) +-- -- end +-- -- +-- -- local specification = { +-- -- name = "mathitalics", +-- -- description = "use alternative math italic correction", +-- -- initializers = { +-- -- base = initializemathitalics, +-- -- node = initializemathitalics, +-- -- } +-- -- } +-- -- +-- -- registerotffeature(specification) +-- -- registerafmfeature(specification) +-- +-- end + +-- -- also not used, only when testing + +if context then + + local letter = characters.is_letter + local always = true + + local function collapseitalics(tfmdata,key,value) + local threshold = value == true and 100 or tonumber(value) + if threshold and threshold > 0 then + if threshold > 100 then + threshold = 100 + end + for unicode, data in next, tfmdata.characters do + if always or letter[unicode] or letter[data.unicode] then + local italic = data.italic + if italic and italic ~= 0 then + local width = data.width + if width and width ~= 0 then + local delta = threshold * italic / 100 + data.width = width + delta + data.italic = italic - delta + end + end + end + end + end + end + + local dimensions_specification = { + name = "collapseitalics", + description = "collapse italics", + manipulators = { + base = collapseitalics, + node = collapseitalics, + } + } + + registerotffeature(dimensions_specification) + registerafmfeature(dimensions_specification) + +end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-ligatures.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-ligatures.lua new file mode 100644 index 00000000000..091eb5d4b45 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-ligatures.lua @@ -0,0 +1,136 @@ +if not modules then modules = { } end modules ['font-imp-ligatures'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local lpegmatch = lpeg.match +local utfsplit = utf.split +local settings_to_array = utilities.parsers.settings_to_array + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register +local addotffeature = otf.addfeature + +-- This is a quick and dirty hack. + +local lookups = { } +local protect = { } +local revert = { } +local zwjchar = 0x200C +local zwj = { zwjchar } + +addotffeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + prepend = true, -- make sure we do it early + future = true, -- avoid nilling due to no steps yet + lookups = { + { + type = "multiple", + data = lookups, + }, + }, + data = { + rules = protect, + } +} + +addotffeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + append = true, -- this is done late + overload = false, -- we don't want to overload the previous definition + lookups = { + { + type = "ligature", + data = lookups, + }, + }, + data = { + rules = revert, + } +} + +registerotffeature { + name = 'blockligatures', + description = 'block certain ligatures', +} + +local splitter = lpeg.splitat(":") + +local function blockligatures(str) + + local t = settings_to_array(str) + + for i=1,#t do + local ti = t[i] + local before, current, after = lpegmatch(splitter,ti) + if current and after then -- before is returned when no match + -- experimental joke + if before then + before = utfsplit(before) + for i=1,#before do + before[i] = { before[i] } + end + end + if current then + current = utfsplit(current) + end + if after then + after = utfsplit(after) + for i=1,#after do + after[i] = { after[i] } + end + end + else + before = nil + current = utfsplit(ti) + after = nil + end + if #current > 1 then + local one = current[1] + local two = current[2] + lookups[one] = { one, zwjchar } + local one = { one } + local two = { two } + local new = #protect + 1 + protect[new] = { + before = before, + current = { one, two }, + after = after, + lookups = { 1 }, -- not shared ! + } + revert[new] = { + -- before = before, + current = { one, zwj }, + -- after = { two, unpack(after) }, + after = { two }, + lookups = { 1 }, -- not shared ! + } + end + end +end + +-- blockligatures("\0\0") + +otf.helpers.blockligatures = blockligatures + +-- blockligatures("fi,ff") +-- blockligatures("fl") +-- blockligatures("u:fl:age") + +if context then + + interfaces.implement { + name = "blockligatures", + arguments = "string", + actions = blockligatures, + } + +end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-math.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-math.lua new file mode 100644 index 00000000000..d93ece4059b --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-math.lua @@ -0,0 +1,81 @@ +if not modules then modules = { } end modules ['font-imp-math'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber + +local fonts = fonts +local helpers = fonts.helpers +local registerotffeature = fonts.handlers.otf.features.register + +local setmetatableindex = table.setmetatableindex + +-- requested for latex but not supported unless really needed in context: +-- +-- registerotffeature { +-- name = "ignoremathconstants", +-- description = "ignore math constants table", +-- initializers = { +-- base = function(tfmdata,value) +-- if value then +-- tfmdata.mathparameters = nil +-- end +-- end +-- } +-- } + +-- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0 + +local splitter = lpeg.splitat(",",tonumber) +local lpegmatch = lpeg.match + +local function initialize(tfmdata,value) + local mathparameters = tfmdata.mathparameters + if mathparameters then + local sup, sub + if type(value) == "string" then + sup, sub = lpegmatch(splitter,value) + if not sup then + sub, sup = 0, 0 + elseif not sub then + sub, sup = sup, 0 + end + elseif type(value) == "number" then + sup, sub = 0, value + end + if sup then + mathparameters.NoLimitSupFactor = sup + end + if sub then + mathparameters.NoLimitSubFactor = sub + end + end +end + +registerotffeature { + name = "mathnolimitsmode", + description = "influence nolimits placement", + initializers = { + base = initialize, + node = initialize, + } +} + +local function initialize(tfmdata,value) + tfmdata.properties.nostackmath = value and true +end + +registerotffeature { + name = "nostackmath", + description = "disable math stacking mechanism", + initializers = { + base = initialize, + node = initialize, + } +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-notused.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-notused.lua new file mode 100644 index 00000000000..be36c98988e --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-notused.lua @@ -0,0 +1,168 @@ +if not modules then modules = { } end modules ['font-imp-notused'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +-- local next = next +-- local utfbyte = utf.byte +-- +-- local fonts = fonts +-- +-- local handlers = fonts.handlers +-- local otf = handlers.otf +-- local afm = handlers.afm +-- +-- local registerotffeature = otf.features.register +-- local registerafmfeature = afm.features.register + +-- local function initialize(tfmdata) +-- local resources = tfmdata.resources +-- local gposfeatures = resources.features.gpos +-- local characters = tfmdata.characters +-- local descriptions = tfmdata.descriptions +-- local sequences = resources.sequences +-- local coverage = { } +-- local units = tfmdata.shared.rawdata.metadata.units +-- for k, v in next, characters do +-- local w = descriptions[k].width +-- local d = units - w +-- coverage[k] = { -d/2, 0, units, 0 } +-- end +-- local f = { dflt = { dflt = true } } +-- local s = #sequences + 1 +-- local t = { +-- features = { fakemono = f }, +-- flags = { false, false, false, false }, +-- index = s, +-- name = "p_s_" .. s, +-- nofsteps = 1, +-- order = { "fakemono" }, +-- skiphash = false, +-- type = "gpos_single", +-- steps = { +-- { +-- format = "single", +-- coverage = coverage, +-- } +-- } +-- } +-- gposfeatures["fakemono"] = f +-- sequences[s] = t +-- end +-- +-- registerotffeature { +-- name = "fakemono", +-- description = "fake monospaced", +-- initializers = { +-- node = initialize, +-- }, +-- } + +-- -- for notosans but not general +-- +-- local v_local = interfaces and interfaces.variables and interfaces.variables["local"] or "local" +-- +-- local function initialize(tfmdata,key,value) +-- local characters = tfmdata.characters +-- local parameters = tfmdata.parameters +-- local oldchar = 32 +-- local newchar = 32 +-- if value == "locl" or value == v_local then +-- newchar = fonts.handlers.otf.getsubstitution(tfmdata,oldchar,"locl",true) or oldchar +-- elseif value == true then +-- -- use normal space +-- elseif value then +-- newchar = utfbyte(value) +-- else +-- return +-- end +-- local newchar = newchar and characters[newchar] +-- local newspace = newchar and newchar.width +-- if newspace > 0 then +-- parameters.space = newspace +-- parameters.space_stretch = newspace/2 +-- parameters.space_shrink = newspace/3 +-- parameters.extra_space = parameters.space_shrink +-- end +-- end +-- +-- registerotffeature { +-- name = 'space', -- true|false|locl|character +-- description = 'space settings', +-- manipulators = { +-- base = initialize, +-- node = initialize, +-- } +-- } + +-- -- historic stuff, move from font-ota (handled differently, typo-rep) +-- +-- local delete_node = nodes.delete +-- local fontdata = fonts.hashes.identifiers +-- +-- local nodecodes = nodes.nodecodes +-- local glyph_code = nodecodes.glyph +-- +-- local strippables = allocate() +-- fonts.strippables = strippables +-- +-- strippables.joiners = table.tohash { +-- 0x200C, -- zwnj +-- 0x200D, -- zwj +-- } +-- +-- strippables.all = table.tohash { +-- 0x000AD, 0x017B4, 0x017B5, 0x0200B, 0x0200C, 0x0200D, 0x0200E, 0x0200F, 0x0202A, 0x0202B, +-- 0x0202C, 0x0202D, 0x0202E, 0x02060, 0x02061, 0x02062, 0x02063, 0x0206A, 0x0206B, 0x0206C, +-- 0x0206D, 0x0206E, 0x0206F, 0x0FEFF, 0x1D173, 0x1D174, 0x1D175, 0x1D176, 0x1D177, 0x1D178, +-- 0x1D179, 0x1D17A, 0xE0001, 0xE0020, 0xE0021, 0xE0022, 0xE0023, 0xE0024, 0xE0025, 0xE0026, +-- 0xE0027, 0xE0028, 0xE0029, 0xE002A, 0xE002B, 0xE002C, 0xE002D, 0xE002E, 0xE002F, 0xE0030, +-- 0xE0031, 0xE0032, 0xE0033, 0xE0034, 0xE0035, 0xE0036, 0xE0037, 0xE0038, 0xE0039, 0xE003A, +-- 0xE003B, 0xE003C, 0xE003D, 0xE003E, 0xE003F, 0xE0040, 0xE0041, 0xE0042, 0xE0043, 0xE0044, +-- 0xE0045, 0xE0046, 0xE0047, 0xE0048, 0xE0049, 0xE004A, 0xE004B, 0xE004C, 0xE004D, 0xE004E, +-- 0xE004F, 0xE0050, 0xE0051, 0xE0052, 0xE0053, 0xE0054, 0xE0055, 0xE0056, 0xE0057, 0xE0058, +-- 0xE0059, 0xE005A, 0xE005B, 0xE005C, 0xE005D, 0xE005E, 0xE005F, 0xE0060, 0xE0061, 0xE0062, +-- 0xE0063, 0xE0064, 0xE0065, 0xE0066, 0xE0067, 0xE0068, 0xE0069, 0xE006A, 0xE006B, 0xE006C, +-- 0xE006D, 0xE006E, 0xE006F, 0xE0070, 0xE0071, 0xE0072, 0xE0073, 0xE0074, 0xE0075, 0xE0076, +-- 0xE0077, 0xE0078, 0xE0079, 0xE007A, 0xE007B, 0xE007C, 0xE007D, 0xE007E, 0xE007F, +-- } +-- +-- strippables[true] = strippables.joiners +-- +-- local function processformatters(head,font) +-- local subset = fontdata[font].shared.features.formatters +-- local vector = subset and strippables[subset] +-- if vector then +-- local current, done = head, false +-- while current do +-- if current.id == glyph_code and current.subtype<256 and current.font == font then +-- local char = current.char +-- if vector[char] then +-- head, current = delete_node(head,current) +-- done = true +-- else +-- current = current.next +-- end +-- else +-- current = current.next +-- end +-- end +-- return head, done +-- else +-- return head, false +-- end +-- end +-- +-- registerotffeature { +-- name = "formatters", +-- description = "hide formatting characters", +-- methods = { +-- base = processformatters, +-- node = processformatters, +-- } +-- } diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-properties.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-properties.lua new file mode 100644 index 00000000000..5805235b780 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-properties.lua @@ -0,0 +1,130 @@ +if not modules then modules = { } end modules ['font-imp-properties'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber, select = next, type, tonumber, select +local byte, find, formatters = string.byte, string.find, string.formatters +local utfchar = utf.char +local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort +local insert = table.insert + +local context = context +local fonts = fonts +local utilities = utilities + +local helpers = fonts.helpers + +local handlers = fonts.handlers +local hashes = fonts.hashes +local otf = handlers.otf +local afm = handlers.afm + +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local fontdata = hashes.identifiers +local fontproperties = hashes.properties + +local constructors = fonts.constructors +local getprivate = constructors.getprivate + +local allocate = utilities.storage.allocate +local family_font = node.family_font + +local setmetatableindex = table.setmetatableindex + +local implement = interfaces.implement + +do + + local P, lpegpatterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match + + local amount, stretch, shrink, extra + + local factor = lpegpatterns.unsigned + local space = lpegpatterns.space + local pattern = ( + (factor / function(n) amount = tonumber(n) or amount end) + + (P("+") + P("plus" )) * space^0 * (factor / function(n) stretch = tonumber(n) or stretch end) + + (P("-") + P("minus")) * space^0 * (factor / function(n) shrink = tonumber(n) or shrink end) + + ( P("extra")) * space^0 * (factor / function(n) extra = tonumber(n) or extra end) + + space^1 + )^1 + + local function initialize(tfmdata,key,value) + local characters = tfmdata.characters + local parameters = tfmdata.parameters + if type(value) == "string" then + local emwidth = parameters.quad + amount, stretch, shrink, extra = 0, 0, 0, false + lpegmatch(pattern,value) + if not extra then + if shrink ~= 0 then + extra = shrink + elseif stretch ~= 0 then + extra = stretch + else + extra = amount + end + end + parameters.space = amount * emwidth + parameters.space_stretch = stretch * emwidth + parameters.space_shrink = shrink * emwidth + parameters.extra_space = extra * emwidth + end + end + + -- 1.1 + 1.2 - 1.3 minus 1.4 plus 1.1 extra 1.4 -- last one wins + + registerotffeature { + name = "spacing", + description = "space settings", + manipulators = { + base = initialize, + node = initialize, + } + } + +end + +do + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.identity = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "identity", + description = "set font identity", + initializers = { + base = initialize, + node = initialize, + } + } + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.writingmode = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "writingmode", + description = "set font direction", + initializers = { + base = initialize, + node = initialize, + } + } + +end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-quality.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-quality.lua new file mode 100644 index 00000000000..01f0afe6309 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-quality.lua @@ -0,0 +1,527 @@ +if not modules then modules = { } end modules ['font-imp-quality'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber +local byte = string.byte +local insert = table.insert + +local fonts = fonts +local utilities = utilities + +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local allocate = utilities.storage.allocate +local getparameters = utilities.parsers.getparameters + +local implement = interfaces and interfaces.implement + +local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) +local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) + +local report_expansions = logs.reporter("fonts","expansions") +local report_protrusions = logs.reporter("fonts","protrusions") + +-- -- -- -- -- -- +-- shared +-- -- -- -- -- -- + +local function get_class_and_vector(tfmdata,value,where) -- "expansions" + local g_where = tfmdata.goodies and tfmdata.goodies[where] + local f_where = fonts[where] + local g_classes = g_where and g_where.classes + local f_classes = f_where and f_where.classes + local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) + if class then + local class_vector = class.vector + local g_vectors = g_where and g_where.vectors + local f_vectors = f_where and f_where.vectors + local vector = (g_vectors and g_vectors[class_vector]) or (f_vectors and f_vectors[class_vector]) + return class, vector + end +end + +-- -- -- -- -- -- +-- expansion (hz) +-- -- -- -- -- -- + +local expansions = fonts.expansions or allocate() + +fonts.expansions = expansions + +local classes = expansions.classes or allocate() +local vectors = expansions.vectors or allocate() + +expansions.classes = classes +expansions.vectors = vectors + +-- beware, pdftex itself uses percentages * 10 +-- +-- todo: get rid of byte() here + +classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } + +classes['quality'] = { + stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1 +} + +vectors['default'] = { + [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, + [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, + [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, + [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, + [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, + [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, + [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, + [byte('w')] = 0.7, [byte('z')] = 0.7, + [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, +} + +vectors['quality'] = vectors['default'] -- metatable ? + +local function initialize(tfmdata,value) + if value then + local class, vector = get_class_and_vector(tfmdata,value,"expansions") + if class then + if vector then + local stretch = class.stretch or 0 + local shrink = class.shrink or 0 + local step = class.step or 0 + local factor = class.factor or 1 + if trace_expansion then + report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", + value,class.vector,factor,stretch,shrink,step) + end + tfmdata.parameters.expansion = { + stretch = 10 * stretch, + shrink = 10 * shrink, + step = 10 * step, + factor = factor, + } + local data = characters and characters.data + for i, chr in next, tfmdata.characters do + local v = vector[i] + if data and not v then -- we could move the data test outside (needed for plain) + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 + else + v = vector[s] or 0 + end + end + end + if v and v ~= 0 then + chr.expansion_factor = v*factor + else -- can be option + chr.expansion_factor = factor + end + end + elseif trace_expansion then + report_expansions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_expansion then + report_expansions("unknown class %a",value) + end + end +end + +local specification = { + name = "expansion", + description = "apply hz optimization", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) + +if context then + + implement { + name = "setupfontexpansion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end + } + +end + +-- -- -- -- -- -- +-- protrusion +-- -- -- -- -- -- + +fonts.protrusions = allocate() +local protrusions = fonts.protrusions + +protrusions.classes = allocate() +protrusions.vectors = allocate() + +local classes = protrusions.classes +local vectors = protrusions.vectors + +-- the values need to be revisioned + +classes.preset = { factor = 1, left = 1, right = 1 } + +classes['pure'] = { + vector = 'pure', factor = 1 +} +classes['punctuation'] = { + vector = 'punctuation', factor = 1 +} +classes['alpha'] = { + vector = 'alpha', factor = 1 +} +classes['quality'] = { + vector = 'quality', factor = 1 +} + +vectors['pure'] = { + + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x00AD] = { 0, 1 }, -- also hyphen + [0x2013] = { 0, 0.50 }, -- endash + [0x2014] = { 0, 0.33 }, -- emdash + [0x3001] = { 0, 1 }, -- ideographic comma 、 + [0x3002] = { 0, 1 }, -- ideographic full stop 。 + [0x060C] = { 0, 1 }, -- arabic comma ، + [0x061B] = { 0, 1 }, -- arabic semicolon ؛ + [0x06D4] = { 0, 1 }, -- arabic full stop ۔ + +} + +vectors['punctuation'] = { + + [0x003F] = { 0, 0.20 }, -- ? + [0x00BF] = { 0.20, 0 }, -- ¿ + [0x0021] = { 0, 0.20 }, -- ! + [0x00A1] = { 0.20, 0, }, -- ¡ + [0x0028] = { 0.05, 0 }, -- ( + [0x0029] = { 0, 0.05 }, -- ) + [0x005B] = { 0.05, 0 }, -- [ + [0x005D] = { 0, 0.05 }, -- ] + [0x002C] = { 0, 0.70 }, -- comma + [0x002E] = { 0, 0.70 }, -- period + [0x003A] = { 0, 0.50 }, -- colon + [0x003B] = { 0, 0.50 }, -- semicolon + [0x002D] = { 0, 0.70 }, -- hyphen + [0x00AD] = { 0, 0.70 }, -- also hyphen + [0x2013] = { 0, 0.30 }, -- endash + [0x2014] = { 0, 0.20 }, -- emdash + [0x060C] = { 0, 0.70 }, -- arabic comma + [0x061B] = { 0, 0.50 }, -- arabic semicolon + [0x06D4] = { 0, 0.70 }, -- arabic full stop + [0x061F] = { 0, 0.20 }, -- ؟ + + -- todo: left and right quotes: .5 double, .7 single + + [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ + [0x203A] = { 0.70, 0.70 }, -- right single guillemet › + [0x00AB] = { 0.50, 0.50 }, -- left guillemet « + [0x00BB] = { 0.50, 0.50 }, -- right guillemet » + + [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ + [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ + [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , + [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ + [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ + [0x201D] = { 0, 0.50 }, -- right double quotation mark ” + [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ + [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ + +} + +vectors['alpha'] = { + + [byte("A")] = { .05, .05 }, + [byte("F")] = { 0, .05 }, + [byte("J")] = { .05, 0 }, + [byte("K")] = { 0, .05 }, + [byte("L")] = { 0, .05 }, + [byte("T")] = { .05, .05 }, + [byte("V")] = { .05, .05 }, + [byte("W")] = { .05, .05 }, + [byte("X")] = { .05, .05 }, + [byte("Y")] = { .05, .05 }, + + [byte("k")] = { 0, .05 }, + [byte("r")] = { 0, .05 }, + [byte("t")] = { 0, .05 }, + [byte("v")] = { .05, .05 }, + [byte("w")] = { .05, .05 }, + [byte("x")] = { .05, .05 }, + [byte("y")] = { .05, .05 }, + +} + +vectors['quality'] = table.merged( + vectors['punctuation'], + vectors['alpha'] +) + +-- As this is experimental code, users should not depend on it. The implications are still +-- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the +-- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The +-- double trick should not be needed it proper hanging punctuation is used in which case +-- values < 1 can be used. +-- +-- preferred (in context, usine vectors): +-- +-- \definefontfeature[whatever][default][mode=node,protrusion=quality] +-- +-- using lfbd and rtbd, with possibibility to enable only one side : +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] +-- +-- idem, using multiplier +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] +-- +-- idem, using named feature file (less frozen): +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] + +classes['double'] = { -- for testing opbd + factor = 2, left = 1, right = 1, +} + +local function map_opbd_onto_protrusion(tfmdata,value,opbd) + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local resources = tfmdata.resources + local rawdata = tfmdata.shared.rawdata + local lookuphash = rawdata.lookuphash + local lookuptags = resources.lookuptags + local script = properties.script + local language = properties.language + local units = parameters.units + local done, factor, left, right = false, 1, 1, 1 + local class = classes[value] + if class then + factor = class.factor or 1 + left = class.left or 1 + right = class.right or 1 + else + factor = tonumber(value) or 1 + end + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + if opbd ~= "right" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"lfbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting left using lfbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[1] + if w == 0 or d == 0 then + -- ignored + else + local p = lfactor * d/units + characters[k].left_protruding = p + if trace_protrusion then + report_protrusions("lfbd -> %0.3F %C",p,k) + end + end + end + end + end + end + done = true + end + end + end + end + if opbd ~= "left" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"rtbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting right using rtbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[3] + if w == 0 or d == 0 then + -- ignored + else + local p = rfactor * d/units + characters[k].right_protruding = p + if trace_protrusion then + report_protrusions("rtbd -> %0.3F %C",p,k) + end + end + end + end + end + end + end + done = true + end + end + end +end + +-- The opbd test is just there because it was discussed on the context development list. However, +-- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported +-- till we have a proper test font. + +local function initialize(tfmdata,value) + if value then + local opbd = tfmdata.shared.features.opbd + if opbd then + -- possible values: left right both yes no (experimental) + map_opbd_onto_protrusion(tfmdata,value,opbd) + else + local class, vector = get_class_and_vector(tfmdata,value,"protrusions") + if class then + if vector then + local factor = class.factor or 1 + local left = class.left or 1 + local right = class.right or 1 + if trace_protrusion then + report_protrusions("setting class %a, vector %a, factor %a, left %a, right %a", + value,class.vector,factor,left,right) + end + local data = characters.data + local emwidth = tfmdata.parameters.quad + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + for i, chr in next, tfmdata.characters do + local v = vector[i] + local pl = nil + local pr = nil + if v then + pl = v[1] + pr = v[2] + else + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + local vl = vector[s[1]] + local vr = vector[s[#s]] + if vl then pl = vl[1] end + if vr then pr = vr[2] end + else + v = vector[s] + if v then + pl = v[1] + pr = v[2] + end + end + end + end + if pl and pl ~= 0 then + local p = pl * lfactor + chr.left_protruding = p + if trace_protrusion then + report_protrusions("left -> %0.3F %C ",p,i) + end + end + if pr and pr ~= 0 then + local p = pr * rfactor + chr.right_protruding = p + if trace_protrusion then + report_protrusions("right -> %0.3F %C",p,i) + end + end + end + elseif trace_protrusion then + report_protrusions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_protrusion then + report_protrusions("unknown class %a",value) + end + end + end +end + +local specification = { + name = "protrusion", + description = "l/r margin character protrusion", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) + +if context then + + implement { + name = "setupfontprotrusion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end + } + +end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-reorder.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-reorder.lua new file mode 100644 index 00000000000..b2dec781c7d --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-reorder.lua @@ -0,0 +1,174 @@ +if not modules then modules = { } end modules ['font-imp-reorder'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next = next +local find = string.find +local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register + +-- This is a rather special test-only feature that I added for the sake of testing +-- Idris's husayni. We wanted to know if uniscribe obeys the order of lookups in a +-- font, in spite of what the description of handling arabic suggests. And indeed, +-- mixed-in lookups of other features (like all these ss* in husayni) are handled +-- the same in context as in uniscribe. If one sets reorderlookups=arab then we sort +-- according to the "assumed" order so e.g. the ss* move to after the standard +-- features. The observed difference in rendering is an indication that uniscribe is +-- quite faithful to the font (while e.g. tests with the hb plugin demonstrate some +-- interference, apart from some hard coded init etc expectations). Anyway, it means +-- that we're okay with the (generic) node processor. A pitfall is that in context +-- we can actually control more, so we can trigger an analyze pass with e.g. +-- dflt/dflt while the libraries depend on the script settings for that. Uniscribe +-- probably also parses the string and when seeing arabic will follow a different +-- code path, although it seems to treat all features equal. + +local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trace_reorder = v end) +local report_reorder = logs.reporter("fonts","reorder") + +local vectors = { } + +vectors.arab = { + gsub = { + ccmp = 1, + isol = 2, + fina = 3, + medi = 4, + init = 5, + rlig = 6, + rclt = 7, + calt = 8, + liga = 9, + dlig = 10, + cswh = 11, + mset = 12, + }, + gpos = { + curs = 1, + kern = 2, + mark = 3, + mkmk = 4, + }, +} + +local function compare(a,b) + local what_a = a.what + local what_b = b.what + if what_a ~= what_b then + return a.index < b.index + end + local when_a = a.when + local when_b = b.when + if when_a == when_b then + return a.index < b.index + else + return when_a < when_b + end +end + +function otf.reorderlookups(tfmdata,vector) + local order = vectors[vector] + if not order then + return + end + local oldsequences = tfmdata.resources.sequences + if oldsequences then + local sequences = { } + for i=1,#oldsequences do + sequences[i] = oldsequences[i] + end + for i=1,#sequences do + local s = sequences[i] + local features = s.features + local kind = s.type + local index = s.index + if features then + local when + local what + for feature in sortedhash(features) do + if not what then + what = find(kind,"^gsub") and "gsub" or "gpos" + end + local newwhen = order[what][feature] + if not newwhen then + -- skip + elseif not when then + when = newwhen + elseif newwhen < when then + when = newwhen + end + end + s.ondex = s.index + s.index = i + s.what = what == "gsub" and 1 or 2 + s.when = when or 99 + else + s.ondex = s.index + s.index = i + s.what = 1 + s.when = 99 + end + end + sort(sequences,compare) + local swapped = 0 + for i=1,#sequences do + local sequence = sequences[i] + local features = sequence.features + if features then + local index = sequence.index + if index ~= i then + swapped = swapped + 1 + end + if trace_reorder then + if swapped == 1 then + report_reorder() + report_reorder("start swapping lookups in font %!font:name!",tfmdata) + report_reorder() + report_reorder("gsub order: % t",table.swapped(order.gsub)) + report_reorder("gpos order: % t",table.swapped(order.gpos)) + report_reorder() + end + report_reorder("%03i : lookup %03i, type %s, sorted %2i, moved %s, % t", + i,index,sequence.what == 1 and "gsub" or "gpos",sequence.when or 99, + (index > i and "-") or (index < i and "+") or "=",sortedkeys(features)) + end + end + sequence.what = nil + sequence.when = nil + sequence.index = sequence.ondex + end + if swapped > 0 then + if trace_reorder then + report_reorder() + report_reorder("stop swapping lookups, %i lookups swapped",swapped) + report_reorder() + end + tfmdata.shared.reorderedsequences = sequences + end + end +end + +-- maybe delay till ra is filled + +local function initialize(tfmdata,key,value) + if value then + otf.reorderlookups(tfmdata,value) + end +end + +registerotffeature { + name = "reorderlookups", + description = "reorder lookups", + manipulators = { + base = initialize, + node = initialize, + } +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-tex.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-tex.lua new file mode 100644 index 00000000000..b4b9a7b6943 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-tex.lua @@ -0,0 +1,144 @@ +if not modules then modules = { } end modules ['font-imp-tex'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register +local addotffeature = otf.addfeature + +-- tlig (we need numbers for some fonts so ...) + +local specification = { + type = "ligature", + order = { "tlig" }, + prepend = true, + data = { + -- endash = "hyphen hyphen", + -- emdash = "hyphen hyphen hyphen", + [0x2013] = { 0x002D, 0x002D }, + [0x2014] = { 0x002D, 0x002D, 0x002D }, + -- quotedblleft = "quoteleft quoteleft", + -- quotedblright = "quoteright quoteright", + -- quotedblleft = "grave grave", + -- quotedblright = "quotesingle quotesingle", + -- quotedblbase = "comma comma", + }, +} + +addotffeature("tlig",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "tlig", + description = "tex ligatures", +} + +-- trep + +local specification = { + type = "substitution", + order = { "trep" }, + prepend = true, + data = { + -- [0x0022] = 0x201D, + [0x0027] = 0x2019, + -- [0x0060] = 0x2018, + }, +} + +addotffeature("trep",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "trep", + description = "tex replacements", +} + +-- some day this will be moved to font-imp-scripts.lua + +-- anum + +local anum_arabic = { + [0x0030] = 0x0660, + [0x0031] = 0x0661, + [0x0032] = 0x0662, + [0x0033] = 0x0663, + [0x0034] = 0x0664, + [0x0035] = 0x0665, + [0x0036] = 0x0666, + [0x0037] = 0x0667, + [0x0038] = 0x0668, + [0x0039] = 0x0669, +} + +local anum_persian = { + [0x0030] = 0x06F0, + [0x0031] = 0x06F1, + [0x0032] = 0x06F2, + [0x0033] = 0x06F3, + [0x0034] = 0x06F4, + [0x0035] = 0x06F5, + [0x0036] = 0x06F6, + [0x0037] = 0x06F7, + [0x0038] = 0x06F8, + [0x0039] = 0x06F9, +} + +local function valid(data) + local features = data.resources.features + if features then + for k, v in next, features do + for k, v in next, v do + if v.arab then + return true + end + end + end + end +end + +local specification = { + { + type = "substitution", + features = { arab = { urd = true, dflt = true } }, + order = { "anum" }, + data = anum_arabic, + valid = valid, + }, + { + type = "substitution", + features = { arab = { urd = true } }, + order = { "anum" }, + data = anum_persian, + valid = valid, + }, +} + +addotffeature("anum",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "anum", + description = "arabic digits", +} + +-- -- example: +-- +-- fonts.handlers.otf.addfeature { +-- name = "hangulfix", +-- type = "substitution", +-- features = { ["hang"] = { ["*"] = true } }, +-- data = { +-- [0x1160] = 0x119E, +-- }, +-- order = { "hangulfix" }, +-- flags = { }, +-- prepend = true, +-- }) diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-imp-tracing.lua b/Master/texmf-dist/tex/context/base/mkiv/font-imp-tracing.lua new file mode 100644 index 00000000000..6ce44514372 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/font-imp-tracing.lua @@ -0,0 +1,281 @@ +if not modules then modules = { } end modules ['font-imp-tracing'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type = next, type +local concat = table.concat +local formatters = string.formatters + +local fonts = fonts + +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local settings_to_array = utilities.parsers.settings_to_array +local setmetatableindex = table.setmetatableindex + +local helpers = fonts.helpers +local appendcommandtable = helpers.appendcommandtable +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char + +local variables = interfaces.variables + +local v_background = variables.background +local v_frame = variables.frame +local v_empty = variables.empty +local v_none = variables.none + +-- for zhichu chen (see mailing list archive): we might add a few more variants +-- in due time +-- +-- \definefontfeature[boxed][default][boundingbox=yes] % paleblue +-- +-- maybe: +-- +-- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression +-- +-- local gray = { "pdf", "origin", "/Tr1 gs .75 g" } +-- local black = { "pdf", "origin", "/Tr0 gs 0 g" } + +-- boundingbox={yes|background|frame|empty|Not much is happening here.
--ldx]]-- -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate +local sortedhash = table.sortedhash -fonts = fonts or { } -local fonts = fonts +fonts = fonts or { } +local fonts = fonts -fonts.hashes = fonts.hashes or { identifiers = allocate() } -fonts.tables = fonts.tables or { } -fonts.helpers = fonts.helpers or { } -fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata -fonts.specifiers = fonts.specifiers or { } -- in format ! +local identifiers = allocate() -fonts.analyzers = { } -- not needed here -fonts.readers = { } -fonts.definers = { methods = { } } -fonts.loggers = { register = function() end } +fonts.hashes = fonts.hashes or { identifiers = identifiers } +fonts.tables = fonts.tables or { } +fonts.helpers = fonts.helpers or { } +fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata +fonts.specifiers = fonts.specifiers or { } -- in format ! + +fonts.analyzers = { } -- not needed here +fonts.readers = { } +fonts.definers = { methods = { } } +fonts.loggers = { register = function() end } if context then + + font.originaleach = font.each + + function font.each() + return sortedhash(identifiers) + end + fontloader = nil + end + +-- Outside context one can bump textbase to some higher value but only the +-- textbase given here is officially supported (read: bug testing etc will +-- use the values below). + +fonts.privateoffsets = { + textbase = 0xF0000, -- used for hidden (opentype features) + textextrabase = 0xFD000, -- used for visible by name + mathextrabase = 0xFE000, -- used for visible by code + mathbase = 0xFF000, -- used for hidden (virtual math) + keepnames = false, -- when set to true names are always kept (not for context) +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-ini.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-ini.mkvi index 69318291929..dd8a5f14834 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-ini.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-ini.mkvi @@ -341,12 +341,16 @@ \the\everybodyfont \settrue\c_font_synchronize} +\let\savedfont\empty + +\installmacrostack\savedfont + \unexpanded\def\savefont {\edef\savedfont{\the\font}% gives \csname - \pushmacro\savedfont} + \push_macro_savedfont} \unexpanded\def\restorefont - {\popmacro\savedfont + {\pop_macro_savedfont \savedfont} \unexpanded\def\pushcurrentfont @@ -424,7 +428,7 @@ % % \def\normalizebodyfontsize_indeed#macro#body% % {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body,\number\fontdigits)}}% -% \global\expandafter\let\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} +% \expandafter\glet\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} % % \def\thenormalizedbodyfontsize#body% % {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}} @@ -439,7 +443,7 @@ \def\normalizebodyfontsize_indeed#macro#body% {\edef#macro{\clf_nbfs\dimexpr#body\relax}% - \global\expandafter\let\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} + \expandafter\glet\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} \def\thenormalizedbodyfontsize#body% {\clf_nbfs\dimexpr#body\relax} @@ -583,8 +587,7 @@ \def\font_basics_define_fontstyle[#commands][#style]% style: rm ss tt ... {\ifcsname\??fontstyleknown#style\endcsname \else % can be delayed till used (cg, hw) \font_helpers_register_style{#style}% - % todo: apptoks - \t_font_style_commands\expandafter{\the\t_font_style_commands\m_font_style_command{#style}}% + \toksapp\t_font_style_commands{\m_font_style_command{#style}}% \fi \processcommalist[#commands]{\font_basics_define_fontstyle_indeed{#style}}} @@ -595,17 +598,14 @@ \unexpanded\def\definefontsize[#size]% {\ifcsname\??fontsizeknown#size\endcsname \else \font_helpers_register_size{#size}% - \t_font_size_commands\expandafter{\the\t_font_size_commands - \m_font_size_command{#size}}% + \toksapp\t_font_size_commands{\m_font_size_command{#size}}% \fi \font_helpers_check_fontname_combinations} \unexpanded\def\definefontalternative[#alternative]% {\ifcsname\??fontalternativeknown#alternative\endcsname \else \font_helpers_register_alternative{#alternative}% - % todo: apptoks - \t_font_alternative_commands\expandafter{\the\t_font_alternative_commands - \m_font_alternative_command{#alternative}}% + \toksapp\t_font_alternative_commands{\m_font_alternative_command{#alternative}}% \fi \font_helpers_check_fontname_combinations} @@ -775,7 +775,7 @@ \unexpanded\def\font_helpers_low_level_define#specification#csname% {% we can now set more at the lua end - \global\let\somefontname\defaultfontfile + \glet\somefontname\defaultfontfile \let\somefontsize\empty \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen % sets \scaledfontmode and \somefontname and \somefontsize @@ -912,7 +912,7 @@ %D The following macros are used at the \LUA\ end. Watch the \type {\normal} %D hackery: this makes the mkvi parser happy. -% \normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} % do before calling +% \normaldef\fntsetdefname {\glet\somefontname\defaultfontfile} % do before calling % \normaldef\fntsetnopsize {\let\somefontsize\empty} % do before calling % \normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument % \normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument @@ -1038,7 +1038,7 @@ {\begingroup \font_basics_define_font[#name][#specification][#settings]% \csname#name\endcsname - \global\let\lastglobalrawfontcall\lastrawfontcall + \glet\lastglobalrawfontcall\lastrawfontcall \endgroup \expandafter\let\csname#name\endcsname\lastglobalrawfontcall} @@ -1377,16 +1377,16 @@ %D settings (just to be sure, as it's not really needed). \def\font_basics_define_body_font_environment_empty[#body][#settings][#dummy]% - {\pushmacro\fontclass + {\push_macro_fontclass \let\fontclass\empty \font_basics_define_body_font_environment_class[][#body][#settings]% - \popmacro\fontclass} + \pop_macro_fontclass} \def\font_basics_define_body_font_environment_unset[#body][#dummya][#dummyb]% - {\pushmacro\fontclass + {\push_macro_fontclass \let\fontclass\empty \font_basics_define_body_font_environment_class[][#body][]% - \popmacro\fontclass} + \pop_macro_fontclass} %D We don't check too soon as we can refer to later definitions. @@ -1397,13 +1397,13 @@ \ifcsname\??fontenvironmentknown#class#normalizedbody\endcsname % environment and size already defined \else\ifproductionrun - \pushmacro\fontclass + \push_macro_fontclass \edef\fontclass{#class}% \font_helpers_register_environment{#class}{#normalizedbody}% \settrue\c_font_defining_environment_state \font_helpers_define_unknown_font{#normalizedbody}% current class \setfalse\c_font_defining_environment_state - \popmacro\fontclass + \pop_macro_fontclass \fi\fi \font_helpers_register_fontbody{#normalizedbody}} @@ -1527,12 +1527,12 @@ \fi} \def\font_basics_define_body_font_class_given[#1][#2][#3]#4% - {\pushmacro\fontclass + {\push_macro_fontclass \doifelse{#4}\s!default {\let\fontclass\empty} {\def\fontclass{#4}}% \definebodyfont[#1][#2][#3]% - \popmacro\fontclass} + \pop_macro_fontclass} \def\font_basics_define_body_font_class_known {\ifthirdargument @@ -1644,13 +1644,13 @@ \unexpanded\def\font_basics_define_body_font_yes_xx[#one#two#rest=#value]% global {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-0}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-4}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-5}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% } @@ -1673,9 +1673,9 @@ \unexpanded\def\font_basics_define_body_font_yes_mm[#one#two#rest=#value]% global {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined - % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined - % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined + % \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined + % \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% } @@ -1727,7 +1727,8 @@ \font_helpers_process_style_list{\font_helpers_define_unknown_check_definitions{#body}}% \ifconditional\c_font_defining_state \ifconditional\c_font_defining_environment_state\else - \showmessage\m!fonts{14}{#body}% main + %\showmessage\m!fonts{14}{#body}% main + \clf_registerunknownbodysize{#body}% \fi \setfalse\c_font_defining_state \font_helpers_register_fontbody{#body}% @@ -1741,13 +1742,6 @@ \fi \fi} -% \def\font_helpers_define_unknown_check_sizes#body#relativesize% -% {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ? -% % how \lastnamedcs here -% \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}% -% \settrue\c_font_defining_state -% \fi} - \def\font_helpers_define_unknown_check_sizes#body#relativesize% {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ? \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}% @@ -2363,7 +2357,7 @@ \noexpand\edef\noexpand\xtextface {\currentbodyfontdimension\s!x }% \noexpand\edef\noexpand\xxtextface {\currentbodyfontdimension\s!xx }% }% - \global\expandafter\let\csname\??fontbodyfaces\fontbody\endcsname\font_basics_set_faces} + \expandafter\glet\csname\??fontbodyfaces\fontbody\endcsname\font_basics_set_faces} % \def\currentbodyfontdimension#parameter% % {\the\dimexpr @@ -2505,15 +2499,15 @@ %D \stoptyping % \unexpanded\def\usebodyfont[#1]% -% {\pushmacro\fontclass +% {\push_macro_fontclass % \switchtobodyfont[#1]% -% \popmacro\fontclass +% \pop_macro_fontclass % \ifx\fontclass\empty\else\setupbodyfont\relax\fi} % \unexpanded\def\usebodyfont[#1]% -% {\pushmacro\fontclass +% {\push_macro_fontclass % \font_helpers_set_font\zerocount{#1}% -% \popmacro\fontclass +% \pop_macro_fontclass % \ifx\fontclass\empty \else % \font_basics_setupbodyfont_nop % \fi} @@ -2716,7 +2710,7 @@ \unexpanded\def\font_basics_predefine#1#2% {\font_basics_defined_font_yes[#2]% - \global\expandafter\let\csname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname} + \expandafter\glet\csname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname} \unexpanded\def\font_basics_predefined#1% {\font_basics_predefine{\??predefinedfont#1}{#1}} @@ -2763,7 +2757,26 @@ \expandafter\getprivatechar \fi} -% new +%D Some fonts can have color specifiers: +%D +%D \starttyping +%D \definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes] +%D \definefontsynonym[emoji][seguiemj*seguiemj-cl] +%D +%D \definecolor[emoji-red] [r=.4] +%D \definecolor[emoji-gray][s=1,t=.5,a=1] +%D +%D %definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] % bad +%D \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] % okay +%D +%D \definefontfeature[seguiemj-r][ccmp=yes,dist=yes,colr=emoji-r] +%D +%D \definefont[MyEmojiR][seguiemj*seguiemj-r @ 100pt] +%D +%D \startTEXpage[offset=10pt] +%D \MyEmojiR\resolvedemoji{triangular ruler} +%D \stopTEXpage +%D \stoptyping \unexpanded\def\definefontcolorpalette {\dodoubleargument\font_define_color_palette} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi index 24ab687817a..3cff8175161 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi @@ -26,22 +26,27 @@ % the otf font loader: +% helpers + + \registerctxluafile{font-otr}{optimize} % opentype fontloader \registerctxluafile{font-web}{} % opentype fontloader \registerctxluafile{font-cff}{optimize} % quadratic outlines \registerctxluafile{font-ttf}{optimize} % cubic outlines \registerctxluafile{font-dsp}{optimize} % ... for this one \registerctxluafile{font-hsh}{} % hashes used by context -\registerctxluafile{font-nod}{} +\registerctxluafile{font-vfc}{} +\registerctxluafile{font-prv}{} % needs hashes +\registerctxluafile{font-nod}{optimize} \registerctxluafile{font-oti}{} % otf initialization \registerctxluafile{font-ott}{} % otf tables (first) \registerctxluafile{font-otl}{} \registerctxluafile{font-oto}{} -\registerctxluafile{font-otj}{} +\registerctxluafile{font-otj}{optimize} \registerctxluafile{font-oup}{} \registerctxluafile{font-ota}{} -\registerctxluafile{font-ots}{} -\registerctxluafile{font-otd}{} +\registerctxluafile{font-ots}{optimize} +\registerctxluafile{font-otd}{optimize} \registerctxluafile{font-otc}{} \registerctxluafile{font-oth}{} \registerctxluafile{font-osd}{} @@ -55,7 +60,12 @@ % tfm -\registerctxluafile{font-tfm}{} +\doifelsefileexists {font-tpk.lua} { + \registerctxluafile{font-tpk}{optimize} + \registerctxluafile{font-tfm}{} +} { + \registerctxluafile{font-tfm}{} +} % name database @@ -87,7 +97,28 @@ \registerctxluafile{font-def}{} \registerctxluafile{font-ctx}{} % after def as it overloads -\registerctxluafile{font-ext}{} +% extensions, order matters + +\registerctxluafile{font-imp-ligatures}{} +\registerctxluafile{font-imp-tex}{} +\registerctxluafile{font-imp-reorder}{} +\registerctxluafile{font-imp-properties}{} +\registerctxluafile{font-imp-unicode}{} +\registerctxluafile{font-imp-math}{} +\registerctxluafile{font-imp-notused}{} +\registerctxluafile{font-imp-effects}{} +\registerctxluafile{font-imp-quality}{} +\registerctxluafile{font-imp-italics}{} +\registerctxluafile{font-imp-dimensions}{} + +\doifelsefileexists{font-imp-scripts.lua} { + \registerctxluafile{font-imp-scripts}{} +} { + % not yet, lmtx feature +} + +\registerctxluafile{font-imp-tracing}{} % comes last! + \registerctxluafile{font-fbk}{} \registerctxluafile{font-aux}{} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-map.lua b/Master/texmf-dist/tex/context/base/mkiv/font-map.lua index 66cf2db3996..d931b822e55 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-map.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-map.lua @@ -168,44 +168,73 @@ local function tounicode16sequence(unicodes) return concat(t) end -local function tounicode(unicode) - if type(unicode) == "table" then - local t = { } - for l=1,#unicode do - local u = unicode[l] - if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then - t[l] = f_single(u) - else - u = u - 0x10000 - t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) - end - end - return concat(t) - else - if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then - return f_single(unicode) - else - unicode = unicode - 0x10000 - return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) - end - end -end +-- local function tounicode(unicode) +-- if type(unicode) == "table" then +-- local t = { } +-- for l=1,#unicode do +-- local u = unicode[l] +-- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then +-- t[l] = f_single(u) +-- else +-- u = u - 0x10000 +-- t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) +-- end +-- end +-- return concat(t) +-- else +-- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then +-- return f_single(unicode) +-- else +-- unicode = unicode - 0x10000 +-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) +-- end +-- end +-- end --- no real gain on runs +local unknown = f_single(0xFFFD) --- local hash = table.setmetatableindex(function(t,u) +-- local function tounicode(unicode) +-- if type(unicode) == "table" then +-- local t = { } +-- for l=1,#unicode do +-- t[l] = tounicode(unicode[l]) +-- end +-- return concat(t) +-- elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then +-- return unknown +-- elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then +-- return unknown +-- elseif unicode >= 0x100000 and unicode <= 0x10FFFF then +-- return unknown +-- elseif unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then +-- return f_single(unicode) +-- else +-- unicode = unicode - 0x10000 +-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) +-- end +-- end + +-- local hash = table.setmetatableindex(function(t,k) -- local v --- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then --- v = f_single(u) +-- if k >= 0x00E000 and k <= 0x00F8FF then +-- v = unknown +-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then +-- v = unknown +-- elseif k >= 0x100000 and k <= 0x10FFFF then +-- v = unknown +-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then +-- v = f_single(k) -- else --- u = u - 0x10000 --- v = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) +-- local k = k - 0x10000 +-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) -- end --- t[u] = v +-- t[k] = v -- return v -- end) -- --- local function tounicode(unicode,name) +-- table.makeweak(hash) +-- +-- local function tounicode(unicode) -- if type(unicode) == "table" then -- local t = { } -- for l=1,#unicode do @@ -217,6 +246,69 @@ end -- end -- end +local hash = { } +local conc = { } + +-- table.makeweak(hash) + +-- table.setmetatableindex(hash,function(t,k) +-- if type(k) == "table" then +-- local n = #k +-- for l=1,n do +-- conc[l] = hash[k[l]] +-- end +-- return concat(conc,"",1,n) +-- end +-- local v +-- if k >= 0x00E000 and k <= 0x00F8FF then +-- v = unknown +-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then +-- v = unknown +-- elseif k >= 0x100000 and k <= 0x10FFFF then +-- v = unknown +-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then +-- v = f_single(k) +-- else +-- local k = k - 0x10000 +-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) +-- end +-- t[k] = v +-- return v +-- end) +-- +-- local function tounicode(unicode) +-- return hash[unicode] +-- end + +table.setmetatableindex(hash,function(t,k) + if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then + v = f_single(k) + else + local k = k - 0x10000 + v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) + end + t[k] = v + return v +end) + +local function tounicode(k) + if type(k) == "table" then + local n = #k + for l=1,n do + conc[l] = hash[k[l]] + end + return concat(conc,"",1,n) + elseif k >= 0x00E000 and k <= 0x00F8FF then + return unknown + elseif k >= 0x0F0000 and k <= 0x0FFFFF then + return unknown + elseif k >= 0x100000 and k <= 0x10FFFF then + return unknown + else + return hash[k] + end +end + local function fromunicode16(str) if #str == 4 then return tonumber(str,16) @@ -431,7 +523,8 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) glyph.unicode = unicode end else - local t, n = { }, 0 + local t = { } + local n = 0 for l=1,nsplit do local base = split[l] local u = unicodes[base] or unicodevector[base] or contextvector[name] @@ -487,12 +580,17 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) missing[du] = true nofmissing = nofmissing + 1 end + else + -- maybe a message or so end end else local overload = overloads[du] if overload then glyph.unicode = overload.unicode + elseif not glyph.unicode then + missing[du] = true + nofmissing = nofmissing + 1 end end end diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-mat.mkvi b/Master/texmf-dist/tex/context/base/mkiv/font-mat.mkvi index 0134f3fe616..64810d3272a 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-mat.mkvi +++ b/Master/texmf-dist/tex/context/base/mkiv/font-mat.mkvi @@ -263,12 +263,12 @@ \fi} \def\font_helpers_bidirectional_mathstrategy_nop_changed - {\textfont \c_font_fam_mr_rl\textfont \c_font_fam_mr - \scriptfont \c_font_fam_mr_rl\scriptfont \c_font_fam_mr - \scriptscriptfont\c_font_fam_mr_rl\scriptscriptfont\c_font_fam_mr - \textfont \c_font_fam_mr_lr\textfont \c_font_fam_mr + {\textfont \c_font_fam_mr_lr\textfont \c_font_fam_mr \scriptfont \c_font_fam_mr_lr\scriptfont \c_font_fam_mr - \scriptscriptfont\c_font_fam_mr_lr\scriptscriptfont\c_font_fam_mr} + \scriptscriptfont\c_font_fam_mr_lr\scriptscriptfont\c_font_fam_mr + \textfont \c_font_fam_mr_rl\textfont \c_font_fam_mr + \scriptfont \c_font_fam_mr_rl\scriptfont \c_font_fam_mr + \scriptscriptfont\c_font_fam_mr_rl\scriptscriptfont\c_font_fam_mr} \appendtoks \ifconditional\c_font_bidirectional_mathstrategy @@ -313,12 +313,12 @@ {\textfont \c_font_fam_mb \textfont \c_font_fam_mr \scriptfont \c_font_fam_mb \scriptfont \c_font_fam_mr \scriptscriptfont\c_font_fam_mb \scriptscriptfont\c_font_fam_mr - \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mr_rl - \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mr_rl - \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mr_rl \textfont \c_font_fam_mb_lr\textfont \c_font_fam_mr_lr \scriptfont \c_font_fam_mb_lr\scriptfont \c_font_fam_mr_lr - \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mr_lr} + \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mr_lr + \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mr_rl + \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mr_rl + \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mr_rl} \def\font_helpers_apply_complete_bold_mathstrategy {\ifconditional\c_font_complete_bold_mathstrategy @@ -425,13 +425,16 @@ \ifdefined\mathdefault \else \let\mathdefault\relax \fi +\newconditional\c_math_bold + \unexpanded\def\mr % math regular {\ifmmode \font_helpers_synchronize_math_family_mr \else \font_helpers_set_current_font_alternative\s!mr \fi - \mathdefault} + \mathdefault + \setfalse\c_math_bold} \unexpanded\def\mb % math bold {\ifmmode @@ -439,12 +442,17 @@ \else \font_helpers_set_current_font_alternative\s!mb \fi - \mathdefault} + \mathdefault + \settrue\c_math_bold} \appendtoks \font_helpers_synchronize_math_family % auto bold \to \everymathematics +\appendtoks + \ifconditional\c_math_bold\mb\fi +\to \everymathematics + %D \macros %D {bigmath,nobigmath} %D diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-mis.lua b/Master/texmf-dist/tex/context/base/mkiv/font-mis.lua index e1f158c83b7..c75b9298454 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-mis.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-mis.lua @@ -8,20 +8,20 @@ if not modules then modules = { } end modules ['font-mis'] = { fonts = fonts or { } -fonts.helpers = fonts.helpers or { } -local helpers = fonts.helpers +local helpers = fonts.helpers or { } +fonts.helpers = helpers -fonts.handlers = fonts.handlers or { } -local handlers = fonts.handlers +local handlers = fonts.handlers or { } +fonts.handlers = handlers -handlers.otf = handlers.otf or { } -local otf = handlers.otf +local otf = handlers.otf or { } +handlers.otf = otf local readers = otf.readers if readers then - otf.version = otf.version or 3.103 + otf.version = otf.version or 3.107 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-mps.lua b/Master/texmf-dist/tex/context/base/mkiv/font-mps.lua index cde34f2ae22..89583595826 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-mps.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-mps.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['font-mps'] = { license = "see context related readme files" } +local tostring = tostring local concat = table.concat local formatters = string.formatters @@ -35,6 +36,17 @@ local f_draw = formatters["draw %s;"] local f_boundingbox = formatters["((%.6F,%.6F)--(%.6F,%.6F)--(%.6F,%.6F)--(%.6F,%.6F)--cycle)"] local f_vertical = formatters["((%.6F,%.6F)--(%.6F,%.6F))"] +directives.register("metapost.stripzeros", function() + + f_moveto = formatters["(%.6N,%.6N)"] + f_lineto = formatters["--(%.6N,%.6N)"] + f_curveto = formatters["..controls(%.6N,%.6N)and(%.6N,%.6N)..(%.6N,%.6N)"] + + f_boundingbox = formatters["((%.6N,%.6N)--(%.6N,%.6N)--(%.6N,%.6N)--(%.6N,%.6N)--cycle)"] + f_vertical = formatters["((%.6N,%.6N)--(%.6N,%.6N))"] + +end) + function metapost.boundingbox(d,factor) local bounds = d.boundingbox local factor = factor or 1 @@ -97,9 +109,12 @@ function metapost.paths(d,xfactor,yfactor) elseif operator =="q" then -- "quadraticto" size = size + 1 -- first is always a moveto - local l_x, l_y = xfactor*sequence[i-2], yfactor*sequence[i-1] - local m_x, m_y = xfactor*sequence[i+1], yfactor*sequence[i+2] - local r_x, r_y = xfactor*sequence[i+3], yfactor*sequence[i+4] + local l_x = xfactor*sequence[i-2] + local l_y = yfactor*sequence[i-1] + local m_x = xfactor*sequence[i+1] + local m_y = yfactor*sequence[i+2] + local r_x = xfactor*sequence[i+3] + local r_y = yfactor*sequence[i+4] path[size] = f_curveto ( l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), @@ -137,9 +152,12 @@ function metapost.paths(d,xfactor,yfactor) size = size + 1 -- first is always a moveto local prev = segments[i-1] - local l_x, l_y = xfactor*prev[#prev-2], yfactor*prev[#prev-1] - local m_x, m_y = xfactor*segment[1], yfactor*segment[2] - local r_x, r_y = xfactor*segment[3], yfactor*segment[4] + local l_x = xfactor*prev[#prev-2] + local l_y = yfactor*prev[#prev-1] + local m_x = xfactor*segment[1] + local m_y = yfactor*segment[2] + local r_x = xfactor*segment[3] + local r_y = yfactor*segment[4] path[size] = f_curveto ( l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), @@ -196,7 +214,10 @@ function metapost.maxbounds(data,index,factor) local boundingbox = glyph.boundingbox local xmin, ymin, xmax, ymax if not maxbounds then - xmin, ymin, xmax, ymax = 0, 0, 0, 0 + xmin = 0 + ymin = 0 + xmax = 0 + ymax = 0 for i=1,#glyphs do local d = glyphs[i] if d then @@ -240,45 +261,52 @@ end -- right time. It's probably why I like watching https://www.youtube.com/watch?v=c5FqpddnJmc -- so much: precisely (and perfectly) timed too. -local nodecodes = nodes.nodecodes -- no nuts yet - -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local rule_code = nodecodes.rule - -local normal_rule = nodes.rulecodes.normal - -local nuts = nodes.nuts -local getnext = nuts.getnext -local getid = nuts.getid -local getlist = nuts.getlist -local getchar = nuts.getchar -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getfield = nuts.getfield -local getbox = nuts.getbox -local getwhd = nuts.getwhd -local getkern = nuts.getkern -local getshift = nuts.getshift -local getwidth = nuts.getwidth -local getheight = nuts.getheight -local getdepth = nuts.getdepth - -local effective_glue = nuts.effective_glue - -local characters = fonts.hashes.characters -local parameters = fonts.hashes.parameters -local shapes = fonts.hashes.shapes -local topaths = metapost.paths - -local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6F,%.6F)(%,t);"] -local f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6F,%.6F,%.6F,%.6F);"] -local f_bounds = formatters["checkbounds(%.6F,%.6F,%.6F,%.6F);"] -local s_nothing = "(origin scaled 10)" +local nodecodes = nodes.nodecodes -- no nuts yet +local rulecodes = nodes.rulecodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule + +local normalrule_code = rulecodes.normal + +local nuts = nodes.nuts +local getnext = nuts.getnext +local getid = nuts.getid +local getlist = nuts.getlist +local getsubtype = nuts.getsubtype +local getfield = nuts.getfield +local getbox = nuts.getbox +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth +local getexpansion = nuts.getexpansion +local isglyph = nuts.isglyph + +local effective_glue = nuts.effective_glue + +local characters = fonts.hashes.characters +local parameters = fonts.hashes.parameters +local shapes = fonts.hashes.shapes +local topaths = metapost.paths + +local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6F,%.6F,%q)(%,t);"] +local f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6F,%.6F,%.6F,%.6F);"] +local f_bounds = formatters["checkbounds(%.6F,%.6F,%.6F,%.6F);"] +local s_nothing = "(origin scaled 10)" + +directives.register("metapost.stripzeros", function() + f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6N,%.6N,%q)(%,t);"] + f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6N,%.6N,%.6N,%.6N);"] + f_bounds = formatters["checkbounds(%.6N,%.6N,%.6N,%.6N);"] +end) local sc = 10 local fc = number.dimenfactors.bp * sc / 10 @@ -302,13 +330,14 @@ function metapost.output(kind,font,char,advance,shift,ex) local advance = advance or 0 local exfactor = ex or 0 local wfactor = 1 + local detail = kind == "p" and tostring(char) or "" if exfactor ~= 0 then wfactor = (1+(ex/units)/1000) xfactor = xfactor * wfactor end local paths = topaths(glyf,xfactor,yfactor) if paths then - local code = f_code(kind,#paths,advance,shift,paths) + local code = f_code(kind,#paths,advance,shift,detail,paths) return code, character.width * fc * wfactor else return "", 0 @@ -337,9 +366,9 @@ function fonts.metapost.boxtomp(n,kind) horizontal = function(parent,current,xoffset,yoffset) local dx = 0 while current do - local id = getid(current) - if id == glyph_code then - local code, width = metapost.output(kind,getfont(current),getchar(current),xoffset+dx,yoffset,getfield(current,"expansion_factor")) + local char, id = isglyph(current) + if char then + local code, width = metapost.output(kind,id,char,xoffset+dx,yoffset,getexpansion(current)) result[#result+1] = code dx = dx + width elseif id == disc_code then @@ -374,7 +403,7 @@ function fonts.metapost.boxtomp(n,kind) dp = getdepth(parent) end local hd = (ht + dp) * fc - if hd ~= 0 and getsubtype(current) == normal_rule then + if hd ~= 0 and getsubtype(current) == normalrule_code then result[#result+1] = f_rule(kind,xoffset+dx+wd/2,yoffset+hd/2,wd,hd) end dx = dx + wd diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-nod.lua b/Master/texmf-dist/tex/context/base/mkiv/font-nod.lua index 2670a924bbf..a0eb88a252c 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-nod.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-nod.lua @@ -32,6 +32,10 @@ nodes.tasks = tasks local handlers = nodes.handlers or { } nodes.handlers = handlers +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + local injections = nodes.injections or { } nodes.injections = injections @@ -52,23 +56,17 @@ local kern_code = nodecodes.kern local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getfont = nuts.getfont local getsubtype = nuts.getsubtype -local getchar = nuts.getchar local getlist = nuts.getlist local getdisc = nuts.getdisc -local getcomponents = nuts.getcomponents local isglyph = nuts.isglyph local getkern = nuts.getkern -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getwidth = nuts.getwidth local setbox = nuts.setbox @@ -78,10 +76,11 @@ local setsubtype = nuts.setsubtype local copy_node_list = nuts.copy_list local hpack_node_list = nuts.hpack local flush_node_list = nuts.flush_list -local traverse_nodes = nuts.traverse ------ traverse_id = nuts.traverse_id local protect_glyphs = nuts.protect_glyphs +local nextnode = nuts.traversers.node +local nextglyph = nuts.traversers.glyph + local nodepool = nuts.pool local new_glyph = nodepool.glyph @@ -98,11 +97,8 @@ local fontparameters = hashes.parameters local properties = nodes.properties.data --- direct.set_properties_mode(true,false) --- direct.set_properties_mode(true,true) -- default - local function freeze(h,where) - for n in traverse_nodes(tonut(h)) do -- todo: disc but not traced anyway + for n in nextnode, h do -- todo: disc but not traced anyway local p = properties[n] if p then local i = p.injections if i then p.injections = fastcopy(i) end @@ -115,15 +111,15 @@ local function freeze(h,where) end function char_tracers.collect(head,list,tag,n) - head = tonut(head) n = n or 0 - local ok, fn = false, nil + local ok = false + local fn = nil while head do - local c, id = isglyph(head) - if c then - local f = getfont(head) - if f ~= fn then - ok, fn = false, f + local char, id = isglyph(head) + if char then + local font = id + if font ~= fn then + ok, fn = false, font end if not ok then ok = true @@ -132,23 +128,23 @@ function char_tracers.collect(head,list,tag,n) list[n][tag] = { } end local l = list[n][tag] - -- l[#l+1] = { c, f, i } - l[#l+1] = { c, f } + -- l[#l+1] = { char, font, i } + l[#l+1] = { char, font } elseif id == disc_code then -- skip -- local pre, post, replace = getdisc(head) -- if replace then - -- for n in traverse_id(glyph_code,replace) do + -- for n in nextglyph, replace do -- l[#l+1] = { c, f } -- end -- end -- if pre then - -- for n in traverse_id(glyph_code,pre) do + -- for n in nextglyph, pre do -- l[#l+1] = { c, f } -- end -- end -- if post then - -- for n in traverse_id(glyph_code,post) do + -- for n in nextglyph, post do -- l[#l+1] = { c, f } -- end -- end @@ -164,7 +160,8 @@ function char_tracers.equal(ta, tb) return false else for i=1,#ta do - local a, b = ta[i], tb[i] + local a = ta[i] + local b = tb[i] -- if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then if a[1] ~= b[1] or a[2] ~= b[2] then return false @@ -221,12 +218,12 @@ function char_tracers.start() function handlers.characters(head) local n = #list char_tracers.collect(head,list,'before',n) - local h, d = npc(tonode(head)) -- for the moment tonode + head = npc(head) -- for the moment tonode char_tracers.collect(head,list,'after',n) if #list > n then list[#list+1] = { } end - return h, d + return head end function char_tracers.stop() tracers.list['characters'] = list @@ -297,47 +294,44 @@ end function step_tracers.features() -- we cannot use first_glyph here as it only finds characters with subtype < 256 local f = collection[1] - while f do - if getid(f) == glyph_code then - local tfmdata = fontidentifiers[getfont(f)] - local features = tfmdata.resources.features - local result_1 = { } - local result_2 = { } - local gpos = features and features.gpos or { } - local gsub = features and features.gsub or { } - for feature, value in table.sortedhash(tfmdata.shared.features) do - if feature == "number" or feature == "features" then - value = false - elseif type(value) == "boolean" then - if value then - value = "yes" - else - value = false - end - else - -- use value - end + for n, char, font in nextglyph, f do + local tfmdata = fontidentifiers[font] + local features = tfmdata.resources.features + local result_1 = { } + local result_2 = { } + local gpos = features and features.gpos or { } + local gsub = features and features.gsub or { } + for feature, value in table.sortedhash(tfmdata.shared.features) do + if feature == "number" or feature == "features" then + value = false + elseif type(value) == "boolean" then if value then - if gpos[feature] or gsub[feature] or feature == "language" or feature == "script" then - result_1[#result_1+1] = formatters["%s=%s"](feature,value) - else - result_2[#result_2+1] = formatters["%s=%s"](feature,value) - end + value = "yes" + else + value = false end - end - if #result_1 > 0 then - context("{\\bf[basic:} %, t{\\bf]} ",result_1) else - context("{\\bf[}no basic features{\\bf]} ") + -- use value end - if #result_2 > 0 then - context("{\\bf[extra:} %, t{\\bf]}",result_2) - else - context("{\\bf[}no extra features{\\bf]}") + if value then + if gpos[feature] or gsub[feature] or feature == "language" or feature == "script" then + result_1[#result_1+1] = formatters["%s=%s"](feature,value) + else + result_2[#result_2+1] = formatters["%s=%s"](feature,value) + end end - return end - f = getnext(f) + if #result_1 > 0 then + context("{\\bf[basic:} %, t{\\bf]} ",result_1) + else + context("{\\bf[}no basic features{\\bf]} ") + end + if #result_2 > 0 then + context("{\\bf[extra:} %, t{\\bf]}",result_2) + else + context("{\\bf[}no extra features{\\bf]}") + end + return end end @@ -349,21 +343,15 @@ end function step_tracers.font(command) local c = collection[1] - while c do - local id = getid(c) - if id == glyph_code then - local font = getfont(c) - local name = file.basename(fontproperties[font].filename or "unknown") - local size = fontparameters[font].size or 0 - if command then - context[command](font,name,size) -- size in sp - else - context("[%s: %s @ %p]",font,name,size) - end - return + for n, char, font in nextglyph, c do + local name = file.basename(fontproperties[font].filename or "unknown") + local size = fontparameters[font].size or 0 + if command then + context[command](font,name,size) -- size in sp else - c = getnext(c) + context("[%s: %s @ %p]",font,name,size) end + return end end @@ -376,9 +364,7 @@ local colors = { function step_tracers.codes(i,command,space) local c = collection[i] - local function showchar(c) - local f = getfont(c) - local c = getchar(c) + local function showchar(c,f) if command then local d = fontdescriptions[f] local d = d and d[c] @@ -392,10 +378,10 @@ function step_tracers.codes(i,command,space) if w then context.startcolor(colors[what]) context("%s:",what) - for c in traverse_nodes(w) do - local id = getid(c) + for c, id in nextnode, w do if id == glyph_code then - showchar(c) + local c, f = isglyph(c) + showchar(c,f) else context("[%s]",nodecodes[id]) end @@ -406,11 +392,11 @@ function step_tracers.codes(i,command,space) end while c do - local id = getid(c) - if id == glyph_code then - showchar(c) - elseif id == dir_code or id == localpar_code then - context("[%s]",getdir(c)) + local char, id = isglyph(c) + if char then + showchar(char,id) + elseif id == dir_code or (id == localpar_code and getsubtype(c) == 0) then + context("[%s]",getdirection(c) or "?") elseif id == disc_code then local pre, post, replace = getdisc(c) if pre or post or replace then @@ -453,13 +439,12 @@ end function step_tracers.check(head) if collecting then step_tracers.reset() - local h = tonut(head) - local n = copy_node_list(h) + local n = copy_node_list(head) freeze(n,"check") - injections.keepcounts(n) -- one-time + injections.keepcounts() -- one-time local l = injections.handler(n,"trace") if l then -- hm, can be false - n = tonut(l) + n = l end protect_glyphs(n) collection[1] = n @@ -470,13 +455,12 @@ function step_tracers.register(head) if collecting then local nc = #collection+1 if messages[nc] then - local h = tonut(head) - local n = copy_node_list(h) + local n = copy_node_list(head) freeze(n,"register") - injections.keepcounts(n) -- one-time + injections.keepcounts() -- one-time local l = injections.handler(n,"trace") if l then -- hm, can be false - n = tonut(l) + n = l end protect_glyphs(n) collection[nc] = n @@ -501,14 +485,11 @@ local threshold = 65536 -- 1pt local function toutf(list,result,nofresult,stopcriterium,nostrip) if list then - for n in traverse_nodes(tonut(list)) do - local c, id = isglyph(n) - if c then - local components = getcomponents(n) - if components then - result, nofresult = toutf(components,result,nofresult,false,true) - elseif c > 0 then - local fc = fontcharacters[getfont(n)] + for n, id in nextnode, tonut(list) do + if id == glyph_code then + local c, f = isglyph(n) + if c > 0 then + local fc = fontcharacters[f] if fc then local fcc = fc[c] if fcc then diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua b/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua index b17cf991d80..0976cdb21c0 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua @@ -13,13 +13,20 @@ local round, max = math.round, math.round local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash local setmetatableindex = table.setmetatableindex -local formatters = string.formatters -local tounicode = fonts.mappings.tounicode +local formatters = string.formatters +local tounicode = fonts.mappings.tounicode -local otf = fonts.handlers.otf +local helpers = fonts.helpers -local f_color = formatters["%.3f %.3f %.3f rg"] -local f_gray = formatters["%.3f g"] +local charcommand = helpers.commands.char +local rightcommand = helpers.commands.right +local leftcommand = helpers.commands.left +local downcommand = helpers.commands.down + +local otf = fonts.handlers.otf + +local f_color = formatters["%.3f %.3f %.3f rg"] +local f_gray = formatters["%.3f g"] if context then @@ -56,31 +63,41 @@ end) if context then + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] -- looks bad + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] -- looks okay + local colors = attributes.list[attributes.private('color')] or { } local transparencies = attributes.list[attributes.private('transparency')] or { } function otf.registerpalette(name,values) sharedpalettes[name] = values + local color = lpdf.color + local transparency = lpdf.transparency + local register = colors.register for i=1,#values do local v = values[i] - local c = nil - local t = nil - if type(v) == "table" then - c = colors.register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) + if v == "textcolor" then + values[i] = false else - c = colors[v] - t = transparencies[v] - end - if c and t then - values[i] = hash[lpdf.color(1,c) .. " " .. lpdf.transparency(t)] - elseif c then - values[i] = hash[lpdf.color(1,c)] - elseif t then - values[i] = hash[lpdf.color(1,t)] + local c = nil + local t = nil + if type(v) == "table" then + c = register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c = colors[v] + t = transparencies[v] + end + if c and t then + values[i] = hash[color(1,c) .. " " .. transparency(t)] + elseif c then + values[i] = hash[color(1,c)] + elseif t then + values[i] = hash[color(1,t)] + end end end end @@ -91,11 +108,13 @@ else -- for generic sharedpalettes[name] = values for i=1,#values do local v = values[i] - values[i] = hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] + if v then + values[i] = hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end end end @@ -127,16 +146,11 @@ local start = { "pdf", "mode", "font" } -- force text mode (so get q Q right) local push = { "pdf", "page", "q" } local pop = { "pdf", "page", "Q" } -if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY < 6472 then - start = { "nop" } - ----- = stop -end - -- -- This one results in color directives inside BT ET but has less q Q pairs. It -- -- only shows the first glyph in acrobat and nothing more. No problem with other -- -- renderers. -- --- local function initializecolr(tfmdata,kind,value) -- hm, always value +-- local function initialize(tfmdata,kind,value) -- hm, always value -- if value then -- local resources = tfmdata.resources -- local palettes = resources.colorpalettes @@ -161,11 +175,6 @@ end -- tfmdata.fonts = { -- { id = 0 } -- } --- local widths = setmetatableindex(function(t,k) --- local v = { "right", -k } --- t[k] = v --- return v --- end) -- -- -- local getactualtext = otf.getactualtext -- local default = colorvalues[#colorvalues] @@ -173,12 +182,6 @@ end -- local actualb = { "pdf", "page", b } -- saves tables -- local actuale = { "pdf", "page", e } -- saves tables -- -- --- local cache = setmetatableindex(function(t,k) --- local v = { "char", k } -- could he a weak shared hash --- t[k] = v --- return v --- end) --- -- -- for unicode, character in next, characters do -- local description = descriptions[unicode] -- if description then @@ -187,7 +190,7 @@ end -- local u = description.unicode or characters[unicode].unicode -- local w = character.width or 0 -- local s = #colorlist --- local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same +-- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same -- local t = { -- start, -- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } @@ -202,7 +205,7 @@ end -- n = n + 1 t[n] = v -- l = v -- end --- n = n + 1 t[n] = cache[entry.slot] +-- n = n + 1 t[n] = charcommand[entry.slot] -- if s > 1 and i < s and goback then -- n = n + 1 t[n] = goback -- end @@ -221,7 +224,7 @@ end -- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat -- -- fails displaying the overlays correctly. Other renderers do it right. -local function initializecolr(tfmdata,kind,value) -- hm, always value +local function initialize(tfmdata,kind,value) if value then local resources = tfmdata.resources local palettes = resources.colorpalettes @@ -232,8 +235,14 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value converted = setmetatableindex(convert) resources.converted = converted end - local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { } - local classes = #colorvalues + local colorvalues = sharedpalettes[value] + local default = false -- so the text color (bad for icon overloads) + if colorvalues then + default = colorvalues[#colorvalues] + else + colorvalues = converted[palettes[tonumber(value) or 1] or palettes[1]] or { } + end + local classes = #colorvalues if classes == 0 then return end @@ -246,24 +255,12 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value tfmdata.fonts = { { id = 0 } } - local widths = setmetatableindex(function(t,k) - local v = { "right", -k } - t[k] = v - return v - end) -- local getactualtext = otf.getactualtext - local default = colorvalues[#colorvalues] local b, e = getactualtext(tounicode(0xFFFD)) local actualb = { "pdf", "page", b } -- saves tables local actuale = { "pdf", "page", e } -- saves tables -- - local cache = setmetatableindex(function(t,k) - local v = { "char", k } -- could he a weak shared hash - t[k] = v - return v - end) - -- for unicode, character in next, characters do local description = descriptions[unicode] if description then @@ -272,7 +269,7 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value local u = description.unicode or characters[unicode].unicode local w = character.width or 0 local s = #colorlist - local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same + local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same local t = { start, -- really needed not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } @@ -291,8 +288,14 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value f = true n = n + 1 t[n] = v l = v + else + if f then + n = n + 1 t[n] = pop + end + f = false + l = nil end - n = n + 1 t[n] = cache[entry.slot] + n = n + 1 t[n] = charcommand[entry.slot] if s > 1 and i < s and goback then n = n + 1 t[n] = goback end @@ -314,80 +317,60 @@ fonts.handlers.otf.features.register { name = "colr", description = "color glyphs", manipulators = { - base = initializecolr, - node = initializecolr, + base = initialize, + node = initialize, } } do - -- local f_setstream = formatters[ [[io.savedata("svg-glyph-%05i",%q)]] ] - -- local f_getstream = formatters[ [[svg-glyph-%05i]] ] - - -- function otfsvg.storepdfdata(pdf) - -- nofstreams = nofstreams + 1 - -- storepdfdata = function(pdf) - -- nofstreams = nofstreams + 1 - -- return f_setstream(nofstreams,pdf), f_getstream(nofstreams) - -- end - -- end - local nofstreams = 0 local f_name = formatters[ [[pdf-glyph-%05i]] ] local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ] local hashed = { } local cache = { } - function otf.storepdfdata(pdf) - local done = hashed[pdf] - if not done then - nofstreams = nofstreams + 1 - local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams)) - cache[n] = o -- we need to keep in mem - done = f_used(n) - hashed[pdf] = done + if epdf then + + local openpdf = epdf.openMemStream + + function otf.storepdfdata(pdf) + local done = hashed[pdf] + if not done then + nofstreams = nofstreams + 1 + local o, n = openpdf(pdf,#pdf,f_name(nofstreams)) + cache[n] = o -- we need to keep in mem + done = f_used(n) + hashed[pdf] = done + end + return done + end + + else + + local openpdf = pdfe.new + ----- prefix = "data:application/pdf," + + function otf.storepdfdata(pdf) + local done = hashed[pdf] + if not done then + nofstreams = nofstreams + 1 + local f = f_name(nofstreams) + local n = openpdf(pdf,#pdf,f) + done = f_used(n) + hashed[pdf] = done + end + return done end - return nil, done, nil - end - -- maybe more efficient but much slower (and we hash already) - -- - -- if context then - -- - -- local storepdfdata = otf.storepdfdata - -- local initialized = false - -- - -- function otf.storepdfdata(pdf) - -- if not initialized then - -- if resolvers.setmemstream then - -- local f_setstream = formatters[ [[resolvers.setmemstream("pdf-glyph-%05i",%q,true)]] ] - -- local f_getstream = formatters[ [[memstream:///pdf-glyph-%05i]] ] - -- local f_nilstream = formatters[ [[resolvers.resetmemstream("pdf-glyph-%05i",true)]] ] - -- storepdfdata = function(pdf) - -- local done = hashed[pdf] - -- local set = nil - -- local reset = nil - -- if not done then - -- nofstreams = nofstreams + 1 - -- set = f_setstream(nofstreams,pdf) - -- done = f_getstream(nofstreams) - -- reset = f_nilstream(nofstreams) - -- hashed[pdf] = done - -- end - -- return set, done, reset - -- end - -- otf.storepdfdata = storepdfdata - -- end - -- initialized = true - -- end - -- return storepdfdata(pdf) - -- end - -- - -- end + end end -local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg +-- I'll probably make a variant for context as we can do it more efficient there than in +-- generic. + +local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg if not tfmdata or not pdfshapes or not kind then return end @@ -400,7 +383,7 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg properties.virtualized = true -- tfmdata.fonts = { - { id = 0 } + { id = 0 } -- not really needed } -- local getactualtext = otf.getactualtext @@ -410,6 +393,12 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg local actualb = { "pdf", "page", b } -- saves tables local actuale = { "pdf", "page", e } -- saves tables -- + local vfimage = lpdf and lpdf.vfimage or function(wd,ht,dp,data,name) + -- needed for generic (if used there at all) + local name = storepdfdata(data) + return { "image", { filename = name, width = wd, height = ht, depth = dp } } + end + -- for unicode, character in sortedhash(characters) do -- sort is nicer for svg local index = character.index if index then @@ -428,31 +417,30 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg dy = 0 end if data then - local setcode, name, nilcode = storepdfdata(data) - if name then - local bt = unicode and getactualtext(unicode) - local wd = character.width or 0 - local ht = character.height or 0 - local dp = character.depth or 0 - character.commands = { - not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, - { "down", dp + dy * hfactor }, - { "right", dx * hfactor }, - -- setcode and { "lua", setcode } or nop, - { "image", { filename = name, width = wd, height = ht, depth = dp } }, - -- nilcode and { "lua", nilcode } or nop, - actuale, - } - character[kind] = true - end + -- We can delay storage by a lua function in commands: but then we need to + -- be able to provide our own mem stream name (so that we can reserve it). + -- Anyway, we will do this different in a future version of context. + local bt = unicode and getactualtext(unicode) + local wd = character.width or 0 + local ht = character.height or 0 + local dp = character.depth or 0 + -- The down and right will change too (we can move that elsewhere). + character.commands = { + not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, + downcommand[dp + dy * hfactor], + rightcommand[dx * hfactor], + vfimage(wd,ht,dp,data,name), + actuale, + } + character[kind] = true end end end end local otfsvg = otf.svg or { } -otf.svg = otfsvg -otf.svgenabled = true +otf.svg = otfsvg +otf.svgenabled = true do @@ -583,27 +571,27 @@ fonts.handlers.otf.features.register { -- This can be done differently e.g. with ffi and gm and we can share code anway. Using -- batchmode in gm is not faster and as it accumulates we would need to flush all --- individual shapes. +-- individual shapes. But ... in context lmtx (and maybe the backport) we will use +-- a different and more efficient method anyway. I'm still wondering if I should +-- keep color code in generic. Maybe it should be optional. -local otfsbix = otf.sbix or { } -otf.sbix = otfsbix -otf.sbixenabled = true +local otfpng = otf.png or { } +otf.png = otfpng +otf.pngenabled = true do - -- for now png but also other bitmap formats - - local report_sbix = logs.reporter("fonts","sbix conversion") + local report_png = logs.reporter("fonts","png conversion") local loaddata = io.loaddata local savedata = io.savedata local remove = os.remove local runner = sandbox and sandbox.registerrunner { - name = "otfsbix", + name = "otfpng", program = "gm", - template = "convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", - -- reporter = report_sbix, + template = "convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + -- reporter = report_png, } if not runner then @@ -611,29 +599,29 @@ do -- poor mans variant for generic: -- runner = function() - return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") end end -- Alternatively we can create a single pdf file with -adjoin and then pick up pages from -- that file but creating thousands of small files is no fun either. - function otfsbix.topdf(sbixshapes) + function otfpng.topdf(pngshapes) local pdfshapes = { } - local sbixfile = "temp-otf-sbix-shape.sbix" - local pdffile = "temp-otf-sbix-shape.pdf" + local pngfile = "temp-otf-png-shape.png" + local pdffile = "temp-otf-png-shape.pdf" local nofdone = 0 - local indices = sortedkeys(sbixshapes) -- can be sparse + local indices = sortedkeys(pngshapes) -- can be sparse local nofindices = #indices - report_sbix("processing %i sbix containers",nofindices) + report_png("processing %i png containers",nofindices) statistics.starttiming() for i=1,nofindices do local index = indices[i] - local entry = sbixshapes[index] - local data = entry.data + local entry = pngshapes[index] + local data = entry.data -- or placeholder local x = entry.x local y = entry.y - savedata(sbixfile,data) + savedata(pngfile,data) runner() pdfshapes[index] = { x = x ~= 0 and x or nil, @@ -642,43 +630,44 @@ do } nofdone = nofdone + 1 if nofdone % 100 == 0 then - report_sbix("%i shapes processed",nofdone) + report_png("%i shapes processed",nofdone) end end - report_sbix("processing %i pdf results",nofindices) - remove(sbixfile) + report_png("processing %i pdf results",nofindices) + remove(pngfile) remove(pdffile) statistics.stoptiming() if statistics.elapsedseconds then - report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + report_png("png conversion time %s",statistics.elapsedseconds() or "-") end return pdfshapes - -- end end end -local function initializesbix(tfmdata,kind,value) -- hm, always value - if value and otf.sbixenabled then - local sbix = tfmdata.properties.sbix - local hash = sbix and sbix.hash - local timestamp = sbix and sbix.timestamp +-- This will change in a future version of context. More direct. + +local function initializepng(tfmdata,kind,value) -- hm, always value + if value and otf.pngenabled then + local png = tfmdata.properties.png + local hash = png and png.hash + local timestamp = png and png.timestamp if not hash then return end local pdffile = containers.read(otf.pdfcache,hash) local pdfshapes = pdffile and pdffile.pdfshapes if not pdfshapes or pdffile.timestamp ~= timestamp then - local sbixfile = containers.read(otf.sbixcache,hash) - local sbixshapes = sbixfile and sbixfile.sbixshapes - pdfshapes = sbixshapes and otfsbix.topdf(sbixshapes) or { } + local pngfile = containers.read(otf.pngcache,hash) + local pngshapes = pngfile and pngfile.pngshapes + pdfshapes = pngshapes and otfpng.topdf(pngshapes) or { } containers.write(otf.pdfcache, hash, { pdfshapes = pdfshapes, timestamp = timestamp, }) end -- - pdftovirtual(tfmdata,pdfshapes,"sbix") + pdftovirtual(tfmdata,pdfshapes,"png") end end @@ -686,8 +675,16 @@ fonts.handlers.otf.features.register { name = "sbix", description = "sbix glyphs", manipulators = { - base = initializesbix, - node = initializesbix, + base = initializepng, + node = initializepng, } } +fonts.handlers.otf.features.register { + name = "cblc", + description = "cblc glyphs", + manipulators = { + base = initializepng, + node = initializepng, + } +} diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-one.lua b/Master/texmf-dist/tex/context/base/mkiv/font-one.lua index a3dc7b03859..18ba5118532 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-one.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-one.lua @@ -86,14 +86,16 @@ function afm.load(filename) local name = file.removesuffix(file.basename(filename)) local data = containers.read(afm.cache,name) local attr = lfs.attributes(filename) - local size, time = attr.size or 0, attr.modification or 0 + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 -- local pfbfile = file.replacesuffix(name,"pfb") local pfbname = resolvers.findfile(pfbfile,"pfb") or "" if pfbname == "" then pfbname = resolvers.findfile(file.basename(pfbfile),"pfb") or "" end - local pfbsize, pfbtime = 0, 0 + local pfbsize = 0 + local pfbtime = 0 if pfbname ~= "" then local attr = lfs.attributes(pfbname) pfbsize = attr.size or 0 @@ -106,6 +108,7 @@ function afm.load(filename) afmenhancers.apply(data,filename) -- otfreaders.addunicodetable(data) -- only when not done yet fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) -- otfreaders.extend(data) otfreaders.pack(data) data.size = size @@ -323,7 +326,8 @@ local addthem = function(rawdata,ligatures) local one = descriptions[unicodes[ligname]] if one then for _, pair in next, ligdata do - local two, three = unicodes[pair[1]], unicodes[pair[2]] + local two = unicodes[pair[1]] + local three = unicodes[pair[2]] if two and three then local ol = one.ligatures if ol then @@ -391,7 +395,7 @@ local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust h if what then for complex, simple in next, what do complex = unicodes[complex] - simple = unicodes[simple] + simple = unicodes[simple] if complex and simple then local complexdescription = descriptions[complex] if complexdescription then -- optional @@ -444,7 +448,8 @@ local function adddimensions(data) -- we need to normalize afm to otf i.e. index for unicode, description in next, data.descriptions do local bb = description.boundingbox if bb then - local ht, dp = bb[4], -bb[2] + local ht = bb[4] + local dp = -bb[2] if ht == 0 or ht < 0 then -- no need to set it and no negative heights, nil == 0 else diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-onr.lua b/Master/texmf-dist/tex/context/base/mkiv/font-onr.lua index 26a782649f4..8523d8729ab 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-onr.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-onr.lua @@ -26,7 +26,7 @@ local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, local char, byte, sub = string.char, string.byte, string.sub local abs = math.abs local bxor, rshift = bit32.bxor, bit32.rshift -local P, S, R, Cmt, C, Ct, Cs, Carg, Cf, Cg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg +local P, S, R, V, Cmt, C, Ct, Cs, Carg, Cf, Cg, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.V, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg, lpeg.Cc local lpegmatch, patterns = lpeg.match, lpeg.patterns local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) @@ -83,31 +83,40 @@ do end - local charstrings = P("/CharStrings") - local subroutines = P("/Subrs") - local encoding = P("/Encoding") - local dup = P("dup") - local put = P("put") - local array = P("array") - local name = P("/") * C((R("az","AZ","09")+S("-_."))^1) - local digits = R("09")^1 - local cardinal = digits / tonumber - local spaces = P(" ")^1 - local spacing = patterns.whitespace^0 + local charstrings = P("/CharStrings") + local subroutines = P("/Subrs") + local encoding = P("/Encoding") + local dup = P("dup") + local put = P("put") + local array = P("array") + local name = P("/") * C((R("az","AZ","09")+S("-_."))^1) + local digits = R("09")^1 + local cardinal = digits / tonumber + local spaces = P(" ")^1 + local spacing = patterns.whitespace^0 local routines, vector, chars, n, m local initialize = function(str,position,size) n = 0 - m = size -- % tonumber(size) + m = size return position + 1 end local setroutine = function(str,position,index,size,filename) - local forward = position + tonumber(size) + if routines[index] then + -- we have passed the end + return false + end + local forward = position + size local stream = decrypt(sub(str,position+1,forward),4330,4) routines[index] = { byte(stream,1,#stream) } - return forward + n = n + 1 + if n >= m then + -- m should be index now but can we assume ordering? + return #str + end + return forward + 1 end local setvector = function(str,position,name,size,filename) @@ -152,7 +161,7 @@ do local p_filterroutines = -- dup
+
+local fromsixteen = lpdf.fromsixteen -- maybe inline the lpeg ... but not worth it
+
+local function f_bfchar(t,a,b)
+ t[tonumber(a,16)] = fromsixteen(b)
+end
+
+local function f_bfrange_1(t,a,b,c)
+ print("todo 1",a,b,c)
+ -- c is string
+ -- todo t[tonumber(a,16)] = fromsixteen(b)
+end
+
+local function f_bfrange_2(t,a,b,c)
+ print("todo 2",a,b,c)
+ -- c is table
+ -- todo t[tonumber(a,16)] = fromsixteen(b)
+end
+
+local optionals = spaces^0
+local hexstring = optionals * P("<") * C((1-P(">"))^1) * P(">")
+local bfchar = Carg(1) * hexstring * hexstring / f_bfchar
+local bfrange = Carg(1) * hexstring * hexstring * hexstring / f_bfrange_1
+ + Carg(1) * hexstring * hexstring * optionals * P("[") * Ct(hexstring^1) * optionals * P("]") / f_bfrange_2
+local fromunicode = (
+ P("beginbfchar" ) * bfchar ^1 * optionals * P("endbfchar" ) +
+ P("beginbfrange") * bfrange^1 * optionals * P("endbfrange") +
+ spaces +
+ P(1)
+)^1 * Carg(1)
+
+local function analyzefonts(document,resources) -- unfinished, see mtx-pdf for better code
+ local fonts = document.__fonts__
+ if resources then
+ local fontlist = resources.Font
+ if fontlist then
+ for id, data in expanded(fontlist) do
+ if not fonts[id] then
+ -- a quick hack ... I will look into it more detail if I find a real
+ -- -application for it
+ local tounicode = data.ToUnicode()
+ if tounicode then
+ tounicode = lpegmatch(fromunicode,tounicode,1,{})
+ end
+ fonts[id] = {
+ tounicode = type(tounicode) == "table" and tounicode or { }
+ }
+ setmetatableindex(fonts[id],"self")
+ end
+ end
+ end
+ end
+ return fonts
+end
+
+local more = 0
+local unic = nil -- cheaper than passing each time as Carg(1)
+
+local p_hex_to_utf = C(4) / function(s) -- needs checking !
+ local now = tonumber(s,16)
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong
+ more = 0
+ return unic[now] or utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ -- return ""
+ else
+ return unic[now] or utfchar(now)
+ end
+end
+
+local p_dec_to_utf = C(1) / function(s) -- needs checking !
+ local now = byte(s)
+ return unic[now] or utfchar(now)
+end
+
+local p_hex_to_utf = P(true) / function() more = 0 end * Cs(p_hex_to_utf^1)
+local p_dec_to_utf = P(true) / function() more = 0 end * Cs(p_dec_to_utf^1)
+
+function lpdf_epdf.getpagecontent(document,pagenumber)
+
+ local page = document.pages[pagenumber]
+
+ if not page then
+ return
+ end
+
+ local fonts = analyzefonts(document,page.Resources)
+
+ local content = page.Contents() or ""
+ local list = lpegmatch(parser,content)
+ local font = nil
+ -- local unic = nil
+
+ for i=1,#list do
+ local entry = list[i]
+ local size = #entry
+ local operator = entry[size]
+ if operator == "Tf" then
+ font = fonts[entry[1]]
+ unic = font.tounicode
+ elseif operator == "TJ" then -- { array, TJ }
+ local list = entry[1]
+ for i=1,#list do
+ local li = list[i]
+ if type(li) == "table" then
+ if li[1] == "hex" then
+ list[i] = lpegmatch(p_hex_to_utf,li[2])
+ else
+ list[i] = lpegmatch(p_dec_to_utf,li[2])
+ end
+ else
+ -- kern
+ end
+ end
+ elseif operator == "Tj" or operator == "'" or operator == '"' then -- { string, Tj } { string, ' } { n, m, string, " }
+ local list = entry[size-1]
+ if list[1] == "hex" then
+ list[2] = lpegmatch(p_hex_to_utf,li[2])
+ else
+ list[2] = lpegmatch(p_dec_to_utf,li[2])
+ end
+ end
+ end
+
+ unic = nil -- can be collected
+
+ return list
+
+end
+
+-- This is also an experiment. When I really need it I can improve it, for instance
+-- with proper position calculating. It might be usefull for some search or so.
+
+local softhyphen = utfchar(0xAD) .. "$"
+local linefactor = 1.3
+
+function lpdf_epdf.contenttotext(document,list) -- maybe signal fonts
+ local last_y = 0
+ local last_f = 0
+ local text = { }
+ local last = 0
+
+ for i=1,#list do
+ local entry = list[i]
+ local size = #entry
+ local operator = entry[size]
+ if operator == "Tf" then
+ last_f = entry[2]
+ elseif operator == "TJ" then
+ local list = entry[1]
+ for i=1,#list do
+ local li = list[i]
+ if type(li) == "string" then
+ last = last + 1
+ text[last] = li
+ elseif li < -50 then
+ last = last + 1
+ text[last] = " "
+ end
+ end
+ line = concat(list)
+ elseif operator == "Tj" then
+ last = last + 1
+ text[last] = entry[size-1]
+ elseif operator == "cm" or operator == "Tm" then
+ local ty = entry[6]
+ local dy = abs(last_y - ty)
+ if dy > linefactor*last_f then
+ if last > 0 then
+ if find(text[last],softhyphen,1,true) then
+ -- ignore
+ else
+ last = last + 1
+ text[last] = "\n"
+ end
+ end
+ end
+ last_y = ty
+ end
+ end
+
+ return concat(text)
+end
+
+function lpdf_epdf.getstructure(document,list) -- just a test
+ local depth = 0
+ for i=1,#list do
+ local entry = list[i]
+ local size = #entry
+ local operator = entry[size]
+ if operator == "BDC" then
+ report_epdf("%w%s : %s",depth,entry[1] or "?",entry[2] and entry[2].MCID or "?")
+ depth = depth + 1
+ elseif operator == "EMC" then
+ depth = depth - 1
+ elseif operator == "TJ" then
+ local list = entry[1]
+ for i=1,#list do
+ local li = list[i]
+ if type(li) == "string" then
+ report_epdf("%w > %s",depth,li)
+ elseif li < -50 then
+ report_epdf("%w >",depth,li)
+ end
+ end
+ elseif operator == "Tj" then
+ report_epdf("%w > %s",depth,entry[size-1])
+ end
+ end
+end
+
+if img then do
+
+ -- This can be made a bit faster (just get raw data and pass it) but I will
+ -- do that later. In the end the benefit is probably neglectable.
+
+ local recompress = false
+ local stripmarked = false
+
+ local copydictionary = nil
+ local copyarray = nil
+
+ local pdfreserveobject = lpdf.reserveobject
+ local shareobjectreference = lpdf.shareobjectreference
+ local pdfflushobject = lpdf.flushobject
+ local pdfflushstreamobject = lpdf.flushstreamobject
+ local pdfreference = lpdf.reference
+ local pdfconstant = lpdf.constant
+ local pdfarray = lpdf.array
+ local pdfdictionary = lpdf.dictionary
+ local pdfnull = lpdf.null
+ local pdfliteral = lpdf.literal
+
+ local report = logs.reporter("backend","xobjects")
+
+ local factor = 65536 / (7200/7227) -- 1/number.dimenfactors.bp
+
+ local createimage = images.create
+
+ directives.register("graphics.pdf.recompress", function(v) recompress = v end)
+ directives.register("graphics.pdf.stripmarked", function(v) stripmarked = v end)
+
+ local function scaledbbox(b)
+ return { b[1]*factor, b[2]*factor, b[3]*factor, b[4]*factor }
+ end
+
+ local codecs = {
+ ASCIIHexDecode = true,
+ ASCII85Decode = true,
+ RunLengthDecode = true,
+ FlateDecode = true,
+ LZWDecode = true,
+ }
+
+ local function deepcopyobject(xref,copied,value)
+ -- no need for tables, just nested loop with obj
+ local objnum = xref[value]
+ if objnum then
+ local usednum = copied[objnum]
+ if usednum then
+ -- report("%s object %i is reused",kind,objnum)
+ else
+ usednum = pdfreserveobject()
+ copied[objnum] = usednum
+ local entry = value
+ local kind = entry.__type__
+ if kind == array_object_code then
+ local a = copyarray(xref,copied,entry)
+ pdfflushobject(usednum,tostring(a))
+ elseif kind == dictionary_object_code then
+ local d = copydictionary(xref,copied,entry)
+ pdfflushobject(usednum,tostring(d))
+ elseif kind == stream_object_code then
+ local d = copydictionary(xref,copied,entry)
+ local filter = d.Filter
+ if filter and codecs[filter] and recompress then
+ -- recompress
+ d.Filter = nil
+ d.Length = nil
+ d.DecodeParms = nil -- relates to filter
+ d.DL = nil -- needed?
+ local s = entry() -- get uncompressed stream
+ pdfflushstreamobject(s,d,true,usednum) -- compress stream
+ else
+ -- keep as-is, even Length which indicates the
+ -- decompressed length
+ local s = entry(false) -- get compressed stream
+ -- pdfflushstreamobject(s,d,false,usednum,true) -- don't compress stream
+ pdfflushstreamobject(s,d,"raw",usednum) -- don't compress stream
+ end
+ else
+ local t = type(value)
+ if t == "string" then
+ value = pdfconstant(value)
+ elseif t == "table" then
+ local kind = value[1]
+ local entry = value[2]
+ if kind == name_object_code then
+ value = pdfconstant(entry)
+ elseif kind == string_object_code then
+ value = pdfliteral(entry,value[3])
+ elseif kind == null_object_code then
+ value = pdfnull()
+ elseif kind == reference_object_code then
+ value = deepcopyobject(xref,copied,entry)
+ else
+ value = tostring(entry)
+ end
+ end
+ pdfflushobject(usednum,value)
+ end
+ end
+ return pdfreference(usednum)
+ elseif kind == stream_object_code then
+ report("stream not done: %s", objectcodes[kind] or "?")
+ else
+ report("object not done: %s", objectcodes[kind] or "?")
+ end
+ end
+
+ local function copyobject(xref,copied,object,key,value)
+ if not value then
+ value = object.__raw__[key]
+ end
+ local t = type(value)
+ if t == "string" then
+ return pdfconstant(value)
+ elseif t ~= "table" then
+ return value
+ end
+ local kind = value[1]
+ if kind == name_object_code then
+ return pdfconstant(value[2])
+ elseif kind == string_object_code then
+ return pdfliteral(value[2],value[3])
+ elseif kind == array_object_code then
+ return copyarray(xref,copied,object[key])
+ elseif kind == dictionary_object_code then
+ return copydictionary(xref,copied,object[key])
+ elseif kind == null_object_code then
+ return pdfnull()
+ elseif kind == reference_object_code then
+ -- expand
+ return deepcopyobject(xref,copied,object[key])
+ else
+ report("weird: %s", objecttypes[kind] or "?")
+ end
+ end
+
+ copyarray = function (xref,copied,object)
+ local target = pdfarray()
+ local source = object.__raw__
+ for i=1,#source do
+ target[i] = copyobject(xref,copied,object,i,source[i])
+ end
+ return target
+ end
+
+ local plugins = nil
+
+ -- Sorting the hash slows down upto 5% bit but it is still as fast as the C
+ -- code. We could loop over the index instead but sorting might be nicer in
+ -- the end.
+
+ copydictionary = function (xref,copied,object)
+ local target = pdfdictionary()
+ local source = object.__raw__
+ -- for key, value in next, source do
+ for key, value in sortedhash(source) do
+ if plugins then
+ local p = plugins[key]
+ if p then
+ target[key] = p(xref,copied,object,key,value,copyobject) -- maybe a table of methods
+ else
+ target[key] = copyobject(xref,copied,object,key,value)
+ end
+ else
+ target[key] = copyobject(xref,copied,object,key,value)
+ end
+ end
+ return target
+ end
+
+ -- local function copyresources(pdfdoc,xref,copied,pagedata)
+ -- local Resources = pagedata.Resources
+ -- if Resources then
+ -- local r = pdfreserveobject()
+ -- local d = copydictionary(xref,copied,Resources)
+ -- pdfflushobject(r,tostring(d))
+ -- return pdfreference(r)
+ -- end
+ -- end
+
+ local function copyresources(pdfdoc,xref,copied,pagedata)
+ local Resources = pagedata.Resources
+ --
+ -- -- This needs testing:
+ --
+ -- if not Resources then
+ -- local Parent = page.Parent
+ -- while (Parent and (Parent.__type__ == dictionary_object_code or Parent.__type__ == reference_object_code) do
+ -- Resources = Parent.Resources
+ -- if Resources then
+ -- break
+ -- end
+ -- Parent = Parent.Parent
+ -- end
+ -- end
+ if Resources then
+ local d = copydictionary(xref,copied,Resources)
+ return shareobjectreference(d)
+ end
+ end
+
+ local openpdf = lpdf_epdf.load
+ local closepdf = lpdf_epdf.unload
+
+ local function newpdf(str,userpassword,ownerpassword)
+ return openpdf(str,userpassword,ownerpassword,true)
+ end
+
+ local function querypdf(pdfdoc,pagenumber)
+ if pdfdoc then
+ if not pagenumber then
+ pagenumber = 1
+ end
+ local root = pdfdoc.Catalog
+ local page = pdfdoc.pages[pagenumber]
+ if page then
+ -- todo
+ local mediabox = page.MediaBox or { 0, 0, 0, 0 }
+ local cropbox = page.CropBox or mediabox
+ return {
+ filename = pdfdoc.filename,
+ pagenumber = pagenumber,
+ nofpages = pdfdoc.nofpages,
+ boundingbox = scaledbbox(cropbox),
+ cropbox = cropbox,
+ mediabox = mediabox,
+ bleedbox = page.BleedBox or cropbox,
+ trimbox = page.TrimBox or cropbox,
+ artbox = page.ArtBox or cropbox,
+ rotation = page.Rotate or 0,
+ xsize = cropbox[3] - cropbox[1],
+ ysize = cropbox[4] - cropbox[2],
+ }
+ end
+ end
+ end
+
+ local function copypage(pdfdoc,pagenumber,attributes,compact,width,height,attr)
+ if pdfdoc then
+ local root = pdfdoc.Catalog
+ local page = pdfdoc.pages[pagenumber or 1]
+ local pageinfo = querypdf(pdfdoc,pagenumber)
+ local contents = page.Contents
+ local xref = pdfdoc.__xrefs__
+ local copied = pdfdoc.__copied__
+ if compact and lpdf_epdf.plugin then
+ plugins = lpdf_epdf.plugin(pdfdoc,xref,copied,page)
+ end
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Form"),
+ FormType = 1,
+ Group = copyobject(xref,copied,page,"Group"),
+ LastModified = copyobject(xref,copied,page,"LastModified"),
+ Metadata = copyobject(xref,copied,page,"Metadata"),
+ PieceInfo = copyobject(xref,copied,page,"PieceInfo"),
+ Resources = copyresources(pdfdoc,xref,copied,page),
+ SeparationInfo = copyobject(xref,copied,page,"SeparationInfo"),
+ } + attr
+ if attributes then
+ for k, v in expanded(attributes) do
+ page[k] = v -- maybe nested
+ end
+ end
+ local content = ""
+ local nolength = nil
+ local ctype = contents.__type__
+ -- we always recompress because image object streams can not be
+ -- influenced (yet)
+ if ctype == stream_object_code then
+ if stripmarked then
+ content = contents() -- uncompressed
+ local stripped = lpdf_epdf.stripcontent(content)
+ if stripped ~= content then
+ -- report("%i bytes stripped on page %i",#content-#stripped,pagenumber or 1)
+ content = stripped
+ end
+ elseif recompress then
+ content = contents() -- uncompressed
+ else
+ local Filter = copyobject(xref,copied,contents,"Filter")
+ local Length = copyobject(xref,copied,contents,"Length")
+ if Length and Filter then
+ nolength = true
+ xobject.Length = Length
+ xobject.Filter = Filter
+ content = contents(false) -- uncompressed
+ else
+ content = contents() -- uncompressed
+ end
+ end
+ elseif ctype == array_object_code then
+ content = { }
+ for i=1,#contents do
+ content[i] = contents[i]() -- uncompressed
+ end
+ content = concat(content," ")
+ end
+ -- still not nice: we double wrap now
+ plugins = nil
+ local rotation = pageinfo.rotation
+ local boundingbox = pageinfo.boundingbox
+ local transform = nil
+ if rotation == 90 then
+ transform = 3
+ elseif rotation == 180 then
+ transform = 2
+ elseif rotation == 270 then
+ transform = 1
+ elseif rotation > 1 and rotation < 4 then
+ transform = rotation
+ end
+ xobject.BBox = pdfarray {
+ boundingbox[1] * bpfactor,
+ boundingbox[2] * bpfactor,
+ boundingbox[3] * bpfactor,
+ boundingbox[4] * bpfactor,
+ }
+ -- maybe like bitmaps
+ return createimage { -- beware: can be a img.new or a dummy
+ bbox = boundingbox,
+ transform = transform,
+ nolength = nolength,
+ nobbox = true,
+ notype = true,
+ stream = content, -- todo: no compress, pass directly also length, filter etc
+ attr = xobject(),
+ kind = images.types.stream,
+ }
+ end
+ end
+
+ lpdf_epdf.image = {
+ open = openpdf,
+ close = closepdf,
+ new = newpdf,
+ query = querypdf,
+ copy = copypage,
+ }
+
+-- lpdf.injectors.pdf = function(specification)
+-- local d = lpdf_epdf.load(specification.filename)
+-- print(d)
+-- end
+
+
+end end
+
+-- local d = lpdf_epdf.load("e:/tmp/oeps.pdf")
+-- inspect(d)
+-- inspect(d.Catalog.Lang)
+-- inspect(d.Catalog.OCProperties.D.AS[1].Event)
+-- inspect(d.Catalog.Metadata())
+-- inspect(d.Catalog.Pages.Kids[1])
+-- inspect(d.layers)
+-- inspect(d.pages)
+-- inspect(d.destinations)
+-- inspect(lpdf_epdf.getpagecontent(d,1))
+-- inspect(lpdf_epdf.contenttotext(document,lpdf_epdf.getpagecontent(d,1)))
+-- inspect(lpdf_epdf.getstructure(document,lpdf_epdf.getpagecontent(d,1)))
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-pdx.xml b/Master/texmf-dist/tex/context/base/mkiv/lpdf-pdx.xml
index 889862c76f7..35726a5c051 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-pdx.xml
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-pdx.xml
@@ -29,6 +29,7 @@
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-pua.xml b/Master/texmf-dist/tex/context/base/mkiv/lpdf-pua.xml
index f985b54d334..f717762b6e6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-pua.xml
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-pua.xml
@@ -29,6 +29,7 @@
+
@@ -110,6 +111,12 @@
ConTeXt.Url
Text
+
+ external
+ ConTeXt support
+ ConTeXt.Support
+ Text
+
external
ConTeXt version
@@ -118,8 +125,38 @@
external
- Banner of pdftex or one of its successors
- PTEX.Fullbanner
+ ConTeXt LMTX version
+ ConTeXt.LMTX
+ Text
+
+
+ external
+ TeX support
+ TeX.Support
+ Text
+
+
+ external
+ LuaTeX version
+ LuaTeX.Version
+ Text
+
+
+ external
+ LuaTeX functionality
+ LuaTeX.Functionality
+ Text
+
+
+ external
+ LuaTeX Lua version
+ LuaTeX.LuaVersion
+ Text
+
+
+ external
+ LuaTeX platform
+ LuaTeX.Platform
Text
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-ren.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-ren.lua
index e9b22f38299..d6e95e66a22 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-ren.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-ren.lua
@@ -54,7 +54,7 @@ local copy_node = nuts.copy
local nodepool = nuts.pool
local register = nodepool.register
-local pdfpageliteral = nodepool.pdfpageliteral
+local pageliteral = nodepool.pageliteral
local pdf_ocg = pdfconstant("OCG")
local pdf_ocmd = pdfconstant("OCMD")
@@ -261,7 +261,7 @@ function nodeinjections.startlayer(name)
local c = cache[name]
if not c then
useviewerlayer(name)
- c = register(pdfpageliteral(f_bdc(escapednames[name])))
+ c = register(pageliteral(f_bdc(escapednames[name])))
cache[name] = c
end
return copy_node(c)
@@ -269,7 +269,7 @@ end
function nodeinjections.stoplayer()
if not stop then
- stop = register(pdfpageliteral(s_emc))
+ stop = register(pageliteral(s_emc))
end
return copy_node(stop)
end
@@ -286,7 +286,7 @@ function nodeinjections.startstackedlayer(s,t,first,last)
r[#r+1] = startlayer(values[t[i]])
end
r = concat(r," ")
- return pdfpageliteral(r)
+ return pageliteral(r)
end
function nodeinjections.stopstackedlayer(s,t,first,last)
@@ -295,7 +295,7 @@ function nodeinjections.stopstackedlayer(s,t,first,last)
r[#r+1] = stoplayer()
end
r = concat(r," ")
- return pdfpageliteral(r)
+ return pageliteral(r)
end
function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
@@ -307,7 +307,7 @@ function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
r[#r+1] = startlayer(values[t2[i]])
end
r = concat(r," ")
- return pdfpageliteral(r)
+ return pageliteral(r)
end
-- transitions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-res.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-res.lua
index 8b00835ef84..d3c591343fc 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-res.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-res.lua
@@ -6,23 +6,25 @@ if not modules then modules = { } end modules ['lpdf-res'] = {
license = "see context related readme files"
}
-local codeinjections = backends.codeinjections
-local implement = interfaces.implement
+local codeinjections = backends.codeinjections
-local nuts = nodes.nuts
-local tonut = nodes.tonut
+local nuts = nodes.nuts
+local tonut = nodes.tonut
-local setwhd = nuts.setwhd
-local setlist = nuts.setlist
+local setwhd = nuts.setwhd
+local setlist = nuts.setlist
-local new_hlist = nuts.pool.hlist
+local new_hlist = nuts.pool.hlist
-local saveboxresource = tex.saveboxresource
-local useboxresource = tex.useboxresource
-local getboxresource = tex.getboxresourcedimensions
+local boxresources = tex.boxresources
+local saveboxresource = boxresources.save
+local useboxresource = boxresources.use
+local getboxresourcedimensions = boxresources.getdimensions
+
+local pdfcollectedresources = lpdf.collectedresources
function codeinjections.registerboxresource(n,offset)
- local r = saveboxresource(n,nil,lpdf.collectedresources(),true,0,offset or 0) -- direct, todo: accept functions as attr/resources
+ local r = saveboxresource(n,nil,pdfcollectedresources(),true,0,offset or 0) -- direct, todo: accept functions as attr/resources
return r
end
@@ -35,5 +37,5 @@ function codeinjections.restoreboxresource(index)
end
function codeinjections.boxresourcedimensions(index)
- return getboxresource(index)
+ return getboxresourcedimensions(index)
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-swf.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-swf.lua
index 0ac107f8b5e..44e42dc5f8d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-swf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-swf.lua
@@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['lpdf-swf'] = {
local format, gsub = string.format, string.gsub
local concat = table.concat
+local formatters = string.formatters
local backends = backends
local lpdf = lpdf
@@ -33,6 +34,43 @@ local trace_swf = false trackers.register("backend.swf", function(v) trace_swf
local report_swf = logs.reporter("backend","swf")
+--------------------------------------------------------------------------------------
+
+local createimage = images.create
+local embedimage = images.embed
+
+local basepoints = number.dimenfactors.bp
+
+local f_image = formatters["%.6F 0 0 %.6F 0 0 cm /%s Do"]
+
+directives.register("pdf.stripzeros",function()
+ f_image = formatters["%.6N 0 0 %.6N 0 0 cm /%s Do"]
+end)
+
+local function package(image) -- see lpdf-u3d **
+ local boundingbox = image.bbox
+ local imagetag = "Im" .. image.index -- this is not ok
+ local resources = pdfdictionary {
+ ProcSet = lpdf.procset(),
+ Resources = pdfdictionary {
+ XObject = pdfdictionary {
+ [imagetag] = pdfreference(image.objnum)
+ }
+ }
+ }
+ local width = boundingbox[3]
+ local height = boundingbox[4]
+ local xform = createimage {
+ attr = resources(),
+ stream = f_image(width,height,imagetag),
+ bbox = { 0, 0, width/basepoints, height/basepoints },
+ }
+ embedimage(xform)
+ return xform
+end
+
+--------------------------------------------------------------------------------------
+
local activations = {
click = "XA",
page = "PO",
@@ -65,7 +103,10 @@ local function insertswf(spec)
local preview = checkedkey(display,"preview","string")
local toolbar = checkedkey(display,"toolbar","boolean")
- local embeddedreference = codeinjections.embedfile { file = filename }
+ local embeddedreference = codeinjections.embedfile {
+ file = filename,
+ compress = false,
+ }
local flash = pdfdictionary {
Subtype = pdfconstant("RichMediaConfiguration"),
@@ -122,6 +163,7 @@ local function insertswf(spec)
file = fullname,
usedname = usedname,
keepdir = true,
+ compress = false,
}
names[#names+1] = pdfstring(filename)
names[#names+1] = embeddedreference
@@ -275,7 +317,7 @@ local function insertswf(spec)
end
end
if figure then
- local image = img.package(figure.status.private)
+ local image = package(figure.status.private)
appearance = pdfdictionary { N = pdfreference(image.objnum) }
if trace_swf then
report_swf("using preview %s",preview)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
index f4ecfc8a601..0a2fe679ea8 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-tag.lua
@@ -13,7 +13,8 @@ local settings_to_hash = utilities.parsers.settings_to_hash
local sortedhash = table.sortedhash
local formatters = string.formatters
-local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
+local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
+local trace_info = false trackers.register("structures.tags.info", function(v) trace_info = v end)
local report_tags = logs.reporter("backend","tags")
@@ -51,11 +52,9 @@ local a_tagged = attributes.private('tagged')
local a_image = attributes.private('image')
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local nodepool = nuts.pool
-local pdfpageliteral = nodepool.pdfpageliteral
+local pageliteral = nodepool.pageliteral
local register = nodepool.register
local getid = nuts.getid
@@ -68,17 +67,17 @@ local setlink = nuts.setlink
local setlist = nuts.setlist
local copy_node = nuts.copy
-local traverse_nodes = nuts.traverse
local tosequence = nuts.tosequence
-local structure_stack = { }
-local structure_kids = pdfarray()
-local structure_ref = pdfreserveobject()
-local parent_ref = pdfreserveobject()
-local root = { pref = pdfreference(structure_ref), kids = structure_kids }
+local nextnode = nuts.traversers.node
+
+local structure_kids -- delayed
+local structure_ref -- delayed
+local parent_ref -- delayed
+local root -- delayed
+local names -- delayed
local tree = { }
local elements = { }
-local names = pdfarray()
local structurestags = structures.tags
local taglist = structurestags.taglist
@@ -112,7 +111,7 @@ local usedmapping = { }
-- end
local function finishstructure()
- if #structure_kids > 0 then
+ if root and #structure_kids > 0 then
local nums, n = pdfarray(), 0
for i=1,#tree do
n = n + 1 ; nums[n] = i - 1
@@ -171,6 +170,7 @@ local index, pageref, pagenum, list = 0, nil, 0, nil
local pdf_mcr = pdfconstant("MCR")
local pdf_struct_element = pdfconstant("StructElem")
+local pdf_s = pdfconstant("S")
local function initializepage()
index = 0
@@ -183,6 +183,8 @@ end
local function finishpage()
-- flush what can be flushed
addtopageattributes("StructParents",pagenum-1)
+ -- there might be more
+ addtopageattributes("Tabs",s)
end
-- here we can flush and free elements that are finished
@@ -255,9 +257,10 @@ local function makeelement(fulltag,parent)
AF = af,
}
local s = pdfreference(pdfflushobject(d))
- if id then
- names[#names+1] = id
- names[#names+1] = s
+ if id and names then
+ local size = #names
+ names[size+1] = id
+ names[size+2] = s
end
local kids = parent.kids
kids[#kids+1] = s
@@ -314,27 +317,35 @@ end
-- no need to adapt head, as we always operate on lists
local EMCliteral = nil
+local visualize = nil
function nodeinjections.addtags(head)
if not EMCliteral then
- EMCliteral = register(pdfpageliteral("EMC"))
+ EMCliteral = register(pageliteral("EMC"))
end
local last = nil
local ranges = { }
local range = nil
- local head = tonut(head)
+
+ if not root then
+ structure_kids = pdfarray()
+ structure_ref = pdfreserveobject()
+ parent_ref = pdfreserveobject()
+ root = { pref = pdfreference(structure_ref), kids = structure_kids }
+ names = pdfarray()
+ end
local function collectranges(head,list)
- for n in traverse_nodes(head) do
- local id = getid(n)
+ for n, id in nextnode, head do
if id == glyph_code then
-- maybe also disc
- local at = getattr(n,a_tagged)
- if not at then
- range = nil
- elseif last ~= at then
+ local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
+ -- if not at then
+ -- range = nil
+ -- elseif ...
+ if last ~= at then
range = { at, "glyph", n, n, list } -- attr id start stop list
ranges[#ranges+1] = range
last = at
@@ -344,12 +355,12 @@ function nodeinjections.addtags(head)
elseif id == hlist_code or id == vlist_code then
local at = getattr(n,a_image)
if at then
- local at = getattr(n,a_tagged)
- if not at then
- range = nil
- else
+ local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
+ -- if not at then
+ -- range = nil
+ -- else
ranges[#ranges+1] = { at, "image", n, n, list } -- attr id start stop list
- end
+ -- end
last = nil
else
collectranges(getlist(n),n)
@@ -379,89 +390,117 @@ function nodeinjections.addtags(head)
local top = nil
local noftop = 0
+
+ local function inject(start,stop,list,literal,left,right)
+ local prev = getprev(start)
+ if prev then
+ setlink(prev,literal)
+ end
+ if left then
+ setlink(literal,left,start)
+ else
+ setlink(literal,start)
+ end
+ if list and getlist(list) == start then
+ setlist(list,literal)
+ end
+ local literal = copy_node(EMCliteral)
+ -- use insert instead:
+ local next = getnext(stop)
+ if next then
+ setlink(literal,next)
+ end
+ if right then
+ setlink(stop,right,literal)
+ else
+ setlink(stop,literal)
+ end
+ end
+
for i=1,#ranges do
- local range = ranges[i]
- local attr = range[1]
- local id = range[2]
- local start = range[3]
- local stop = range[4]
- local list = range[5]
- local specification = taglist[attr]
- local taglist = specification.taglist
- local noftags = #taglist
- local common = 0
- if top then
- for i=1,noftags >= noftop and noftop or noftags do
- if top[i] == taglist[i] then
- common = i
- else
- break
+
+ local range = ranges[i]
+ local attr = range[1]
+ local id = range[2]
+ local start = range[3]
+ local stop = range[4]
+ local list = range[5]
+
+ if attr then
+
+ local specification = taglist[attr]
+ local taglist = specification.taglist
+ local noftags = #taglist
+ local common = 0
+ local literal = nil
+ local ignore = false
+
+ if top then
+ for i=1,noftags >= noftop and noftop or noftags do
+ if top[i] == taglist[i] then
+ common = i
+ else
+ break
+ end
end
end
- end
- local prev = common > 0 and elements[taglist[common]] or root
- local ignore = false
- local literal = nil
-
- for j=common+1,noftags do
- local tag = taglist[j]
- local prv = elements[tag] or makeelement(tag,prev)
- if prv == false then
- -- ignore this one
- prev = false
- ignore = true
- break
- elseif prv == true then
- -- skip this one
- else
- prev = prv
+ local prev = common > 0 and elements[taglist[common]] or root
+
+ for j=common+1,noftags do
+ local tag = taglist[j]
+ local prv = elements[tag] or makeelement(tag,prev)
+ if prv == false then
+ -- ignore this one
+ prev = false
+ ignore = true
+ break
+ elseif prv == true then
+ -- skip this one
+ else
+ prev = prv
+ end
end
- end
- if prev then
- literal = pdfpageliteral(makecontent(prev,id,specification))
- elseif ignore then
- literal = pdfpageliteral(makeignore(specification))
- end
- if literal then
- local prev = getprev(start)
if prev then
- setlink(prev,literal)
- end
- setlink(literal,start)
- if list and getlist(list) == start then
- setlist(list,literal)
+ literal = pageliteral(makecontent(prev,id,specification))
+ elseif ignore then
+ literal = pageliteral(makeignore(specification))
+ else
+ -- maybe also ignore or maybe better: comment or so
end
- local literal = copy_node(EMCliteral)
- -- use insert instead:
- local next = getnext(stop)
- if next then
- setlink(literal,next)
+
+ if literal then
+ local left,right
+ if trace_info then
+ local name = specification.tagname
+ if name then
+ if not visualize then
+ visualize = nodes.visualizers.register("tags")
+ end
+ left = visualize(name)
+ right = visualize()
+ end
+ end
+ inject(start,stop,list,literal,left,right)
end
- setlink(stop,literal)
- end
--- if literal then
--- if list and getlist(list) == start then
--- setlink(literal,start)
--- setlist(list,literal)
--- else
--- setlink(getprev(start),literal,start)
--- end
--- -- use insert instead:
--- local literal = copy_node(EMCliteral)
--- setlink(stop,literal,getnext(stop))
--- end
+ top = taglist
+ noftop = noftags
+
+ else
+
+ local literal = pageliteral(makeignore(specification))
+
+ inject(start,stop,list,literal)
+
+ end
- top = taglist
- noftop = noftags
end
finishpage()
- head = tonode(head)
- return head, true
+ return head
end
@@ -472,8 +511,7 @@ end
-- local last, ranges, range = nil, { }, nil
--
-- local function collectranges(head,list)
--- for n in traverse_nodes(head) do
--- local id = getid(n) -- 14: image, 8: literal (mp)
+-- for n, id in nextnode, head do
-- if id == glyph_code then
-- local at = getattr(n,a_tagged)
-- if not at then
@@ -505,7 +543,6 @@ end
--
-- initializepage()
--
--- head = tonut(head)
-- collectranges(head)
--
-- if trace_tags then
@@ -577,9 +614,9 @@ end
-- end
--
-- if r > 0 then
--- local literal = pdfpageliteral(concat(result,"\n"))
+-- local literal = pageliteral(concat(result,"\n"))
-- -- use insert instead:
--- local literal = pdfpageliteral(result)
+-- local literal = pageliteral(result)
-- local prev = getprev(start)
-- if prev then
-- setlink(prev,literal)
@@ -601,7 +638,7 @@ end
-- for i=1,noftop do
-- result[i] = "EMC"
-- end
--- local literal = pdfpageliteral(concat(result,"\n"))
+-- local literal = pageliteral(concat(result,"\n"))
-- -- use insert instead:
-- local next = getnext(last)
-- if next then
@@ -612,8 +649,7 @@ end
--
-- finishpage()
--
--- head = tonode(head)
--- return head, true
+-- return head
--
-- end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-u3d.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-u3d.lua
index dfd4c1b0686..f6897e92d20 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-u3d.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-u3d.lua
@@ -27,7 +27,6 @@ local nodeinjections = backends.pdf.nodeinjections
local pdfconstant = lpdf.constant
local pdfboolean = lpdf.boolean
-local pdfnumber = lpdf.number
local pdfunicode = lpdf.unicode
local pdfdictionary = lpdf.dictionary
local pdfarray = lpdf.array
@@ -39,6 +38,8 @@ local pdfflushstreamfileobject = lpdf.flushstreamfileobject
local checkedkey = lpdf.checkedkey
local limited = lpdf.limited
+local embedimage = images.embed
+
local schemes = table.tohash {
"Artwork", "None", "White", "Day", "Night", "Hard",
"Primary", "Blue", "Red", "Cube", "CAD", "Headlamp",
@@ -347,6 +348,12 @@ end
local stored_js, stored_3d, stored_pr, streams = { }, { }, { }, { }
+local f_image = formatters["q /GS gs %.6F 0 0 %.6F 0 0 cm /IM Do Q"]
+
+directives.register("pdf.stripzeros",function()
+ f_image = formatters["q /GS gs %.6N 0 0 %.6N 0 0 cm /IM Do Q"]
+end)
+
local function insert3d(spec) -- width, height, factor, display, controls, label, foundname
local width, height, factor = spec.width, spec.height, spec.factor or number.dimenfactors.bp
@@ -431,7 +438,7 @@ local function insert3d(spec) -- width, height, factor, display, controls, label
local tag = formatters["%s:%s:%s"](label,stream,preview)
local ref = stored_pr[tag]
if not ref then
- local figure = img.immediatewrite {
+ local figure = embedimage {
filename = preview,
width = width,
height = height
@@ -440,13 +447,13 @@ local function insert3d(spec) -- width, height, factor, display, controls, label
stored_pr[tag] = ref
end
if ref then -- see back-pdf ** .. here we have a local /IM !
- local zero, one = pdfnumber(0), pdfnumber(1) -- not really needed
local pw = pdfdictionary {
Type = pdfconstant("XObject"),
Subtype = pdfconstant("Form"),
- FormType = one,
- BBox = pdfarray { zero, zero, pdfnumber(factor*width), pdfnumber(factor*height) },
- Matrix = pdfarray { one, zero, zero, one, zero, zero },
+ FormType = 1,
+ BBox = pdfarray { 0, 0, pdfnumber(factor*width), pdfnumber(factor*height) },
+ Matrix = pdfarray { 1, 0, 0, 1, 0, 0 },
+ ProcSet = lpdf.procset(),
Resources = pdfdictionary {
XObject = pdfdictionary {
IM = pdfreference(ref)
@@ -455,13 +462,12 @@ local function insert3d(spec) -- width, height, factor, display, controls, label
ExtGState = pdfdictionary {
GS = pdfdictionary {
Type = pdfconstant("ExtGState"),
- CA = one,
- ca = one,
+ CA = 1,
+ ca = 1,
}
},
- ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") },
}
- local pwd = pdfflushstreamobject(formatters["q /GS gs %.6F 0 0 %.6F 0 0 cm /IM Do Q"](factor*width,factor*height),pw)
+ local pwd = pdfflushstreamobject(f_image(factor*width,factor*height),pw)
annot.AP = pdfdictionary {
N = pdfreference(pwd)
}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-wid.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-wid.lua
index 03febbf01e2..a929ed2ceb9 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-wid.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-wid.lua
@@ -11,11 +11,11 @@ if not modules then modules = { } end modules ['lpdf-wid'] = {
-- had renditions but they turned out to be unreliable from the start and look
-- obsolete too or at least they are bound to the (obsolete) flash technology for
-- rendering. They were already complex constructs. Now we have rich media which
--- instead of providing a robust future proof framework fo rgeneral media types
+-- instead of providing a robust future proof framework for general media types
-- again seems to depend on viewers built in (yes, also kind of obsolete) flash
-- technology, and we cannot expect this non-open technology to show up in open
-- browsers. So, in the end we can best just use links to external resources to be
--- future proof. Just look at the viewer prferences pane to see how fragile support
+-- future proof. Just look at the viewer preferences pane to see how fragile support
-- is. Interestingly u3d support is kind of built in, while e.g. mp4 support relies
-- on wrapping in swf. We used to stay ahead of the pack with support of the fancy
-- pdf features but it backfires and is not worth the trouble. And yes, for control
@@ -29,7 +29,7 @@ local gmatch, gsub, find, lower = string.gmatch, string.gsub, string.find, strin
local stripstring = string.strip
local settings_to_array = utilities.parsers.settings_to_array
local settings_to_hash = utilities.parsers.settings_to_hash
-local sortedhash = table.sortedhash
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
local report_media = logs.reporter("backend","media")
local report_attachment = logs.reporter("backend","attachment")
@@ -141,6 +141,10 @@ local attachment_symbols = {
attachment_symbols.PushPin = attachment_symbols.Pushpin
attachment_symbols.Default = attachment_symbols.Pushpin
+function lpdf.attachmentsymbols()
+ return sortedkeys(comment_symbols)
+end
+
local comment_symbols = {
Comment = pdfconstant("Comment"),
Help = pdfconstant("Help"),
@@ -154,6 +158,10 @@ local comment_symbols = {
comment_symbols.NewParagraph = Newparagraph
comment_symbols.Default = Note
+function lpdf.commentsymbols()
+ return sortedkeys(comment_symbols)
+end
+
local function analyzesymbol(symbol,collection)
if not symbol or symbol == "" then
return collection and collection.Default, nil
@@ -239,10 +247,12 @@ local function flushembeddedfiles()
e[#e+1] = pdfstring(tag)
e[#e+1] = reference -- already a reference
else
- -- messy spec ... when annot not in named else twice in menu list acrobat
+ -- -- messy spec ... when annot not in named else twice in menu list acrobat
end
end
- lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e })))
+ if #e > 0 then
+ lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e })))
+ end
end
end
@@ -257,9 +267,13 @@ function codeinjections.embedfile(specification)
local keepdir = specification.keepdir -- can change
local usedname = specification.usedname
local filetype = specification.filetype
+ local compress = specification.compress
if filename == "" then
filename = nil
end
+ if compress == nil then
+ compress = true
+ end
if data then
local r = filestreams[hash]
if r == false then
@@ -314,7 +328,7 @@ function codeinjections.embedfile(specification)
specification.data = true -- signal that still data but already flushed
else
local foundname = specification.foundname or filename
- f = pdfflushstreamfileobject(foundname,a)
+ f = pdfflushstreamfileobject(foundname,a,compress)
end
local d = pdfdictionary {
Type = pdfconstant("Filespec"),
@@ -417,7 +431,8 @@ function codeinjections.attachmentid(filename) -- not used in context
return filestreams[filename]
end
-local nofcomments, usepopupcomments = 0, false
+local nofcomments = 0
+local usepopupcomments = false
local defaultattributes = {
["xmlns"] = "http://www.w3.org/1999/xhtml",
@@ -612,7 +627,8 @@ local function insertrendering(specification)
local option = settings_to_hash(specification.option)
if not mf[label] then
local filename = specification.filename
- local isurl = find(filename,"://",1,true)
+ local isurl = find(filename,"://",1,true)
+ local mimetype = specification.mimetype or specification.mime
-- local start = pdfdictionary {
-- Type = pdfconstant("MediaOffset"),
-- S = pdfconstant("T"), -- time
@@ -648,13 +664,17 @@ local function insertrendering(specification)
if isurl then
descriptor.FS = pdfconstant("URL")
elseif option[v_embed] then
- descriptor.EF = codeinjections.embedfile { file = filename }
+ descriptor.EF = codeinjections.embedfile {
+ file = filename,
+ mimetype = mimetype, -- yes or no
+ compress = false,
+ }
end
local clip = pdfdictionary {
Type = pdfconstant("MediaClip"),
S = pdfconstant("MCD"),
N = label,
- CT = specification.mime,
+ CT = mimetype,
Alt = pdfarray { "", "file not found" }, -- language id + message
D = pdfreference(pdfflushobject(descriptor)),
-- P = pdfreference(pdfflushobject(parameters)),
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-xmp.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-xmp.lua
index eb15a358287..508bb19976d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-xmp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-xmp.lua
@@ -11,6 +11,7 @@ local tostring, type = tostring, type
local format, gsub = string.format, string.gsub
local utfchar = utf.char
local xmlfillin = xml.fillin
+local md5HEX = md5.HEX
local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp = v end)
local trace_info = false trackers.register("backend.info", function(v) trace_info = v end)
@@ -33,7 +34,7 @@ local pdfgetmetadata = lpdf.getmetadata
-- XMP-Toolkit-SDK-CC201607.zip. So we hardcode the id.
local xpacket = format ( [[
-
+
%%s
@@ -46,7 +47,8 @@ local mapping = {
["ConTeXt.Url"] = { "context", "rdf:Description/pdfx:ConTeXt.Url" },
["ConTeXt.Support"] = { "context", "rdf:Description/pdfx:ConTeXt.Support" },
["ConTeXt.Version"] = { "context", "rdf:Description/pdfx:ConTeXt.Version" },
- ["TeX.Support"] = { "metadata", "rdf:Description/pdfx:TeX.Support" },
+ ["ConTeXt.LMTX"] = { "context", "rdf:Description/pdfx:ConTeXt.LMTX" },
+ ["TeX.Support"] = { "metadata","rdf:Description/pdfx:TeX.Support" },
["LuaTeX.Version"] = { "metadata","rdf:Description/pdfx:LuaTeX.Version" },
["LuaTeX.Functionality"] = { "metadata","rdf:Description/pdfx:LuaTeX.Functionality" },
["LuaTeX.LuaVersion"] = { "metadata","rdf:Description/pdfx:LuaTeX.LuaVersion" },
@@ -89,7 +91,7 @@ local mapping = {
["CaptionWriter"] = { "metadata", "rdf:Description/photoshop:CaptionWriter" },
}
-pdf.setsuppressoptionalinfo(
+lpdf.setsuppressoptionalinfo (
0 --
+ 1 -- pdfnofullbanner
+ 2 -- pdfnofilename
@@ -104,59 +106,62 @@ pdf.setsuppressoptionalinfo(
)
local included = backends.included
-
-local pdfsettrailerid = pdf.settrailerid
-
-local lpdfid = lpdf.id
+local lpdfid = lpdf.id
function lpdf.id() -- overload of ini
return lpdfid(included.date)
end
-pdf.disablecommand("settrailerid")
+local settrailerid = lpdf.settrailerid -- this is the wrapped one
+
+local trailerid = nil
+local dates = nil
-function lpdf.settrailerid(v)
- if v then
- local b = toboolean(v) or v == ""
+local function update()
+ if trailer_id then
+ local b = toboolean(trailer_id) or trailer_id == ""
if b then
- v = "This file is processed by ConTeXt and LuaTeX."
+ trailer_id = "This file is processed by ConTeXt and LuaTeX."
else
- v = tostring(v)
+ trailer_id = tostring(trailer_id)
end
- local h = md5.HEX(v)
+ local h = md5HEX(trailer_id)
if b then
report_info("using frozen trailer id")
else
- report_info("using hashed trailer id %a (%a)",v,h)
+ report_info("using hashed trailer id %a (%a)",trailer_id,h)
end
- pdfsettrailerid(format("[<%s> <%s>]",h,h))
+ settrailerid(format("[<%s> <%s>]",h,h))
end
-end
-
-function lpdf.setdates(v)
- local t = type(v)
+ --
+ local t = type(dates)
if t == "number" or t == "string" then
- t = converters.totime(v)
- if t then
+ local d = converters.totime(dates)
+ if d then
included.date = true
included.id = "fake"
- report_info("forced date/time information %a will be used",lpdf.settime(t))
- lpdf.settrailerid(false)
+ report_info("forced date/time information %a will be used",lpdf.settime(d))
+ settrailerid(false)
return
end
- end
- v = toboolean(v)
- included.date = v
- if v then
- included.id = true
- else
- report_info("no date/time but fake id information will be added")
- lpdf.settrailerid(true)
- included.id = "fake"
- -- maybe: lpdf.settime(231631200) -- 1975-05-05 % first entry of knuth about tex mentioned in DT
+ if t == "string" then
+ dates = toboolean(dates)
+ included.date = dates
+ if dates ~= false then
+ included.id = true
+ else
+ report_info("no date/time but fake id information will be added")
+ settrailerid(true)
+ included.id = "fake"
+ end
+ end
end
end
+function lpdf.settrailerid(v) trailerid = v end
+function lpdf.setdates (v) dates = v end
+
+lpdf.registerdocumentfinalizer(update,"trailer id and dates",1)
directives.register("backend.trailerid", lpdf.settrailerid)
directives.register("backend.date", lpdf.setdates)
@@ -313,7 +318,7 @@ local function flushxmpinfo()
commands.poprandomseed() -- hack
end
--- his will be enabled when we can inhibit compression for a stream at the lua end
+-- this will be enabled when we can inhibit compression for a stream at the lua end
lpdf.registerdocumentfinalizer(flushxmpinfo,1,"metadata")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-bas.mkiv b/Master/texmf-dist/tex/context/base/mkiv/luat-bas.mkiv
index b1af4da3ee9..0add4ce6926 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-bas.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-bas.mkiv
@@ -13,6 +13,7 @@
\writestatus{loading}{ConTeXt Lua Macros / Basic Lua Libraries}
+\registerctxluafile{l-bit32} {} % before sandbox
\registerctxluafile{l-lua} {} % before sandbox
\registerctxluafile{l-macro} {}
\registerctxluafile{l-sandbox} {}
@@ -30,6 +31,7 @@
\registerctxluafile{l-file} {}
\registerctxluafile{l-gzip} {}
\registerctxluafile{l-md5} {}
+\registerctxluafile{l-sha} {}
\registerctxluafile{l-dir} {}
\registerctxluafile{l-unicode} {optimize}
%registerctxluafile{l-utils} {}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-cbk.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-cbk.lua
index 6fcfdc7f2ee..d3184e1af77 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-cbk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-cbk.lua
@@ -121,6 +121,12 @@ if trace_calls then
end
+-- temporary, not public:
+
+callbacks.functions = { }
+
+-- till here
+
local reported = { }
local function register_usercall(what,name,func)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-cnf.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-cnf.lua
index b6ee15083da..0670d168418 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-cnf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-cnf.lua
@@ -154,6 +154,8 @@ function texconfig.init()
end
+CONTEXTLMTXMODE = %s
+
-- we provide a qualified path
callback.register('find_format_file',function(name)
@@ -212,7 +214,7 @@ local function makestub()
t[#t+1] = format("texconfig.%s=%s",v,tv)
end
end
- io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable)))
+ io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable,tostring(CONTEXTLMTXMODE) or 0)))
logs.newline()
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua
index 91bb7c2e168..dcb16c0dd72 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua
@@ -11,6 +11,10 @@ local match, gsub, find, format, gmatch = string.match, string.gsub, string.find
local texconfig, lua = texconfig, lua
+-- maybe pick up from commandline:
+--
+-- texconfig.interaction: 0=batchmode 1=nonstopmode 2=scrollmode 3=errornonstopmode 4=normal
+
-- some basic housekeeping
texconfig.kpse_init = false
@@ -38,7 +42,7 @@ lua.bytedata = bytedata
lua.bytedone = bytedone
local setbytecode = lua.setbytecode
-local getbytecode = lua.getbytecode
+----- getbytecode = lua.getbytecode
lua.firstbytecode = 501
lua.lastbytecode = lua.lastbytecode or (lua.firstbytecode - 1) -- as we load ourselves again ... maybe return earlier
@@ -49,9 +53,13 @@ end
-- no file.* and utilities.parsers.* functions yet
+local strip = false if arg then for i=-1,#arg do if arg[i] == "--c:strip" then strip = true break end end end
+
function lua.registercode(filename,options)
local barename = gsub(filename,"%.[%a%d]+$","")
- if barename == filename then filename = filename .. ".lua" end
+ if barename == filename then
+ filename = filename .. ".lua"
+ end
local basename = match(barename,"^.+[/\\](.-)$") or barename
if not bytedone[basename] then
local opts = { }
@@ -66,7 +74,11 @@ function lua.registercode(filename,options)
if environment.initex then
local n = lua.lastbytecode + 1
bytedata[n] = { name = barename, options = opts }
- setbytecode(n,code)
+ if strip or opts.strip then
+ setbytecode(n,code,true)
+ else
+ setbytecode(n,code)
+ end
lua.lastbytecode = n
end
elseif environment.initex then
@@ -129,6 +141,18 @@ if LUATEXVERION == nil then
+ (tonumber(LUATEXVERSION) or (string.byte(LUATEXVERSION)-string.byte("a")+10))/1000
end
+if CONTEXTLMTXMODE == nil then
+ if status.obj_ptr == nil then
+ CONTEXTLMTXMODE = 2
+ else
+ CONTEXTLMTXMODE = 0
+ for i=1,#arg do if arg[i] == "--c:lmtx" then
+ CONTEXTLMTXMODE, pdf, img = 1, nil, nil
+ break
+ end end
+ end
+end
+
if LUATEXFUNCTIONALITY == nil then
LUATEXFUNCTIONALITY = status.development_id or 6346
end
@@ -143,7 +167,7 @@ end
environment.luatexengine = LUATEXENGINE
environment.luatexversion = LUATEXVERSION
-environment.luatexfuncitonality = LUATEXFUNCTIONALITY
+environment.luatexfunctionality = LUATEXFUNCTIONALITY
environment.jitsupported = JITSUPPORTED
environment.initex = INITEXMODE
environment.initexmode = INITEXMODE
@@ -151,12 +175,14 @@ environment.initexmode = INITEXMODE
if not environment.luafilechunk then
function environment.luafilechunk(filename)
+ local fullname = filename
if sourcepath ~= "" then
- filename = sourcepath .. "/" .. filename
+ fullname = sourcepath .. "/" .. filename
end
- local data = loadfile(filename)
- texio.write("term and log","<",data and "+ " or "- ",filename,">")
+ local data = loadfile(fullname)
+ texio.write("term and log","<",data and "+ " or "- ",fullname,">")
if data then
+-- package.loaded[gsub(filename,"%..-$"] =
data()
end
return data
@@ -187,6 +213,21 @@ end
-- a kpse error when disabled. This is an engine issue that will
-- be sorted out in due time.
+if not lfs.isfile then
+
+ local attributes = lfs.attributes
+
+ function lfs.isdir(name)
+ return attributes(name,"mode") == "directory"
+ end
+
+ function lfs.isfile(name)
+ local a = attributes(name,"mode")
+ return a == "file" or a == "link" or nil
+ end
+
+end
+
local isfile = lfs.isfile
local function source_file(name)
@@ -229,6 +270,15 @@ local function open_read_file(name)
}
end
+local function find_data_file(name)
+ return source_file(name)
+end
+
+local open_data_file = open_read_file
+
callback.register('find_read_file' , find_read_file )
callback.register('open_read_file' , open_read_file )
callback.register('find_write_file', find_write_file)
+
+callback.register('find_data_file' , find_data_file )
+callback.register('open_data_file' , open_data_file )
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-env.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-env.lua
index 5b46b403622..e0c69d2079b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-env.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-env.lua
@@ -11,7 +11,8 @@
-- sense. Much of this evolved before bytecode arrays were available and so a lot of
-- code has disappeared already.
-local rawset, rawget, loadfile, assert = rawset, rawget, loadfile, assert
+local rawset, rawget, loadfile = rawset, rawget, loadfile
+local gsub = string.gsub
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
@@ -123,7 +124,7 @@ function environment.loadluafile(filename, version)
luaname = file.addsuffix(basename,luasuffixes.lua)
lucname = file.addsuffix(basename,luasuffixes.luc)
else
- luaname = basename -- forced suffix
+ luaname = filename -- forced suffix
lucname = nil
end
-- when not overloaded by explicit suffix we look for a luc file first
@@ -136,7 +137,7 @@ function environment.loadluafile(filename, version)
chunk = loadfile(fullname) -- this way we don't need a file exists check
end
if chunk then
- assert(chunk)()
+ chunk()
if version then
-- we check of the version number of this chunk matches
local v = version -- can be nil
@@ -168,9 +169,24 @@ function environment.loadluafile(filename, version)
report_lua("unknown file %a",filename)
end
else
- assert(chunk)()
+ chunk()
return true
end
end
return false
end
+
+environment.filenames = setmetatable( { }, {
+ __index = function(t,k)
+ local v = environment.files[k]
+ if v then
+ return (gsub(v,"%.+$",""))
+ end
+ end,
+ __newindex = function(t,k)
+ -- nothing
+ end,
+ __len = function(t)
+ return #environment.files
+ end,
+} )
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-fio.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-fio.lua
index 806caefe621..2996ae66ab0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-fio.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-fio.lua
@@ -70,12 +70,16 @@ if not resolvers.initialized() then
return okay or ""
end
+ resolvers.findpk = findpk
+
-- register('process_jobname' , function(name) return name end, true)
register('find_read_file' , function(id,name) return findtexfile(name) end, true)
register('open_read_file' , function( name) return opentexfile(name) end, true)
register('find_data_file' , function(name) return findbinfile(name,"tex") end, true)
+ register('open_data_file' , function(name) return opentexfile(name) end, true)
+
register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true)
register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true)
-- register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua
index 30c55eeccfd..1c9222d95d1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua
@@ -19,9 +19,9 @@ local function primaryflags()
if arguments.silent then
flags[#flags+1] = "--interaction=batchmode"
end
- if arguments.jit then
- flags[#flags+1] = "--jiton"
- end
+ -- if arguments.jit then
+ -- flags[#flags+1] = "--jiton"
+ -- end
return concat(flags," ")
end
@@ -48,10 +48,16 @@ local function secondaryflags()
if arguments.ansi then
flags[#flags+1] = "--c:ansi"
end
+ if arguments.strip then
+ flags[#flags+1] = "--c:strip"
+ end
+ if arguments.lmtx then
+ flags[#flags+1] = "--c:lmtx"
+ end
return concat(flags," ")
end
--- The silent option is Taco. It's a bit of a hack because we cannot yet mess
+-- The silent option is for Taco. It's a bit of a hack because we cannot yet mess
-- with directives. In fact, I could probably clean up the maker a bit by now.
local template = [[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-ini.lua
index de725492200..ffd402c7752 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-ini.lua
@@ -25,15 +25,19 @@ if not global then
global = _G
end
-LUATEXVERSION = status.luatex_version/100
- + tonumber(status.luatex_revision)/1000
+LUATEXVERSION = status.luatex_version/100
+ + tonumber(status.luatex_revision)/1000
-LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
- or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex")
+LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
+ or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex")
-JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
+LUATEXFUNCTIONALITY = status.development_id or 6346
-INITEXMODE = status.ini_version
+JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
+
+INITEXMODE = status.ini_version
+
+CONTEXTLMTXMODE = CONTEXTLMTXMODE or (status.obj_ptr == nil and 2 or 1)
function os.setlocale()
-- no need for a message
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/luat-ini.mkiv
index 872d27e7726..da5a3a3109f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-ini.mkiv
@@ -265,55 +265,84 @@
% \def\syst_helpers_checked_stripped_csname#1%
% {\if\noexpand#1\letterbackslash\else#1\fi}
-\normalprotected\def\installctxfunction#1#2% expandable
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installctxscanner#1#2% expandable
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installprotectedctxfunction#1#2% protected
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installprotectedctxscanner#1#2% protected
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
-
-% not yet used
-
-\ifdefined\luafunctioncall \else
- \protected\def\luafunctioncall{\luafunctioncall}
-\fi
+\ifdefined\normalluadef
+
+ \normalprotected\def\installctxfunction#1#2% expandable
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax}
+
+ \normalprotected\def\installctxscanner#1#2% expandable
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax}
+
+ \normalprotected\def\installprotectedctxfunction#1#2% protected
+ {\edef\m_syst_name{\csstring#1}%
+ \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax}
+
+ \normalprotected\def\installprotectedctxscanner#1#2% protected
+ {\edef\m_syst_name{\csstring#1}%
+ \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax}
+
+ \normalprotected\def\resetctxscanner#1%
+ {\edef\m_syst_name{\csstring#1}%
+ \expandafter\glet\csname\m_syst_name\endcsname\relax}
+
+ % \let\installctxfunctioncall \installctxfunction
+ % \let\installctxscannercall \installctxscanner
+ % \let\installprotectedctxfunctioncall\installprotectedctxfunction
+ % \let\installprotectedctxscannercall \installprotectedctxscanner
+
+\else
+
+ \ifdefined\luafunctioncall \else
+ \normalprotected\def\luafunctioncall{\luafunction}
+ \fi
+
+ \normalprotected\def\installctxfunction#1#2% expandable
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
+ \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
+
+ \normalprotected\def\installctxscanner#1#2% expandable
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
+ \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}}
+
+ \normalprotected\def\installprotectedctxfunction#1#2% protected
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
+ \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
+
+ \normalprotected\def\installprotectedctxscanner#1#2% protected
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
+ \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
+
+ \normalprotected\def\resetctxscanner#1%
+ {\edef\m_syst_name{\csstring#1}%
+ \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\zerocount
+ \expandafter\glet\csname\m_syst_name\endcsname\relax}
+
+ % \normalprotected\def\installctxfunctioncall#1#2%
+ % {\edef\m_syst_name{\csstring#1}%
+ % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
+ % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
+ %
+ % \normalprotected\def\installctxscannercall#1#2%
+ % {\edef\m_syst_name{\csstring#1}%
+ % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
+ % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
+ %
+ % \normalprotected\def\installprotectedctxfunctioncall#1#2%
+ % {\edef\m_syst_name{\csstring#1}%
+ % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
+ % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
+ %
+ % \normalprotected\def\installprotectedctxscannercall#1#2%
+ % {\edef\m_syst_name{\csstring#1}%
+ % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
+ % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
-\normalprotected\def\installctxfunctioncall#1#2%
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installctxscannercall#1#2%
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
- \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installprotectedctxfunctioncall#1#2%
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax
- \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\installprotectedctxscannercall#1#2%
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax
- \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}}
-
-\normalprotected\def\resetctxscanner#1%
- {\edef\m_syst_name{\csstring#1}%
- \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\zerocount
- \global\expandafter\let\csname\m_syst_name\endcsname\relax}
+\fi
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-lib.mkiv b/Master/texmf-dist/tex/context/base/mkiv/luat-lib.mkiv
index 0df31a4e54e..d5f6099ca79 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-lib.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-lib.mkiv
@@ -19,7 +19,7 @@
\registerctxluafile{util-sac}{optimize}
\registerctxluafile{util-sto}{} % could also be done in trac-deb.mkiv
\registerctxluafile{util-pck}{}
-\registerctxluafile{util-seq}{}
+% \registerctxluafile{util-seq}{}
%registerctxluafile{util-mrg}{} % not needed in context itself, only mtxrun
%registerctxluafile{util-lua}{} % moved
\registerctxluafile{util-prs}{}
@@ -35,11 +35,25 @@
\registerctxluafile{util-deb}{} % could also be done in trac-deb.mkiv
\registerctxluafile{util-tpl}{} % needs tracker
+\registerctxluafile{util-seq}{}
\registerctxluafile{util-sta}{}
\registerctxluafile{util-sbx}{} % needs tracker and templates
+\registerctxluafile{util-soc-imp-reset} {}
+\registerctxluafile{util-soc-imp-socket} {}
+%registerctxluafile{util-soc-imp-copas} {}
+\registerctxluafile{util-soc-imp-ltn12} {}
+%registerctxluafile{util-soc-imp-mbox} {}
+\registerctxluafile{util-soc-imp-mime} {}
+\registerctxluafile{util-soc-imp-url} {}
+\registerctxluafile{util-soc-imp-headers}{}
+\registerctxluafile{util-soc-imp-http} {}
+\registerctxluafile{util-soc-imp-tp} {}
+%registerctxluafile{util-soc-imp-ftp} {}
+%registerctxluafile{util-soc-imp-smtp} {}
+
\registerctxluafile{data-ini}{}
\registerctxluafile{data-exp}{}
\registerctxluafile{data-env}{}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-run.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-run.lua
index 59fb0b9371a..98f98177705 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-run.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-run.lua
@@ -115,6 +115,29 @@ local function wrapup_synctex()
synctex.wrapup()
end
+-- For Taco ...
+
+local sequencers = utilities.sequencers
+local appendgroup = sequencers.appendgroup
+local appendaction = sequencers.appendaction
+local wrapupactions = sequencers.new { }
+
+appendgroup(wrapupactions,"system")
+appendgroup(wrapupactions,"user")
+
+local function wrapup_run()
+ local runner = wrapupactions.runner
+ if runner then
+ runner()
+ end
+end
+
+function luatex.wrapup(action)
+ appendaction(wrapupactions,"user",action)
+end
+
+appendaction(wrapupactions,"system",synctex.wrapup)
+
-- this can be done later
callbacks.register('start_run', start_run, "actions performed at the beginning of a run")
@@ -126,20 +149,26 @@ callbacks.register('stop_run', stop_run, "actions perf
callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages")
callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file")
-callbacks.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout")
-callbacks.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout")
+---------.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout")
+---------.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout")
+
+callbacks.register('start_page_number', function() end, "actions performed at the beginning of a shipout")
+callbacks.register('stop_page_number', function() end, "actions performed at the end of a shipout")
callbacks.register('process_input_buffer', false, "actions performed when reading data")
callbacks.register('process_output_buffer', false, "actions performed when writing data")
callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump
-if LUATEXFUNCTIONALITY and LUATEXFUNCTIONALITY > 6505 then
- callbacks.register("finish_synctex", wrapup_synctex, "rename temporary synctex file")
- callbacks.register('wrapup_run', false, "actions performed after closing files")
-else
- callbacks.register("finish_synctex_callback", wrapup_synctex, "rename temporary synctex file")
-end
+-- finish_synctex might go away (move to wrapup_run)
+
+callbacks.register("finish_synctex", wrapup_synctex, "rename temporary synctex file")
+callbacks.register('wrapup_run', wrapup_run, "actions performed after closing files")
+
+-- temp hack for testing:
+
+callbacks.functions.start_page_number = start_shipout_page
+callbacks.functions.stop_page_number = stop_shipout_page
-- an example:
@@ -176,14 +205,6 @@ luatex.registerstopactions(luatex.cleanuptempfiles)
-- filenames
-local types = {
- "data",
- "font map",
- "image",
- "font subset",
- "full font",
-}
-
local report_open = logs.reporter("open source")
local report_close = logs.reporter("close source")
local report_load = logs.reporter("load resource")
@@ -199,15 +220,8 @@ function luatex.currentfile()
return stack[#stack] or tex.jobname
end
-local function report_start(left,name)
- if not left then
- -- skip
- elseif left ~= 1 then
- if all then
- -- report_load("%s > %s",types[left],name or "?")
- report_load("type %a, name %a",types[left],name or "?")
- end
- elseif find(name,"virtual://",1,true) then
+local function report_start(name)
+ if find(name,"virtual://",1,true) then
insert(stack,false)
else
insert(stack,name)
@@ -219,16 +233,47 @@ local function report_start(left,name)
end
end
-local function report_stop(right)
- if level == 1 or not right or right == 1 then
- local name = remove(stack)
- if name then
- -- report_close("%i > %i > %s",level,total,name or "?")
- report_close("level %i, order %i, name %a",level,total,name or "?")
- level = level - 1
- synctex.setfilename(stack[#stack] or tex.jobname)
+local function report_stop()
+ local name = remove(stack)
+ if name then
+ -- report_close("%i > %i > %s",level,total,name or "?")
+ report_close("level %i, order %i, name %a",level,total,name or "?")
+ level = level - 1
+ synctex.setfilename(stack[#stack] or tex.jobname)
+ end
+end
+
+if CONTEXTLMTXMODE < 2 then
+
+ local types = {
+ "data",
+ "font map",
+ "image",
+ "font subset",
+ "full font",
+ }
+
+ local do_report_start = report_start
+ local do_report_stop = report_stop
+
+ report_start = function(left,name)
+ if not left then
+ -- skip
+ elseif left ~= 1 then
+ if all then
+ report_load("type %a, name %a",types[left],name or "?")
+ end
+ else
+ do_report_start(name)
+ end
+ end
+
+ report_stop = function(right)
+ if level == 1 or not right or right == 1 then
+ do_report_stop()
end
end
+
end
local function report_none()
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-soc.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-soc.lua
deleted file mode 100644
index 9342a4b3375..00000000000
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-soc.lua
+++ /dev/null
@@ -1,11 +0,0 @@
--- This is just a loader. The package handler knows about the TEX tree.
-
--- require "luatex/lua/socket.lua"
--- require "luatex/lua/ltn12.lua"
--- require "luatex/lua/mime.lua"
--- require "luatex/lua/socket/http.lua"
--- require "luatex/lua/socket/url.lua"
--- require "luatex/lua/socket/tp.lua"
--- require "luatex/lua/socket/ftp.lua"
-
--- "luatex/lua/socket/smtp.lua"
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-soc.mkiv b/Master/texmf-dist/tex/context/base/mkiv/luat-soc.mkiv
new file mode 100644
index 00000000000..b2ce7048395
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-soc.mkiv
@@ -0,0 +1,52 @@
+%D \module
+%D [ file=luat-soc,
+%D version=2018.08.05,
+%D title=\CONTEXT\ Lua Macros,
+%D subtitle=Socket Libraries,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Lua Macros / Socket Libraries}
+
+%D In \LUATEX\ we provide the socket library that is more or less the standard one
+%D for \LUA. It has been around for a while and seems to be pretty stable. The
+%D binary module is copmpiled into \LUATEX\ and the accompanying .lua files are
+%D preloaded. These files are mostly written by Diego Nehab, Andre Carregal, Javier
+%D Guerra, and Fabio Mascarenhas with contributions from Diego Nehab, Mike Pall,
+%D David Burgess, Leonardo Godinho, Thomas Harning Jr., and Gary NG. The originals
+%D are part of and copyrighted by the Kepler project.
+%D
+%D Here we reload a slightly reworked version of these \type {.lua} files. We keep
+%D the same (documented) interface but streamlined some fo the code. No more
+%D modules, no more pre 5.2 \LUA, etc. Also, as it loads into the \CONTEXT
+%D ecosystem, we plug in some logging. (and maybe tracing in the future). As we
+%D don't support serial ports in \LUATEX, related code has been dropped.
+%D
+%D The files are reformatted so that we can more easilly add additional features
+%D and|/|or tracing options. Any error introduced there is our fault! The url module
+%D might be replaced by the one in \CONTEXT. When we need mbox a suitable variant
+%D will be provided.
+
+%D Currently we preload the related \LUA\ code in \LUATEX, but that might change at
+%D some point. We're prepared for that.
+
+% \registerctxluafile{util-soc-imp-reset} {}
+%
+% \registerctxluafile{util-soc-imp-socket} {}
+% % registerctxluafile{util-soc-imp-copas} {}
+% \registerctxluafile{util-soc-imp-ltn12} {}
+% % registerctxluafile{util-soc-imp-mbox} {}
+% \registerctxluafile{util-soc-imp-mime} {}
+% \registerctxluafile{util-soc-imp-url} {}
+% \registerctxluafile{util-soc-imp-headers}{}
+% \registerctxluafile{util-soc-imp-http} {}
+% \registerctxluafile{util-soc-imp-tp} {}
+% % registerctxluafile{util-soc-imp-ftp} {}
+% % registerctxluafile{util-soc-imp-smtp} {}
+
+\endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-sto.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-sto.lua
index e67830b0db4..ce891765aa9 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-sto.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-sto.lua
@@ -78,7 +78,7 @@ if environment.initex then
dumped = concat({ definition, comment, dumped },"\n")
local code = nil
local name = formatters["slot %s (%s)"](max,name)
- if LUAVERSION >= 5.3 and LUATEXFUNCTIONALITY >= 6454 then
+ if LUAVERSION >= 5.3 then
local code = loadstring(dumped,name)
setbytecode(max,code,strip)
else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-usr.lua b/Master/texmf-dist/tex/context/base/mkiv/luat-usr.lua
index ebcb0f0e82a..b49379bbf05 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-usr.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-usr.lua
@@ -26,8 +26,6 @@ local io = io
local os = os
local lpeg = lpeg
-local luanames = lua.name -- luatex itself
-
local setmetatableindex = table.setmetatableindex
local load = load
local xpcall = xpcall
@@ -135,7 +133,6 @@ local function registername(name,message)
messages[lnn] = message
numbers[name] = lnn
end
- luanames[lnn] = instance_banner(message)
local report = reporter("lua instance",message)
local proxy = {
-- we can access all via:
diff --git a/Master/texmf-dist/tex/context/base/mkiv/luat-usr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/luat-usr.mkiv
index 760de9f213f..f3868ccf4bc 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/luat-usr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/luat-usr.mkiv
@@ -69,7 +69,7 @@
\obeyluatokens
\csname\??luacode#1\endcsname}%
%
- \global\expandafter\let\csname\s!stop#1\s!code\endcsname\relax
+ \expandafter\glet\csname\s!stop#1\s!code\endcsname\relax
%
\normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\s!stop#1\s!code\endcsname}%
{\noexpand\expandafter\endgroup
@@ -77,7 +77,7 @@
\expandafter\noexpand\csname clf_\fullname\endcsname
\noexpand\expandafter{\noexpand\normalexpanded{##1}}}%
%
- \global\expandafter\let\csname#1\s!code\expandafter\endcsname\csname clf_\fullname\endcsname
+ \expandafter\glet\csname#1\s!code\expandafter\endcsname\csname clf_\fullname\endcsname
\fi
\fi
\egroup}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-aux.lua b/Master/texmf-dist/tex/context/base/mkiv/lxml-aux.lua
index 78cf1d6bd58..ed0f03fd8c7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-aux.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-aux.lua
@@ -134,10 +134,12 @@ end
function xml.collect_tags(root, pattern, nonamespace)
local collected = xmlapplylpath(root,pattern)
if collected then
- local t, n = { }, 0
+ local t = { }
+ local n = 0
for c=1,#collected do
- local e = collected[c]
- local ns, tg = e.ns, e.tg
+ local e = collected[c]
+ local ns = e.ns
+ local tg = e.tg
n = n + 1
if nonamespace then
t[n] = tg
@@ -226,7 +228,7 @@ function xml.delete(root,pattern)
if trace_manipulations then
report('deleting',pattern,c,e)
end
- local d = p.dt
+ local d = p.dt
local ni = e.ni
if ni <= #d then
if false then
@@ -313,8 +315,10 @@ local function inject_element(root,pattern,whatever,prepend)
local element = root and xmltoelement(whatever,root)
local collected = element and xmlapplylpath(root,pattern)
local function inject_e(e)
- local r = e.__p__
- local d, k, rri = r.dt, e.ni, r.ri
+ local r = e.__p__
+ local d = r.dt
+ local k = e.ni
+ local rri = r.ri
local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt)
if edt then
local be, af
@@ -354,7 +358,8 @@ local function insert_element(root,pattern,whatever,before) -- todo: element als
local collected = element and xmlapplylpath(root,pattern)
local function insert_e(e)
local r = e.__p__
- local d, k = r.dt, e.ni
+ local d = r.dt
+ local k = e.ni
if not before then
k = k + 1
end
@@ -860,8 +865,10 @@ function xml.separate(x,pattern)
report_xml("warning: xml.separate changes root")
x = d
end
- local t, n = { "\n" }, 1
- local i, nd = 1, #d
+ local t = { "\n" }
+ local n = 1
+ local i = 1
+ local nd = #d
while i <= nd do
while i <= nd do
local di = d[i]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-css.lua b/Master/texmf-dist/tex/context/base/mkiv/lxml-css.lua
index 1787c53df18..b0f5c9b72f6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-css.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-css.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['lxml-css'] = {
license = "see context related readme files"
}
-local tonumber, rawset, type = tonumber, rawset, type
+local tonumber, rawset, type, select = tonumber, rawset, type, select
local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch
local topattern, is_empty = string.topattern, string.is_empty
local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs
@@ -118,24 +118,33 @@ css.padding = padding
-- print(padding("0",pixel,hsize,exheight,emwidth))
--- local currentfont = font.current
--- local texget = tex.get
--- local hashes = fonts.hashes
--- local quads = hashes.quads
--- local xheights = hashes.xheights
---
--- local function padding(str)
--- local font = currentfont()
--- local exheight = xheights[font]
--- local emwidth = quads[font]
--- local hsize = texget("hsize")/100
--- local pixel = emwidth/100
--- return padding(str,pixel,hsize,exheight,emwidth)
--- end
---
--- function css.simplepadding(str)
--- context("%ssp",padding(str,pixel,hsize,exheight,emwidth))
--- end
+local context = context
+
+if context then
+
+ local currentfont = font.current
+ local texget = tex.get
+ local hashes = fonts.hashes
+ local quads = hashes.quads
+ local xheights = hashes.xheights
+
+ local function todimension(str)
+ local font = currentfont()
+ local exheight = xheights[font]
+ local emwidth = quads[font]
+ local hsize = texget("hsize")/100
+ local pixel = emwidth/100
+ return dimension(str,pixel,hsize,exheight,emwidth)
+ end
+
+ css.todimension = todimension
+
+ function context.cssdimension(str)
+ -- context("%ssp",todimension(str))
+ context(todimension(str) .. "sp")
+ end
+
+end
local pattern = Cf( Ct("") * (
Cg(
@@ -949,7 +958,7 @@ local someaction = skipspace * colon * skipspace * (somevalue/ctx_sprint)
-- -- cache patterns (2.13):
-local patterns= setmetatableindex(function(t,k)
+local patterns = setmetatableindex(function(t,k)
local v = P(k * someaction + 1)^0
t[k] = v
return v
@@ -993,3 +1002,91 @@ interfaces.implement {
actions = css.mappedstylevalue,
arguments = "3 strings",
}
+
+-- more (for mm)
+
+local containsws = string.containsws
+local classsplitter = lpeg.tsplitat(whitespace^1)
+
+function xml.functions.classes(e,class) -- cache
+ if class then
+ local at = e.at
+ local data = at[class] or at.class
+ if data then
+ return lpegmatch(classsplitter,data) or { }
+ end
+ end
+ return { }
+end
+
+-- function xml.functions.hasclass(e,class,name)
+-- if class then
+-- local at = e.at
+-- local data = at[class] or at.class
+-- if data then
+-- return data == name or containsws(data,name)
+-- end
+-- end
+-- return false
+-- end
+--
+-- function xml.expressions.hasclass(attribute,name)
+-- if attribute then
+-- return attribute == name or containsws(attribute,name)
+-- end
+-- return false
+-- end
+
+function xml.functions.hasclass(e,class,name,more,...)
+ if class and name then
+ local at = e.at
+ local data = at[class] or at.class
+ if not data or data == "" then
+ return false
+ end
+ if data == name or data == more then
+ return true
+ end
+ if containsws(data,name) then
+ return true
+ end
+ if not more then
+ return false
+ end
+ if containsws(data,more) then
+ return true
+ end
+ for i=1,select("#",...) do
+ if containsws(data,select(i,...)) then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+function xml.expressions.hasclass(data,name,more,...)
+ if data then
+ if not data or data == "" then
+ return false
+ end
+ if data == name or data == more then
+ return true
+ end
+ if containsws(data,name) then
+ return true
+ end
+ if not more then
+ return false
+ end
+ if containsws(data,more) then
+ return true
+ end
+ for i=1,select("#",...) do
+ if containsws(data,select(i,...)) then
+ return true
+ end
+ end
+ end
+ return false
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-inf.lua b/Master/texmf-dist/tex/context/base/mkiv/lxml-inf.lua
index 8d99d627031..6fb64c0fef6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-inf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-inf.lua
@@ -17,7 +17,8 @@ local getid = lxml.getid
local status, stack
local function get(e,d)
- local ns, tg = e.ns, e.tg
+ local ns = e.ns
+ local tg = e.tg
local name = tg
if ns ~= "" then name = ns .. ":" .. tg end
stack[d] = name
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/lxml-ini.mkiv
index 7c97ffb2c77..5cb4bb22d65 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-ini.mkiv
@@ -36,11 +36,11 @@
% for now indirect
-\def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}}
-\def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange {#1}{#2}{#3}{#4}{\detokenize{#5}}}
-\def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!compress}}
-\def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!compress}}
-\def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!compress}}
+\def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}}
+\def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange{#1}{#2}{#3}{#4}{\detokenize{#5}}}
+\def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!compress}}
+\def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!compress}}
+\def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!compress}}
% aliased
@@ -231,6 +231,7 @@
\unexpanded\def\xmlremovedocumentsetup #1#2{\clf_xmlremovesetup {#1}{#2}}
\unexpanded\def\xmlresetdocumentsetups #1{\clf_xmlresetsetups {#1}}
+\unexpanded\def\xmlflushsetups #1{\clf_xmlflushsetups {#1}{*}{}} % #1 == id where to apply *
\unexpanded\def\xmlflushdocumentsetups #1#2{\clf_xmlflushsetups {#1}{*}{#2}} % #1 == id where to apply * and #2
\let\xmlregistersetup \xmlappendsetup
@@ -240,7 +241,7 @@
\unexpanded\def\xmlregisteredsetups
{\xmlstarttiming
- \xmlflushsetups
+ \xmlflushsetups\xmldocument
\xmldefaulttotext\xmldocument % after include
\xmlstoptiming}
@@ -260,8 +261,8 @@
%xmlpushdocument{#3}%
#2{#3}{#4}%
\setcatcodetable\notcatcodes
- \doifelsenothing{#5}
- {\xmlsetup{#3}{xml:process}}
+ \doifelsenothing{#5}%
+ {\xmlsetup{#3}{xml:process}}%
{\xmlsetup{#3}{#5}}%
%xmlpopdocument
\endgroup}
@@ -326,7 +327,7 @@
\fi
\unexpanded\def\stopxmldisplayverbatim
{\endofverbatimlines
- \stoppacked}
+ \stoppacked}%
\doinitializeverbatim
\beginofverbatimlines}
@@ -404,7 +405,7 @@
\c!entities=\v!no] % load big entity file
\appendtoks
- \doif{\directxmlparameter\c!entities}\clf_xmlloadentities
+ \doif{\directxmlparameter\c!entities}\v!yes\clf_xmlloadentities
\to \everysetupxml
\def\xmlmapvalue #1#2#3{\setvalue{\??xmlmapvalue#1:#2}{#3}} % keep #3 to grab spaces
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-lpt.lua b/Master/texmf-dist/tex/context/base/mkiv/lxml-lpt.lua
index bb6fb456816..392c1a4014e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-lpt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-lpt.lua
@@ -157,32 +157,47 @@ apply_axis['root'] = function(list)
end
apply_axis['self'] = function(list)
---~ local collected = { }
---~ for l=1,#list do
---~ collected[l] = list[l]
---~ end
---~ return collected
+ -- local collected = { }
+ -- for l=1,#list do
+ -- collected[l] = list[l]
+ -- end
+ -- return collected
return list
end
apply_axis['child'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
local dt = ll.dt
if dt then -- weird that this is needed
- local en = 0
- for k=1,#dt do
- local dk = dt[k]
+ local n = #dt
+ if n == 0 then
+ ll.en = 0
+ elseif n == 1 then
+ local dk = dt[1]
if dk.tg then
c = c + 1
collected[c] = dk
- dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ dk.ni = 1 -- refresh
+ dk.ei = 1
+ ll.en = 1
end
+ else
+ local en = 0
+ for k=1,#dt do
+ local dk = dt[k]
+ if dk.tg then
+ c = c + 1
+ en = en + 1
+ collected[c] = dk
+ dk.ni = k -- refresh
+ dk.ei = en
+ end
+ end
+ ll.en = en
end
- ll.en = en
end
end
return collected
@@ -191,25 +206,43 @@ end
local function collect(list,collected,c)
local dt = list.dt
if dt then
- local en = 0
- for k=1,#dt do
- local dk = dt[k]
+ local n = #dt
+ if n == 0 then
+ list.en = 0
+ elseif n == 1 then
+ local dk = dt[1]
if dk.tg then
c = c + 1
collected[c] = dk
- dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ dk.ni = 1 -- refresh
+ dk.ei = 1
c = collect(dk,collected,c)
+ list.en = 1
+ else
+ list.en = 0
end
+ else
+ local en = 0
+ for k=1,n do
+ local dk = dt[k]
+ if dk.tg then
+ c = c + 1
+ en = en + 1
+ collected[c] = dk
+ dk.ni = k -- refresh
+ dk.ei = en
+ c = collect(dk,collected,c)
+ end
+ end
+ list.en = en
end
- list.en = en
end
return c
end
apply_axis['descendant'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
c = collect(list[l],collected,c)
end
@@ -219,24 +252,41 @@ end
local function collect(list,collected,c)
local dt = list.dt
if dt then
- local en = 0
- for k=1,#dt do
- local dk = dt[k]
+ local n = #dt
+ if n == 0 then
+ list.en = 0
+ elseif n == 1 then
+ local dk = dt[1]
if dk.tg then
c = c + 1
collected[c] = dk
- dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ dk.ni = 1 -- refresh
+ dk.ei = 1
c = collect(dk,collected,c)
+ list.en = 1
end
+ else
+ local en = 0
+ for k=1,#dt do
+ local dk = dt[k]
+ if dk.tg then
+ c = c + 1
+ en = en + 1
+ collected[c] = dk
+ dk.ni = k -- refresh
+ dk.ei = en
+ c = collect(dk,collected,c)
+ end
+ end
+ list.en = en
end
- list.en = en
end
return c
end
+
apply_axis['descendant-or-self'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
if ll.special ~= true then -- catch double root
@@ -249,7 +299,8 @@ apply_axis['descendant-or-self'] = function(list)
end
apply_axis['ancestor'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
while ll do
@@ -264,7 +315,8 @@ apply_axis['ancestor'] = function(list)
end
apply_axis['ancestor-or-self'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
c = c + 1
@@ -281,7 +333,8 @@ apply_axis['ancestor-or-self'] = function(list)
end
apply_axis['parent'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local pl = list[l].__p__
if pl then
@@ -301,45 +354,47 @@ apply_axis['namespace'] = function(list)
end
apply_axis['following'] = function(list) -- incomplete
---~ local collected, c = { }, 0
---~ for l=1,#list do
---~ local ll = list[l]
---~ local p = ll.__p__
---~ local d = p.dt
---~ for i=ll.ni+1,#d do
---~ local di = d[i]
---~ if type(di) == "table" then
---~ c = c + 1
---~ collected[c] = di
---~ break
---~ end
---~ end
---~ end
---~ return collected
+ -- local collected, c = { }, 0
+ -- for l=1,#list do
+ -- local ll = list[l]
+ -- local p = ll.__p__
+ -- local d = p.dt
+ -- for i=ll.ni+1,#d do
+ -- local di = d[i]
+ -- if type(di) == "table" then
+ -- c = c + 1
+ -- collected[c] = di
+ -- break
+ -- end
+ -- end
+ -- end
+ -- return collected
return { }
end
apply_axis['preceding'] = function(list) -- incomplete
---~ local collected, c = { }, 0
---~ for l=1,#list do
---~ local ll = list[l]
---~ local p = ll.__p__
---~ local d = p.dt
---~ for i=ll.ni-1,1,-1 do
---~ local di = d[i]
---~ if type(di) == "table" then
---~ c = c + 1
---~ collected[c] = di
---~ break
---~ end
---~ end
---~ end
---~ return collected
+ -- local collected = { }
+ -- local c = 0
+ -- for l=1,#list do
+ -- local ll = list[l]
+ -- local p = ll.__p__
+ -- local d = p.dt
+ -- for i=ll.ni-1,1,-1 do
+ -- local di = d[i]
+ -- if type(di) == "table" then
+ -- c = c + 1
+ -- collected[c] = di
+ -- break
+ -- end
+ -- end
+ -- end
+ -- return collected
return { }
end
apply_axis['following-sibling'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -356,7 +411,8 @@ apply_axis['following-sibling'] = function(list)
end
apply_axis['preceding-sibling'] = function(list)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -373,7 +429,8 @@ apply_axis['preceding-sibling'] = function(list)
end
apply_axis['reverse-sibling'] = function(list) -- reverse preceding
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -400,7 +457,8 @@ local function apply_nodes(list,directive,nodes)
-- ... currently ignored
local maxn = #nodes
if maxn == 3 then --optimized loop
- local nns, ntg = nodes[2], nodes[3]
+ local nns = nodes[2]
+ local ntg = nodes[3]
if not nns and not ntg then -- wildcard
if directive then
return list
@@ -408,40 +466,47 @@ local function apply_nodes(list,directive,nodes)
return { }
end
else
- local collected, c, m, p = { }, 0, 0, nil
+ local collected = { }
+ local c = 0
+ local m = 0
+ local p = nil
if not nns then -- only check tag
for l=1,#list do
- local ll = list[l]
+ local ll = list[l]
local ltg = ll.tg
if ltg then
if directive then
if ntg == ltg then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
elseif ntg ~= ltg then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
end
end
elseif not ntg then -- only check namespace
for l=1,#list do
- local ll = list[l]
+ local ll = list[l]
local lns = ll.rn or ll.ns
if lns then
if directive then
if lns == nns then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
elseif lns ~= nns then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
end
end
@@ -454,14 +519,16 @@ local function apply_nodes(list,directive,nodes)
local ok = ltg == ntg and lns == nns
if directive then
if ok then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
elseif not ok then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
end
end
@@ -469,15 +536,19 @@ local function apply_nodes(list,directive,nodes)
return collected
end
else
- local collected, c, m, p = { }, 0, 0, nil
+ local collected = { }
+ local c = 0
+ local m = 0
+ local p = nil
for l=1,#list do
- local ll = list[l]
+ local ll = list[l]
local ltg = ll.tg
if ltg then
local lns = ll.rn or ll.ns
- local ok = false
+ local ok = false
for n=1,maxn,3 do
- local nns, ntg = nodes[n+1], nodes[n+2]
+ local nns = nodes[n+1]
+ local ntg = nodes[n+2]
ok = (not ntg or ltg == ntg) and (not nns or lns == nns)
if ok then
break
@@ -485,14 +556,16 @@ local function apply_nodes(list,directive,nodes)
end
if directive then
if ok then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
elseif not ok then
- local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
+ local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end
c = c + 1
- collected[c], ll.mi = ll, m
+ collected[c] = ll
+ ll.mi = m
end
end
end
@@ -503,7 +576,8 @@ end
local quit_expression = false
local function apply_expression(list,expression,order)
- local collected, c = { }, 0
+ local collected = { }
+ local c = 0
quit_expression = false
for l=1,#list do
local ll = list[l]
@@ -900,7 +974,8 @@ local function tagstostring(list)
local t = { }
for i=1, #list do
local li = list[i]
- local ns, tg = li.ns, li.tg
+ local ns = li.ns
+ local tg = li.tg
if not ns or ns == "" then ns = "*" end
if not tg or tg == "" then tg = "*" end
t[i] = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg)
@@ -1365,7 +1440,8 @@ expressions.name = function(e,n) -- ns + tg
if n == 0 then
found = type(e) == "table" and e
elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
+ local d = e.__p__.dt
+ local k = e.ni
for i=k-1,1,-1 do
local di = d[i]
if type(di) == "table" then
@@ -1378,7 +1454,8 @@ expressions.name = function(e,n) -- ns + tg
end
end
else
- local d, k = e.__p__.dt, e.ni
+ local d = e.__p__.dt
+ local k = e.ni
for i=k+1,#d,1 do
local di = d[i]
if type(di) == "table" then
@@ -1392,7 +1469,8 @@ expressions.name = function(e,n) -- ns + tg
end
end
if found then
- local ns, tg = found.rn or found.ns or "", found.tg
+ local ns = found.rn or found.ns or ""
+ local tg = found.tg
if ns ~= "" then
return ns .. ":" .. tg
else
@@ -1412,7 +1490,8 @@ expressions.tag = function(e,n) -- only tg
if n == 0 then
found = (type(e) == "table") and e -- seems to fail
elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
+ local d = e.__p__.dt
+ local k = e.ni
for i=k-1,1,-1 do
local di = d[i]
if type(di) == "table" then
@@ -1425,7 +1504,8 @@ expressions.tag = function(e,n) -- only tg
end
end
else
- local d, k = e.__p__.dt, e.ni
+ local d = e.__p__.dt
+ local k = e.ni
for i=k+1,#d,1 do
local di = d[i]
if type(di) == "table" then
@@ -1592,8 +1672,8 @@ end
-- local w = lpeg.patterns.whitespace
-- local p = w^0 * lpeg.Cf(lpeg.Ct("") * lpeg.Cg(lpeg.C((1-w)^1) * lpeg.Cc(true) * w^0)^1,rawset)
--- function xml.functions.classes(e) -- cache
--- local class = e.at.class
+-- function xml.functions.classes(e,class) -- cache
+-- class = class and e.at[class] or e.at.class
-- if class then
-- return lpegmatch(p,class)
-- else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua b/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua
index b8280ba9c63..ae3edba5613 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua
@@ -92,6 +92,8 @@ local forceraw = false
local p_texescape = patterns.texescape
+local tokenizedcs = context.tokenizedcs
+
directives.enable("xml.path.keeplastmatch")
-- tex entities
@@ -499,13 +501,29 @@ function lxml.checkindex(name)
return root and root.index or 0
end
-function lxml.withindex(name,n,command) -- will change as name is always there now
- local i, p = lpegmatch(splitter,n)
- if p then
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}")
- else
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}")
+if tokenizedcs then
+
+ function lxml.withindex(name,n,command) -- will change as name is always there now
+ local i, p = lpegmatch(splitter,n)
+ local w = tokenizedcs.xmlw
+ if p then
+ contextsprint(ctxcatcodes,w,"{",command,"}{",n,"}")
+ else
+ contextsprint(ctxcatcodes,w,"{",command,"}{",name,"::",n,"}")
+ end
+ end
+
+else
+
+ function lxml.withindex(name,n,command) -- will change as name is always there now
+ local i, p = lpegmatch(splitter,n)
+ if p then
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}")
+ else
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}")
+ end
end
+
end
function lxml.getindex(name,n) -- will change as name is always there now
@@ -728,21 +746,6 @@ end
local default_element_handler = xml.gethandlers("verbose").functions["@el@"]
--- local xmlw = setmetatableindex(function(t,k)
--- local v = setmetatableindex(function(t,kk)
--- local v
--- if kk == false then
--- v = "\\xmlw{" .. k .. "}{"
--- else
--- v = "\\xmlw{" .. k .. "}{" .. kk .. "::"
--- end
--- t[kk] = v
--- return v
--- end)
--- t[k]= v
--- return v
--- end)
-
local setfilename = false
local trace_name = false
local report_name = logs.reporter("lxml")
@@ -765,39 +768,80 @@ trackers.register("system.synctex.xml",function(v)
trace_name = v
end)
-local function tex_element(e,handlers)
- if setfilename then
- syncfilename(e,"element")
- end
- local command = e.command
- if command == nil then
- default_element_handler(e,handlers)
- elseif command == true then
- -- text (no ) / so, no mkii fallback then
- handlers.serialize(e.dt,handlers)
- elseif command == false then
- -- ignore
- else
- local tc = type(command)
- if tc == "string" then
- local rootname, ix = e.name, e.ix
- if rootname then
- if not ix then
- addindex(rootname,false,true)
- ix = e.ix
+local tex_element
+
+if tokenizedcs then
+
+ tex_element = function(e,handlers)
+ if setfilename then
+ syncfilename(e,"element")
+ end
+ local command = e.command
+ if command == nil then
+ default_element_handler(e,handlers)
+ elseif command == true then
+ -- text (no ) / so, no mkii fallback then
+ handlers.serialize(e.dt,handlers)
+ elseif command == false then
+ -- ignore
+ else
+ local tc = type(command)
+ if tc == "string" then
+ local rootname, ix = e.name, e.ix
+ local w = tokenizedcs.xmlw
+ if rootname then
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,w,"{",command,"}{",rootname,"::",ix,"}")
+ else
+ report_lxml("fatal error: no index for %a",command)
+ contextsprint(ctxcatcodes,w,"{",command,"}{",ix or 0,"}")
end
- -- faster than context.xmlw
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}")
- -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}")
- else
- report_lxml("fatal error: no index for %a",command)
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}")
- -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}")
+ elseif tc == "function" then
+ command(e)
+ end
+ end
+ end
+
+else
+
+ tex_element = function(e,handlers)
+ if setfilename then
+ syncfilename(e,"element")
+ end
+ local command = e.command
+ if command == nil then
+ default_element_handler(e,handlers)
+ elseif command == true then
+ -- text (no ) / so, no mkii fallback then
+ handlers.serialize(e.dt,handlers)
+ elseif command == false then
+ -- ignore
+ else
+ local tc = type(command)
+ if tc == "string" then
+ local rootname, ix = e.name, e.ix
+ if rootname then
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ -- faster than context.xmlw
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}")
+ -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}")
+ else
+ report_lxml("fatal error: no index for %a",command)
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}")
+ -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}")
+ end
+ elseif tc == "function" then
+ command(e)
end
- elseif tc == "function" then
- command(e)
end
end
+
end
--
@@ -1180,7 +1224,7 @@ function lxml.flushsetups(id,...)
local sd = setups[document]
if sd then
for k=1,#sd do
- local v= sd[k]
+ local v = sd[k]
if not done[v] then
if trace_loading then
report_lxml("applying setup %02i : %a to %a",k,v,document)
@@ -1442,29 +1486,63 @@ end
-- the number of commands is often relative small but there can be many calls
-- to this finalizer
-local function command(collected,cmd,otherwise)
- local n = collected and #collected
- if n and n > 0 then
- local wildcard = find(cmd,"*",1,true)
- for c=1,n do -- maybe optimize for n=1
- local e = collected[c]
- local ix = e.ix
- local name = e.name
- if name and not ix then
- addindex(name,false,true)
- ix = e.ix
- end
- if not ix or not name then
- report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
- elseif wildcard then
- contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
- else
- contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}")
+local command
+
+if tokenizedcs then
+
+ command = function(collected,cmd,otherwise)
+ local n = collected and #collected
+ local w = tokenizedcs.xmlw
+ if n and n > 0 then
+ local wildcard = find(cmd,"*",1,true)
+ for c=1,n do -- maybe optimize for n=1
+ local e = collected[c]
+ local ix = e.ix
+ local name = e.name
+ if name and not ix then
+ addindex(name,false,true)
+ ix = e.ix
+ end
+ if not ix or not name then
+ report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
+ elseif wildcard then
+ contextsprint(ctxcatcodes,w,"{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
+ else
+ contextsprint(ctxcatcodes,w,"{",cmd,"}{",name,"::",ix,"}")
+ end
+ end
+ elseif otherwise then
+ contextsprint(ctxcatcodes,w,"{",otherwise,"}{#1}")
+ end
+ end
+
+else
+
+ command = function(collected,cmd,otherwise)
+ local n = collected and #collected
+ if n and n > 0 then
+ local wildcard = find(cmd,"*",1,true)
+ for c=1,n do -- maybe optimize for n=1
+ local e = collected[c]
+ local ix = e.ix
+ local name = e.name
+ if name and not ix then
+ addindex(name,false,true)
+ ix = e.ix
+ end
+ if not ix or not name then
+ report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
+ elseif wildcard then
+ contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
+ else
+ contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}")
+ end
end
+ elseif otherwise then
+ contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}")
end
- elseif otherwise then
- contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}")
end
+
end
-- local wildcards = setmetatableindex(function(t,k)
@@ -1675,7 +1753,7 @@ local function concatrange(collected,start,stop,separator,lastseparator,textonly
end
end
-local function concat(collected,separator,lastseparator,textonly) -- test this on mml
+local function concatlist(collected,separator,lastseparator,textonly) -- test this on mml
concatrange(collected,false,false,separator,lastseparator,textonly)
end
@@ -1697,14 +1775,12 @@ texfinalizers.context = ctxtext
texfinalizers.position = position
texfinalizers.match = match
texfinalizers.index = index
-texfinalizers.concat = concat
+texfinalizers.concat = concatlist
texfinalizers.concatrange = concatrange
texfinalizers.chainattribute = chainattribute
texfinalizers.chainpath = chainpath
texfinalizers.default = all -- !!
-local concat = table.concat
-
function texfinalizers.tag(collected,n)
if collected then
local nc = #collected
@@ -1997,7 +2073,7 @@ do
implement {
name = "xmldoifatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doif(e and e.at[k] == v or false)
end
@@ -2006,7 +2082,7 @@ do
implement {
name = "xmldoifnotatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doifnot(e and e.at[k] == v or false)
end
@@ -2015,7 +2091,7 @@ do
implement {
name = "xmldoifelseatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doifelse(e and e.at[k] == v or false)
end
@@ -2139,24 +2215,51 @@ function lxml.direct(id)
end
end
-function lxml.command(id,pattern,cmd)
- local i, p = getid(id,true)
- local collected = xmlapplylpath(getid(i),pattern)
- if collected then
- local nc = #collected
- if nc > 0 then
- local rootname = p or i.name
- for c=1,nc do
- local e = collected[c]
- local ix = e.ix
- if not ix then
- addindex(rootname,false,true)
- ix = e.ix
+if tokenizedcs then
+
+ function lxml.command(id,pattern,cmd)
+ local i, p = getid(id,true)
+ local collected = xmlapplylpath(getid(i),pattern)
+ if collected then
+ local nc = #collected
+ if nc > 0 then
+ local rootname = p or i.name
+ local w = tokenizedcs.xmlw
+ for c=1,nc do
+ local e = collected[c]
+ local ix = e.ix
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,w,"{",cmd,"}{",rootname,"::",ix,"}")
+ end
+ end
+ end
+ end
+
+else
+
+ function lxml.command(id,pattern,cmd)
+ local i, p = getid(id,true)
+ local collected = xmlapplylpath(getid(i),pattern)
+ if collected then
+ local nc = #collected
+ if nc > 0 then
+ local rootname = p or i.name
+ for c=1,nc do
+ local e = collected[c]
+ local ix = e.ix
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
end
- contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
end
end
end
+
end
-- loops
@@ -2292,13 +2395,13 @@ function texfinalizers.lettered(collected)
end
end
---~ function texfinalizers.apply(collected,what) -- to be tested
---~ if collected then
---~ for c=1,#collected do
---~ contextsprint(ctxcatcodes,what(collected[c].dt[1]))
---~ end
---~ end
---~ end
+-- function texfinalizers.apply(collected,what) -- to be tested
+-- if collected then
+-- for c=1,#collected do
+-- contextsprint(ctxcatcodes,what(collected[c].dt[1]))
+-- end
+-- end
+-- end
function lxml.toparameters(id)
local e = getid(id)
@@ -2357,49 +2460,56 @@ end
-- parameters
-function lxml.setatt(id,name,value)
- local e = getid(id)
- if e then
- local a = e.at
- if a then
- a[name] = value
- else
- e.at = { [name] = value }
+do
+
+ local function setatt(id,name,value)
+ local e = getid(id)
+ if e then
+ local a = e.at
+ if a then
+ a[name] = value
+ else
+ e.at = { [name] = value }
+ end
end
end
-end
-function lxml.setpar(id,name,value)
- local e = getid(id)
- if e then
- local p = e.pa
- if p then
- p[name] = value
- else
- e.pa = { [name] = value }
+ local function setpar(id,name,value)
+ local e = getid(id)
+ if e then
+ local p = e.pa
+ if p then
+ p[name] = value
+ else
+ e.pa = { [name] = value }
+ end
end
end
-end
-function lxml.setattribute(id,pattern,name,value)
- local collected = xmlapplylpath(getid(id),pattern)
- if collected then
- for i=1,#collected do
- setatt(collected[i],name,value)
+ lxml.setatt = setatt
+ lxml.setpar = setpar
+
+ function lxml.setattribute(id,pattern,name,value)
+ local collected = xmlapplylpath(getid(id),pattern)
+ if collected then
+ for i=1,#collected do
+ setatt(collected[i],name,value)
+ end
end
end
-end
-function lxml.setparameter(id,pattern,name,value)
- local collected = xmlapplylpath(getid(id),pattern)
- if collected then
- for i=1,#collected do
- setpar(collected[i],name,value)
+ function lxml.setparameter(id,pattern,name,value)
+ local collected = xmlapplylpath(getid(id),pattern)
+ if collected then
+ for i=1,#collected do
+ setpar(collected[i],name,value)
+ end
end
end
-end
-lxml.setparam = lxml.setparameter
+ lxml.setparam = lxml.setparameter
+
+end
-- relatively new:
@@ -2629,3 +2739,59 @@ function texfinalizers.xml(collected,name,setup)
buffers.assign(name,strip(xmltostring(root)))
context.xmlprocessbuffer(name,name,setup or (name..":setup"))
end
+
+-- experiment
+
+do
+
+ local xmltoelement = xml.toelement
+ local xmlreindex = xml.reindex
+
+ function lxml.replace(root,pattern,whatever)
+ if type(root) == "string" then
+ root = lxml.getid(root)
+ end
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ local isstring = type(whatever) == "string"
+ for c=1,#collected do
+ local e = collected[c]
+ local p = e.__p__
+ if p then
+ local d = p.dt
+ local n = e.ni
+ local w = isstring and whatever or whatever(e)
+ if w then
+ local t = xmltoelement(w,root).dt
+ if t then
+ t.__p__ = p
+ if type(t) == "table" then
+ local t1 = t[1]
+ d[n] = t1
+ t1.at.type = e.at.type or t1.at.type
+ for i=2,#t do
+ n = n + 1
+ insert(d,n,t[i])
+ end
+ else
+ d[n] = t
+ end
+ xmlreindex(d) -- probably not needed
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- function document.mess_around(root)
+ -- lxml.replace(
+ -- root,
+ -- "p[@variant='foo']",
+ -- function(c)
+ -- return (string.gsub(tostring(c),"foo","%1 "))
+ -- end
+ -- )
+ -- end
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv b/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv
index b74b8c3d0d3..154e4780427 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv
@@ -186,6 +186,7 @@
\definefontfeature
[arabic-node]
[arabic]
+ [salt=yes] % seems to be needed for husayni
\definefontfeature
[arabic-native]
@@ -224,7 +225,7 @@
\getbuffer[#5-definitions]
\showfontkerns
\showmakeup[discretionary]
- \enabletrackers[fonts.plugins.hb.colors]%
+ % \enabletrackers[fonts.plugins.hb.colors]%
\testfeatureonce{1}{
\getbuffer[#5-text]
}
@@ -263,7 +264,7 @@
\title{#1 #3 #4}
\start
\getbuffer[#5-definitions]
- \enabletrackers[fonts.plugins.hb.colors]%
+ % \enabletrackers[fonts.plugins.hb.colors]%
\testfeatureonce{1}{
\setupalign[flushleft] % easier to compare
\getbuffer[#5-text]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-act.lua b/Master/texmf-dist/tex/context/base/mkiv/math-act.lua
index 77a355b225f..07ef32746a4 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-act.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-act.lua
@@ -23,6 +23,12 @@ local mathematics = mathematics
local texsetdimen = tex.setdimen
local abs = math.abs
+local helpers = fonts.helpers
+local upcommand = helpers.commands.up
+local rightcommand = helpers.commands.right
+local charcommand = helpers.commands.char
+local prependcommands = helpers.prependcommands
+
local sequencers = utilities.sequencers
local appendgroup = sequencers.appendgroup
local appendaction = sequencers.appendaction
@@ -237,7 +243,6 @@ function mathematics.overloaddimensions(target,original,set)
local factor = parameters.factor
local hfactor = parameters.hfactor
local vfactor = parameters.vfactor
- local addprivate = fonts.helpers.addprivate
-- to be sure
target.type = "virtual"
target.properties.virtualized = true
@@ -257,7 +262,8 @@ function mathematics.overloaddimensions(target,original,set)
local height = data.height
local depth = data.depth
if trace_defining and (width or height or depth) then
- report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth)
+ report_math("overloading dimensions of %C, width %p, height %p, depth %p",
+ unicode,width or 0,height or 0,depth or 0)
end
if width then character.width = width * hfactor end
if height then character.height = height * vfactor end
@@ -270,25 +276,26 @@ function mathematics.overloaddimensions(target,original,set)
if d then
xoffset = - d.boundingbox[1] * hfactor
character.width = character.width + xoffset
- xoffset = { "right", xoffset }
+ xoffset = rightcommand[xoffset]
+ else
+ xoffset = nil
end
- elseif xoffset then
- xoffset = { "right", xoffset * hfactor }
+ elseif xoffset and xoffset ~= 0 then
+ xoffset = rightcommand[xoffset * hfactor]
+ else
+ xoffset = nil
end
- if yoffset then
- yoffset = { "down", -yoffset * vfactor }
+ if yoffset and yoffset ~= 0 then
+ yoffset = upcommand[yoffset * vfactor]
+ else
+ yoffset = nil
end
if xoffset or yoffset then
- if character.commands then
- if yoffset then
- insert(character.commands,1,yoffset)
- end
- if xoffset then
- insert(character.commands,1,xoffset)
- end
+ local commands = characters.commands
+ if commands then
+ prependcommands(commands,yoffset,xoffset)
else
- -- local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) }
- local slot = { "slot", 0, addprivate(target,nil,fastcopy(character)) }
+ local slot = charcommand[unicode]
if xoffset and yoffset then
character.commands = { xoffset, yoffset, slot }
elseif xoffset then
@@ -297,7 +304,6 @@ function mathematics.overloaddimensions(target,original,set)
character.commands = { yoffset, slot }
end
end
- character.index = nil
end
elseif trace_defining then
report_math("no overloading dimensions of %C, not in font",unicode)
@@ -732,9 +738,9 @@ function mathematics.finishfallbacks(target,specification,fallbacks)
done[unic] = true
end
end
+ local step = offset - start
for unicode = start, stop do
- local unic = unicode + offset - start
- remap(unic,unicode,false)
+ remap(unicode + step,unicode,false)
end
if gaps then
for unic, unicode in next, gaps do
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-ali.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-ali.mkiv
index 083fb764540..ecfac68870f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-ali.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-ali.mkiv
@@ -321,11 +321,18 @@
\def\math_alignment_EQ
{\NC=}
+\installmacrostack\NC % maybe more to shared table definitions
+\installmacrostack\NN % maybe more to shared table definitions
+\installmacrostack\EQ % maybe more to shared table definitions
+\installmacrostack\NR % maybe more to shared table definitions
+\installmacrostack\BC % maybe more to shared table definitions
+\installmacrostack\EC % maybe more to shared table definitions
+
\appendtoks
- \pushmacro\NC
- \pushmacro\NN
- \pushmacro\EQ
- \pushmacro\NR
+ \push_macro_NC
+ \push_macro_NN
+ \push_macro_EQ
+ \push_macro_NR
\let\NC\math_alignment_NC
\let\NN\math_alignment_NN
\let\EQ\math_alignment_EQ
@@ -334,10 +341,10 @@
\to \everymathalignment
\appendtoks
- \popmacro\NR
- \popmacro\EQ
- \popmacro\NN
- \popmacro\NC
+ \pop_macro_NR
+ \pop_macro_EQ
+ \pop_macro_NN
+ \pop_macro_NC
\to \everymathalignmentdone
\let\math_alignment_snap_start\relax
@@ -694,11 +701,11 @@
{\unskip
\math_cases_end_math
\aligntab
- \global\let\math_cases_NC\math_cases_NC_first
+ \glet\math_cases_NC\math_cases_NC_first
\dodirectdoubleempty\math_cases_NR}
\def\math_cases_NC_first
- {\global\let\math_cases_NC\math_cases_NC_second}
+ {\glet\math_cases_NC\math_cases_NC_second}
\def\math_cases_NC_second
{\math_cases_end_math\aligntab}
@@ -722,7 +729,7 @@
\let\NC\math_cases_NC_zero
\let\MC\math_cases_MC_zero
\let\NR\math_cases_NR_zero
- \global\let\math_cases_NC\math_cases_NC_first
+ \glet\math_cases_NC\math_cases_NC_first
\normalbaselines
\mathsurround\zeropoint
\everycr\emptytoks
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-arr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-arr.mkiv
index a0dda66b9b7..2edb91465ff 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-arr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-arr.mkiv
@@ -67,39 +67,46 @@
\def\math_arrows_construct#1#2#3#4#5% hm, looks like we do a double mathrel (a bit cleaned up .. needs checking)
{\begingroup
- \def\m_math_arrows_factor{1}%
- \def\m_math_arrows_extra {0}%
+ \let\m_math_arrows_factor\!!plusone
+ \let\m_math_arrows_extra \!!zerocount
\edef\p_math_spacing{#1}%
\csname\??matharrowsettings
\ifcsname\??matharrowsettings\p_math_spacing\endcsname\p_math_spacing\else\s!unknown\fi
\endcsname
\mathsurround\zeropoint
- \muskip0=\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax
- \muskip2=\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax
- \setbox0\hbox{\normalstartimath
- \scriptstyle
- \mkern\muskip0\relax
- #5\relax
- \mkern\muskip2\relax
- \normalstopimath}%
- \setbox2\hbox{\normalstartimath
- \scriptstyle
- \mkern\muskip0\relax
- #4\relax
- \mkern\muskip2\relax
- \normalstopimath}%
- \setbox4\hbox{#3\displaystyle}%
- \dimen0\wd0\relax
- \ifdim\wd2>\dimen0
- \dimen0\wd2\relax
+ \scratchmuskipone\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax
+ \scratchmuskiptwo\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax
+ \setbox\scratchboxone\hbox
+ {\normalstartimath
+ \scriptstyle
+ \mkern\scratchmuskipone\relax
+ #5\relax
+ \mkern\scratchmuskiptwo\relax
+ \normalstopimath}%
+ \setbox\scratchboxtwo\hbox
+ {\normalstartimath
+ \scriptstyle
+ \mkern\scratchmuskipone\relax
+ #4\relax
+ \mkern\scratchmuskiptwo\relax
+ \normalstopimath}%
+ \setbox\scratchboxthree\hbox{#3\displaystyle}%
+ \scratchdimenone\wd\scratchboxone\relax
+ \ifdim\wd\scratchboxtwo>\scratchdimenone
+ \scratchdimenone\wd\scratchboxtwo\relax
\fi
- \ifdim\wd4>\dimen0
- \dimen0\wd4\relax
+ \ifdim\wd\scratchboxthree>\scratchdimenone
+ \scratchdimenone\wd\scratchboxthree\relax
\fi
- \ifdim\wd4=\dimen0\else
- \setbox4\hbox to \dimen0{#3\displaystyle}%
+ \ifdim\wd\scratchboxthree=\scratchdimenone\else
+ \setbox\scratchboxthree\hbox to \scratchdimenone{#3\displaystyle}%
\fi
- \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}\limits\normalsuperscript{\box0}\normalsubscript{\box2}}% pack ?
+ \mathrel
+ {\mathop
+ {\hpack to \scratchdimenone{\hss\box\scratchboxthree\hss}}% pack ? copy ?
+ \limits
+ \normalsuperscript{\box\scratchboxone}%
+ \normalsubscript {\box\scratchboxtwo}}%
\endgroup}
\let\math_arrows_construct_single\math_arrows_construct
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-dim.lua b/Master/texmf-dist/tex/context/base/mkiv/math-dim.lua
index 72b9d7e5037..eb7adb53f97 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-dim.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-dim.lua
@@ -157,7 +157,8 @@ function mathematics.dimensions(dimens) -- beware, dimens get spoiled
for variable, styles in next, defaults do
local tt = { }
for style, default in next, styles do
- local one, two = default[1], default[2]
+ local one = default[1]
+ local two = default[2]
local value = dimens[one]
if value then
tt[style] = value
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-dir.lua b/Master/texmf-dist/tex/context/base/mkiv/math-dir.lua
index 759f1e79715..38aa44358e2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-dir.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-dir.lua
@@ -48,7 +48,9 @@ local vlist_code = nodecodes.vlist
local nodepool = nuts.pool
-local new_textdir = nodepool.textdir
+local new_direction = nodepool.direction
+
+local lefttoright_code = nodes.dirvalues.lefttoright
local chardirections = characters.directions
local charmirrors = characters.mirrors
@@ -60,16 +62,14 @@ local a_mathbidi = attributes.private('mathbidi')
local function processmath(head)
local current = head
- local done = false
local start = nil
local stop = nil
local function capsulate()
- head = insert_node_before(head,start,new_textdir("+TLT"))
- insert_node_after(head,stop,new_textdir("-TLT"))
+ head = insert_node_before(head,start,new_direction(lefttoright_code))
+ insert_node_after(head,stop,new_direction(lefttoright_code,true))
if trace_directions then
report_directions("reversed: %s",nodes.listtoutf(start,false,false,stop))
end
- done = true
start = false
stop = nil
end
@@ -100,7 +100,6 @@ local function processmath(head)
if trace_directions then
report_directions("mirrored: %C to %C",char,mirror)
end
- done = true
end
end
end
@@ -108,11 +107,8 @@ local function processmath(head)
elseif not start then
-- nothing
if id == hlist_code or id == vlist_code then
- local list, d = processmath(getlist(current))
+ local list = processmath(getlist(current))
setlist(current,list)
- if d then
- done = true
- end
end
elseif start == stop then
start = nil
@@ -121,11 +117,8 @@ local function processmath(head)
-- math can pack things into hlists .. we need to make sure we don't process
-- too often: needs checking
if id == hlist_code or id == vlist_code then
- local list, d = processmath(getlist(current))
+ local list = processmath(getlist(current))
setlist(current,list)
- if d then
- done = true
- end
end
end
current = getnext(current)
@@ -137,21 +130,18 @@ local function processmath(head)
else
capsulate()
end
- return head, done
+ return head
end
local enabled = false
function directions.processmath(head) -- style, penalties
if enabled then
- local h = tonut(head)
- local a = getattr(h,a_mathbidi)
+ local a = getattr(head,a_mathbidi)
if a and a > 0 then
- local head, done = processmath(h)
- return tonode(head), done
+ return processmath(head)
end
end
- return head, false
end
function directions.setmath(n)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-ext.lua b/Master/texmf-dist/tex/context/base/mkiv/math-ext.lua
index a4b8657136c..b923853f4a6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-ext.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-ext.lua
@@ -7,29 +7,30 @@ if not modules then modules = { } end modules ['math-ext'] = {
}
local rawget = rawget
-
-local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end)
-
local basename = file.basename
+local sortedhash = table.sortedhash
+
+local mathematics = mathematics
+local extras = mathematics.extras or { }
+mathematics.extras = extras
-local mathematics = mathematics
-local characters = characters
+local characters = characters
+local chardata = characters.data
+local mathpairs = characters.mathpairs
-local report_math = logs.reporter("mathematics")
+local trace_virtual = false
+local report_math = logs.reporter("mathematics")
-mathematics.extras = mathematics.extras or { }
-local extras = mathematics.extras
+trackers.register("math.virtual", function(v) trace_virtual = v end)
-local mathplus = { }
-local chardata = characters.data
-local mathpairs = characters.mathpairs
+local mathplus = { }
-- todo: store them and skip storage if already stored
-- todo: make a char-ctx.lua (or is this already side effect of save in format)
local function addextra(unicode)
local min = mathematics.extrabase
- local max = mathematics.privatebase - 1
+ local max = min + 0xFFF
if unicode >= min and unicode <= max then
if chardata[unicode] then
mathplus[unicode] = true
@@ -47,7 +48,7 @@ function extras.copy(target,original)
local characters = target.characters
local properties = target.properties
local parameters = target.parameters
- for unicode in table.sortedhash(mathplus) do
+ for unicode in sortedhash(mathplus) do
local extradesc = chardata[unicode]
local nextinsize = extradesc.nextinsize
if nextinsize then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-fbk.lua b/Master/texmf-dist/tex/context/base/mkiv/math-fbk.lua
index 7aa8c437fa1..963461de5cf 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-fbk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-fbk.lua
@@ -20,10 +20,22 @@ local sortedhash = table.sortedhash
local fallbacks = { }
mathematics.fallbacks = fallbacks
+local helpers = fonts.helpers
+local prependcommands = helpers.prependcommands
+local charcommand = helpers.commands.char
+local leftcommand = helpers.commands.left
+local rightcommand = helpers.commands.right
+local upcommand = helpers.commands.up
+local downcommand = helpers.commands.down
+local dummycommand = helpers.commands.dummy
+local popcommand = helpers.commands.pop
+local pushcommand = helpers.commands.push
+
local virtualcharacters = { }
-local identifiers = fonts.hashes.identifiers
-local lastmathids = fonts.hashes.lastmathids
+local hashes = fonts.hashes
+local identifiers = hashes.identifiers
+local lastmathids = hashes.lastmathids
-- we need a trick (todo): if we define scriptscript, script and text in
-- that order we could use their id's .. i.e. we could always add a font
@@ -115,6 +127,8 @@ function fallbacks.apply(target,original)
}
target.mathrelation = data
--
+ local fullname = trace_fallbacks and target.properties.fullname
+ --
for k, v in sortedhash(virtualcharacters) do
if not characters[k] then
local tv = type(v)
@@ -132,7 +146,7 @@ function fallbacks.apply(target,original)
-- something else
end
if trace_fallbacks and characters[k] then
- report_fallbacks("extending math font %a with %U",target.properties.fullname,k)
+ report_fallbacks("extending math font %a with %U",fullname,k)
end
end
end
@@ -151,22 +165,21 @@ local function reference(index,char)
if index then
return { "slot", index, char }
else
- return { "char", char }
+ return charcommand[char]
end
end
-local function raised(data,down)
- local replacement = data.replacement
- local character = data.scriptdata.characters[replacement]
+local function raised(data,replacement,down)
+ local character = data.scriptdata.characters[replacement]
if character then
+ local size = data.size
return {
width = character.width,
height = character.height,
depth = character.depth,
commands = {
- { "down", down and data.size/4 or -data.size/2 }, -- maybe exheight
+ down and downcommand[size/4] or upcommand[size/2],
reference(data.scriptindex,replacement)
- -- { "slot", data.scriptindex or 0, char } -- hm, data.mathrelation.scriptindex
}
}
end
@@ -177,33 +190,18 @@ end
-- virtualcharacters[0x208A] = 0x2212
-- virtualcharacters[0x208B] = 0x002B
-virtualcharacters[0x207A] = function(data)
- data.replacement = 0x002B
- return raised(data)
-end
-
-virtualcharacters[0x207B] = function(data)
- data.replacement = 0x2212
- return raised(data)
-end
-
-virtualcharacters[0x208A] = function(data)
- data.replacement = 0x002B
- return raised(data,true)
-end
-
-virtualcharacters[0x208B] = function(data)
- data.replacement = 0x2212
- return raised(data,true)
-end
+virtualcharacters[0x207A] = function(data) return raised(data,0x002B) end
+virtualcharacters[0x207B] = function(data) return raised(data,0x2212) end
+virtualcharacters[0x208A] = function(data) return raised(data,0x002B,true) end
+virtualcharacters[0x208B] = function(data) return raised(data,0x2212,true) end
-- local function repeated(data,char,n,fraction)
-- local character = data.characters[char]
-- if character then
-- local width = character.width
-- local delta = width - character.italic -- width * fraction
--- local c = { "char", char }
--- local r = { "right", right }
+-- local c = charcommand[char]
+-- local r = rightcommand[right]
-- local commands = { }
-- for i=1,n-1 do
-- width = width + delta
@@ -234,14 +232,9 @@ addextra(0xFE350) -- MATHEMATICAL DOUBLE ARROW LEFT END
addextra(0xFE351) -- MATHEMATICAL DOUBLE ARROW MIDDLE PART
addextra(0xFE352) -- MATHEMATICAL DOUBLE ARROW RIGHT END
-local push = { "push" }
-local pop = { "pop" }
-local leftarrow = { "char", 0x2190 }
-local relbar = { "char", 0x2212 }
-local rightarrow = { "char", 0x2192 }
--- local leftarrow = { "slot", 0, 0x2190 }
--- local relbar = { "slot", 0, 0x2212 }
--- local rightarrow = { "slot", 0, 0x2192 }
+local leftarrow = charcommand[0x2190]
+local relbar = charcommand[0x2212]
+local rightarrow = charcommand[0x2192]
virtualcharacters[0xFE350] = function(data)
-- return combined(data,0x2190,0x2212) -- leftarrow relbar
@@ -254,11 +247,11 @@ virtualcharacters[0xFE350] = function(data)
height = size,
depth = size,
commands = {
- push,
- { "down", size/2 },
+ pushcommand,
+ downcommand[size/2],
leftarrow,
- pop,
- { "down", -size/2 },
+ popcommand,
+ upcommand[size/2],
relbar,
}
}
@@ -275,11 +268,11 @@ virtualcharacters[0xFE351] = function(data)
height = size,
depth = size,
commands = {
- push,
- { "down", size/2 },
+ pushcommand,
+ downcommand[size/2],
relbar,
- pop,
- { "down", -size/2 },
+ popcommand,
+ upcommand[size/2],
relbar,
}
}
@@ -297,12 +290,12 @@ virtualcharacters[0xFE352] = function(data)
height = size,
depth = size,
commands = {
- push,
- { "down", size/2 },
+ pushcommand,
+ downcommand[size/2],
relbar,
- pop,
- { "right", chartwo.width - charone.width },
- { "down", -size/2 },
+ popcommand,
+ rightcommand[chartwo.width - charone.width],
+ upcommand[size/2],
rightarrow,
}
}
@@ -325,10 +318,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s
height = height or 0
depth = depth or 0
end
- local correction = swap and { "down", (olddata.height or 0) - height } or { "down", olddata.height + (offset or 0)}
+ local oldheight = olddata.height or 0
+ local correction = swap and
+ downcommand[oldheight - height]
+ or downcommand[oldheight + (offset or 0)]
local newdata = {
- commands = { correction, { "slot", 1, oldchr } },
- -- commands = { correction, { "slot", 0, oldchr } },
+ commands = { correction, charcommand[oldchr] },
width = olddata.width,
height = height,
depth = depth,
@@ -340,14 +335,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s
local oldnextdata = characters[nextglyph]
if oldnextdata then
local newnextdata = {
- commands = { correction, { "slot", 1, nextglyph } },
- -- commands = { correction, { "slot", 0, nextglyph } },
+ commands = { correction, charcommand[nextglyph] },
width = oldnextdata.width,
height = height,
depth = depth,
}
--- local newnextglyph = addprivate(target,formatters["M-N-%H"](nextglyph),newnextdata)
- local newnextglyph = addprivate(target,nil,newnextdata)
+ local newnextglyph = addprivate(target,formatters["M-N-%H"](nextglyph),newnextdata)
newdata.next = newnextglyph
local nextnextglyph = oldnextdata.next
if nextnextglyph == nextglyph then
@@ -372,14 +365,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s
local olddata = characters[oldglyph]
if olddata then
local newdata = {
- commands = { correction, { "slot", 1, oldglyph } },
- -- commands = { correction, { "slot", 0, oldglyph } },
+ commands = { correction, charcommand[oldglyph] },
width = olddata.width,
height = height,
depth = depth,
}
--- hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata)
- hvi.glyph = addprivate(target,nil,newdata)
+ hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata)
else
report_fallbacks("error in fallback: no valid horiz_variants, slot %X, index %i",oldglyph,i)
end
@@ -393,15 +384,16 @@ end
virtualcharacters[0x203E] = function(data)
local target = data.target
- local height, depth = 0, 0
--- local mathparameters = target.mathparameters
--- if mathparameters then
--- height = mathparameters.OverbarVerticalGap
--- depth = mathparameters.UnderbarVerticalGap
--- else
+ local height = 0
+ local depth = 0
+ -- local mathparameters = target.mathparameters
+ -- if mathparameters then
+ -- height = mathparameters.OverbarVerticalGap
+ -- depth = mathparameters.UnderbarVerticalGap
+ -- else
height = target.parameters.xheight/4
depth = height
--- end
+ -- end
return accent_to_extensible(target,0x203E,data.original,0x0305,height,depth,nil,nil,0x203E)
end
@@ -431,7 +423,7 @@ local function spacefraction(data,fraction)
local width = fraction * data.target.parameters.space
return {
width = width,
- commands = { { "right", width } }
+ commands = { rightcommand[width] }
}
end
@@ -439,7 +431,7 @@ local function charfraction(data,char)
local width = data.target.characters[char].width
return {
width = width,
- commands = { { "right", width } }
+ commands = { rightcommand[width] }
}
end
@@ -447,7 +439,7 @@ local function quadfraction(data,fraction)
local width = fraction * data.target.parameters.quad
return {
width = width,
- commands = { { "right", width } }
+ commands = { rightcommand[width] }
}
end
@@ -527,9 +519,8 @@ local function smashed(data,unicode,optional)
local shift = oldchar.height - height
local newchar = {
commands = {
- { "down", shift },
- { "slot", 0, unicode },
--- { "char", unicode },
+ downcommand[shift],
+ charcommand[unicode],
},
height = height,
width = oldchar.width,
@@ -607,11 +598,11 @@ local function actuarian(data)
width = basewidth + 4 * linewidth,
unicode = 0x20E7,
commands = {
- { "right", 2 * linewidth },
- { "down", - baseheight - 3 * linewidth },
+ rightcommand[2 * linewidth],
+ downcommand[- baseheight - 3 * linewidth],
{ "rule", linewidth, basewidth + 4 * linewidth },
- { "right", -linewidth },
- { "down", baseheight + 4 * linewidth },
+ leftcommand[linewidth],
+ downcommand[baseheight + 4 * linewidth],
{ "rule", baseheight + 5 * linewidth, linewidth },
},
}
@@ -629,11 +620,11 @@ local function equals(data,unicode,snippet,advance,n) -- mathpair needs them
unicode = unicode,
width = n*basechar.width + (n-1)*advance,
commands = {
- { "char", snippet },
- { "right", advance },
- { "char", snippet },
- n > 2 and { "right", advance } or nil,
- n > 2 and { "char", snippet } or nil,
+ charcommand[snippet],
+ rightcommand[advance],
+ charcommand[snippet],
+ n > 2 and rightcommand[advance] or nil,
+ n > 2 and charcommand[snippet] or nil,
},
}
end
@@ -657,11 +648,43 @@ virtualcharacters[0x2980] = function(data) return equals(data,0x2980,0x007C,-1/8
-- height = height, -- we cheat (no time now)
-- depth = depth, -- we cheat (no time now)
-- commands = {
--- { "down", - height/2 }, -- sort of works
--- { "char", 0x003D },
--- { "right", -width },
--- { "down", height }, -- sort of works
--- { "char", 0x003D },
+-- upcommand[height/2], -- sort of works
+-- charcommand[0x003D],
+-- leftcommand[width],
+-- downcommand[height], -- sort of works
+-- charcommand[0x003D],
-- },
-- }
-- end
+
+-- lucida needs this
+
+virtualcharacters[0x305] = function(data)
+ local target = data.target
+ local height = target.parameters.xheight/8
+ local width = target.parameters.emwidth/2
+ local depth = height
+ local used = 0.8 * width
+ return {
+ width = width,
+ height = height,
+ depth = depth,
+ commands = { { "rule", height, width } },
+ horiz_variants = {
+ {
+ advance = width,
+ ["end"] = used,
+ glyph = 0x305,
+ start = 0,
+ },
+ {
+ advance = width,
+ ["end"] = 0,
+ extender = 1,
+ glyph = 0x305,
+ start = used,
+ },
+ }
+ }
+end
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-fen.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-fen.mkiv
index a32ea410e74..6c6724bf52e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-fen.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-fen.mkiv
@@ -65,14 +65,19 @@
% we need the direct use of \Udelimiter because of { etc
-\newconditional\c_math_fenced_mirror \settrue\c_math_fenced_mirror
+\newconditional\c_math_fenced_mirror \settrue \c_math_fenced_mirror
+\newconditional\c_math_fenced_sized \setfalse\c_math_fenced_sized
\unexpanded\def\math_fenced_inject#1#2#3#4%
{\ifx#1\empty
#2.%
\else
\edef\p_mathclass{\mathfenceparameter\c!mathclass}%
- \edef\p_factor{\mathfenceparameter\c!factor}%
+ \ifconditional\c_math_fenced_sized
+ \let\p_factor\v!fixed
+ \else
+ \edef\p_factor{\mathfenceparameter\c!factor}%
+ \fi
\ifx\p_factor\empty
\ifx\p_mathclass\empty
#2%
@@ -97,7 +102,11 @@
\s!axis
% #2%
\else
- \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
+ \ifx\p_factor\v!fixed
+ \scratchdimen\scaledpoint
+ \else
+ \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
+ \fi
#3%
\s!height\scratchdimen
\s!depth\scratchdimen
@@ -121,16 +130,14 @@
\mathfenceparameter\c!left
\fi}%
\math_fenced_color_push
- % \normalleft\ifx\p_left\empty.\else\Udelimiter\plusfour\fam\p_left\relax\fi
\math_fenced_inject\p_left\normalleft\Uleft\plusfour
\math_fenced_color_pop}
\def\math_fenced_middle
{\edef\p_middle
- {\mathfenceparameter\c!middle}%
+ {\mathfenceparameter\c!middle}%
\mskip\thinmuskip
\math_fenced_color_push
- % \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi
\math_fenced_inject\p_middle\normalmiddle\Umiddle\plusfour
\math_fenced_color_pop
\mskip\thinmuskip}
@@ -147,7 +154,6 @@
\mathfenceparameter\c!right
\fi}%
\math_fenced_color_push
- % \normalright \ifx\p_right\empty.\else\Udelimiter\plusfive\fam\p_right\relax\fi
\math_fenced_inject\p_right\normalright\Uright\plusfive
\math_fenced_color_pop}
@@ -194,16 +200,60 @@
\edef\currentmathfence{#1}%
\dosingleempty\math_fenced_fenced_indeed}
-\unexpanded\def\math_fenced_fenced_indeed[#1]#2%
+\def\math_fenced_force_size#1#2%
+ {\attribute\mathsizeattribute\numexpr#1*\plushundred+#2\relax}
+
+% \unexpanded\def\math_fenced_fenced_indeed[#1]#2%
+% {\iffirstargument\setupcurrentmathfence[#1]\fi
+% \math_fenced_fenced_common
+% \edef\p_size{\mathfenceparameter\c!size}%
+% \ifx\p_size\empty
+% \setfalse\c_math_fenced_sized
+% \else
+% \settrue\c_math_fenced_sized
+% \math_fenced_force_size\bigmathdelimitervariant\p_size
+% \fi
+% \math_fenced_left
+% #2%
+% \math_fenced_right
+% \stopusemathstyleparameter
+% \endgroup
+% \advance\c_math_fenced_nesting\minusone}
+
+\unexpanded\def\math_fenced_fenced_indeed[#1]%
{\iffirstargument\setupcurrentmathfence[#1]\fi
\math_fenced_fenced_common
- \math_fenced_left
- #2%
- \math_fenced_right
- \stopusemathstyleparameter
+ \edef\p_size{\mathfenceparameter\c!size}%
+ \ifx\p_size\empty
+ \expandafter\math_fenced_fenced_indeed_adapt
+ \else
+ \expandafter\math_fenced_fenced_indeed_fixed
+ \fi}
+
+\unexpanded\def\math_fenced_fenced_indeed_finish
+ {\stopusemathstyleparameter
\endgroup
\advance\c_math_fenced_nesting\minusone}
+\unexpanded\def\math_fenced_fenced_indeed_fixed#1%
+ {\math_fenced_force_size\bigmathdelimitervariant\p_size
+ \settrue\c_math_fenced_sized
+ \math_fenced_left
+ \setfalse\c_math_fenced_sized
+ #1%
+ \settrue\c_math_fenced_sized
+ \math_fenced_right
+ \setfalse\c_math_fenced_sized
+ \math_fenced_fenced_indeed_finish}
+
+\unexpanded\def\math_fenced_fenced_indeed_adapt#1%
+ {\setfalse\c_math_fenced_sized
+ \math_fenced_left
+ #1%
+ \setfalse\c_math_fenced_sized
+ \math_fenced_right
+ \math_fenced_fenced_indeed_finish}
+
\appendtoks
\let\fenced\math_fenced_fenced
\to \everymathematics
@@ -440,31 +490,31 @@
\installmathfencepair \letteropenbrace \Lbrace \letterclosebrace \Rbrace % as we escape in mp textexts
-\installmathfencepair . \Lnothing . \Rnothing
-\installmathfencepair . \Rnothingmirrored . \Lnothingmirrored
+\installmathfencepair . \Lnothing . \Rnothing
+\installmathfencepair . \Rnothingmirrored . \Lnothingmirrored
-\installmathfencepair [ \Lbracket ] \Rbracket
-\installmathfencepair ] \Rbracketmirrored [ \Lbracketmirrored
+\installmathfencepair [ \Lbracket ] \Rbracket
+\installmathfencepair ] \Rbracketmirrored [ \Lbracketmirrored
-\installmathfencepair ( \Lparenthesis ) \Rparenthesis
-\installmathfencepair ) \Rparentmirrored ( \Lparentmirrored
+\installmathfencepair ( \Lparenthesis ) \Rparenthesis
+\installmathfencepair ) \Rparenthesismirrored ( \Lparenthesismirrored
-\installmathfencepair < \Langle > \Rangle
-\installmathfencepair > \Ranglemirrored < \Langlemirrored
+\installmathfencepair < \Langle > \Rangle
+\installmathfencepair > \Ranglemirrored < \Langlemirrored
-\installmathfencepair / \Lsolidus / \Rsolidus
-%installmathfencepair / \Rsolidusmirrored / \Lsolidusmirrored
+\installmathfencepair / \Lsolidus / \Rsolidus
+%installmathfencepair / \Rsolidusmirrored / \Lsolidusmirrored
-\installmathfencepair | \Lbar | \Rbar
-%installmathfencepair | \Rbarmirrored | \Lbarmirrored
+\installmathfencepair | \Lbar | \Rbar
+%installmathfencepair | \Rbarmirrored | \Lbarmirrored
-\installmathfencepair ⌊ \Lfloor ⌋ \Rfloor
-\installmathfencepair ⌋ \Rfloormirrored ⌊ \Lfloormirrored
-\installmathfencepair ⌈ \Lceiling ⌉ \Rceiling
-\installmathfencepair ⌉ \Rceilingmirrored ⌈ \Lceilingmirrored
+\installmathfencepair ⌊ \Lfloor ⌋ \Rfloor
+\installmathfencepair ⌋ \Rfloormirrored ⌊ \Lfloormirrored
+\installmathfencepair ⌈ \Lceiling ⌉ \Rceiling
+\installmathfencepair ⌉ \Rceilingmirrored ⌈ \Lceilingmirrored
-\installmathfencepair ⟨ \Langle ⟩ \Rangle
-\installmathfencepair ⟩ \Ranglemirrored ⟨ \Langlemirrored
+\installmathfencepair ⟨ \Langle ⟩ \Rangle
+\installmathfencepair ⟩ \Ranglemirrored ⟨ \Langlemirrored
\installmathfencepair ⟪ \Ldoubleangle ⟫ \Rdoubleangle
\installmathfencepair ⟫ \Rdoubleanglemirrored ⟪ \Ldoubleanglemirrored
@@ -475,10 +525,10 @@
\installmathfencepair ⦀ \Ltriplebar ⦀ \Rtriplebar
%installmathfencepair ⦀ \Rtriplebarmirrored ⦀ \Ltriplebarmirrored
-% \installmathfencepair { \Lbrace } \Rbrace
-% \installmathfencepair } \Rbracemirrored { \Lbracemirrored
+% \installmathfencepair { \Lbrace } \Rbrace
+% \installmathfencepair } \Rbracemirrored { \Lbracemirrored
-\installmathfencepair ⦗ \Linterv ⦘ \Rinterv
+\installmathfencepair ⦗ \Linterval ⦘ \Rinterval
\appendtoks
\ignorediscretionaries % so $\mtext{a|b}$ works, this is ok because it's an \hbox
@@ -591,7 +641,7 @@
\ifcase\bigmathdelimitermethod
\math_fenced_step#2\relax
\or
- \attribute\mathsizeattribute\numexpr\bigmathdelimitervariant*\plushundred+#1\relax
+ \math_fenced_force_size\bigmathdelimitervariant{#1}\relax
\math_fenced_step#2\relax
\else
\math_fenced_step#2{\vpack to\csname\??mathbig\number#1\endcsname\bodyfontsize{}}%
@@ -621,7 +671,7 @@
\unexpanded\def\mathdelimiterstep#1#2%
{\begingroup
- \attribute\mathsizeattribute\numexpr\plushundred+#1\relax
+ \math_fenced_force_size\plusone{#1}%
\math_fenced_step#2\relax
\endgroup}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-frc.lua b/Master/texmf-dist/tex/context/base/mkiv/math-frc.lua
index 5c4879527d7..190c364101d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-frc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-frc.lua
@@ -28,8 +28,8 @@ end)
local ctx_normalatop = context.normalatop
local ctx_normalover = context.normalover
-local function mathfraction(how,left,right,width) -- of course we could use the scanners directly here which
- if how == v_no then -- is faster but also less abstract ... maybe some day
+local function mathfraction(how,left,right,width)
+ if how == v_no then
if left == 0x002E and right == 0x002E then
ctx_normalatop()
else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-frc.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-frc.mkiv
index 9a5ce62b05d..97107a6bf91 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-frc.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-frc.mkiv
@@ -611,6 +611,46 @@
% \unexpanded\def\ShowMathFractions#1#2%
% {\mathematics{x+\tfrac{#1}{#2}+1+\frac{#1}{#2}+2+\sfrac{#1}{#2}+g}}
+%D More fracking (for Alan):
+
+\def\s!vfrac{vfrac}
+
+\unexpanded\def\math_frac_colored_vulgar#1#2%
+ {\savecolor
+ \colo_helpers_activate\p_math_fractions_color
+ {\restorecolor#1}\Uskewed/{\restorecolor#2}}
+
+\unexpanded\def\math_frac_normal_vulgar#1#2%
+ {{#1}\Uskewed/{#2}}
+
+\unexpanded\def\vfrac#1#2%
+ {\bgroup
+ \edef\p_math_fractions_color{\namedmathfractionparameter\s!vfrac\c!color}%
+ \ifx\p_math_fractions_color\empty
+ \expandafter\math_frac_normal_vulgar
+ \else
+ \expandafter\math_frac_colored_vulgar
+ \fi
+ {#1}%
+ {#2}%
+ \egroup}
+
+\appendtoks
+ \edef\p_hfactor{\namedmathfractionparameter\s!vfrac\c!hfactor}%
+ \edef\p_vfactor{\namedmathfractionparameter\s!vfrac\c!vfactor}%
+ \Umathskewedfractionhgap\textstyle \p_hfactor\fontemwidth \mathstylefont\textstyle
+ \Umathskewedfractionhgap\scriptstyle \p_hfactor\fontemwidth \mathstylefont\scriptstyle
+ \Umathskewedfractionhgap\scriptscriptstyle\p_hfactor\fontemwidth \mathstylefont\scriptscriptstyle
+ \Umathskewedfractionvgap\textstyle \p_vfactor\fontexheight\mathstylefont\textstyle
+ \Umathskewedfractionvgap\scriptstyle \p_vfactor\fontexheight\mathstylefont\scriptstyle
+ \Umathskewedfractionvgap\scriptscriptstyle\p_vfactor\fontexheight\mathstylefont\scriptscriptstyle
+\to \everysetupmathfraction
+
+\setupmathfraction
+ [\s!vfrac]
+ [\c!hfactor=.2,
+ \c!vfactor=.1]
+
\protect \endinput
% I have no clue what \mthfrac and \mthsqrt are supposed to do but
@@ -660,7 +700,7 @@
% \unexpanded\def\mthfrac#1#2#3{[mthfrac: #1 #2 #3]}
% \unexpanded\def\mthsqrt#1#2#3{[mthsqrt: #1 #2 #3]}
-% used for prototypine \Uskewed
+% used for prototyping \Uskewed
%
% \unexpanded\def\skewedfractiona#1#2{%
% \raise
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-inc.lua b/Master/texmf-dist/tex/context/base/mkiv/math-inc.lua
new file mode 100644
index 00000000000..010d29a359a
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-inc.lua
@@ -0,0 +1,87 @@
+if not modules then modules = { } end modules ['back-inc'] = {
+ version = 1.001,
+ comment = "companion to back-exp.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is an experiment. If it's really useful then I'll make a more efficient
+-- local export facility.
+
+local tonumber, next = tonumber, next
+local utfbyte, utfchar, utfsplit = utf.byte, utf.char, utf.split
+local match, gsub = string.match, string.gsub
+local nspaces = string.nspaces
+local concat = table.concat
+local xmltext = xml.text
+local undent = buffers.undent
+
+local f_entity = string.formatters["&x%X;"]
+local f_blob = string.formatters['\n\n\n\n%s']
+
+local all = nil
+local back = nil
+
+local function unmath(s)
+ local t = utfsplit(s)
+ for i=1,#t do
+ local ti = t[i]
+ local bi = utfbyte(ti)
+ if bi > 0xFFFF then
+ local ch = back[bi]
+ t[i] = ch and utfchar(ch) or f_entity(bi)
+ end
+ end
+ s = concat(t)
+ return s
+end
+
+local function beautify(s)
+ local b = match(s,"^( *)%s*$")
+ if b and e then
+ b = #b
+ e = #e
+ if e > b then
+ s = undent(nspaces[e-b] .. s)
+ elseif e < b then
+ s = undent((gsub(s,"^( *)",nspaces[b-e])))
+ end
+ end
+ return s
+end
+
+local function getblob(n)
+ if all == nil then
+ local name = file.nameonly(tex.jobname)
+ local full = name .. "-export/" .. name .. "-raw.xml"
+ if lfs.isfile(full) then
+ all = { }
+ back = { }
+ local root = xml.load(full)
+ for c in xml.collected(root,"formulacontent") do
+ local index = tonumber(c.at.n)
+ all[index] = f_blob(index,beautify(xmltext(c,"math") or ""))
+ end
+ local it = mathematics.alphabets.regular.it
+ for k, v in next, it.digits do back[v] = k end
+ for k, v in next, it.ucletters do back[v] = k end
+ for k, v in next, it.lcletters do back[v] = k end
+ else
+ all = false
+ end
+ end
+ if all == false then
+ return ""
+ end
+ return unmath(all[n] or "")
+end
+
+interfaces.implement {
+ name = "xmlformulatobuffer",
+ arguments = { "integer", "string" },
+ actions = function(n,target)
+ buffers.assign(target,getblob(n))
+ end
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-inc.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-inc.mkiv
new file mode 100644
index 00000000000..2821580cbf1
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-inc.mkiv
@@ -0,0 +1,69 @@
+%D \module
+%D [ file=math-inc,
+%D version=2018.06.23,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=XML inclusion,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Math Macros / XML inclusion}
+
+\registerctxluafile{math-inc}{}
+
+%D I had some doubt about including this in \CONTEXT\ but it might serve some users
+%D anyway. It's always the question to what extent one can be really roundtrip. I
+%D might improve it when I need it.
+
+% Talking about creating from a source ... June Lee's transcription of
+% Close to You by Jacob Collier is an amazing example:
+%
+% https://www.youtube.com/watch?v=hdBVN-HMuqI
+
+\unprotect
+
+\definesymbol[mmlattachment][{\infofont\darkred mml}]
+\definesymbol[mmlcomment] [{\infofont\darkblue mml}]
+
+\unexpanded\def\lxml_add_mml_blob#1#2%
+ {\relax
+ \clf_xmlformulatobuffer\number\c_strc_formulas_n{temp-xml-export}%
+ #2%
+ [\c!symbol=#1,%
+ \c!space=\v!yes,%
+ \c!buffer=temp-xml-export,%
+ \c!name={formula-\number\c_strc_formulas_n.xml}]%
+ \relax}
+
+\unexpanded\def\xmlattachmml
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \lxml_add_mml_blob{mmlattachment}\attachment
+ \dostoptagged
+ \fi \fi \fi}
+
+\unexpanded\def\xmlcommentmml
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \lxml_add_mml_blob{mmlcomment}\comment
+ \dostoptagged
+ \fi \fi \fi}
+
+%D This kind of feature creep is not yet configurable, nor documented.
+
+\unexpanded\def\xmladdmmlsource
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \inleftmargin{%
+ \lxml_add_mml_blob{mmlattachment}\attachment
+ \quad
+ \lxml_add_mml_blob{mmlcomment}\comment
+ }%
+ \dostoptagged
+ \fi \fi \fi}
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/math-ini.lua
index b79ef8c8cf4..7a841970209 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-ini.lua
@@ -36,8 +36,8 @@ local report_math = logs.reporter("mathematics","initializing")
mathematics = mathematics or { }
local mathematics = mathematics
-mathematics.extrabase = 0xFE000 -- here we push some virtuals
-mathematics.privatebase = 0xFF000 -- here we push the ex
+mathematics.extrabase = fonts.privateoffsets.mathextrabase -- here we push some virtuals
+mathematics.privatebase = fonts.privateoffsets.mathbase -- here we push the ex
local unsetvalue = attributes.unsetvalue
local allocate = utilities.storage.allocate
@@ -289,7 +289,8 @@ function mathematics.define(family)
local data = characters.data
for unicode, character in sortedhash(data) do
local symbol = character.mathsymbol
- local mset, dset = true, true
+ local mset = true
+ local dset = true
if symbol then
local other = data[symbol]
local class = other.mathclass
@@ -641,7 +642,7 @@ function mathematics.big(tfmdata,unicode,n,method)
end
end
end
- else
+ elseif method == 3 then
local size = 1.33^n
if method == 4 then
size = tfmdata.parameters.size * size
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv
index 17d900d74f2..50da1a400c8 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv
@@ -123,9 +123,12 @@
\definesystemattribute[mathbidi] [public]
\definesystemattribute[mathdomain] [public]
\definesystemattribute[mathcollapsing] [public]
+\definesystemattribute[mathunstack] [public]
\definesystemattribute[displaymath] [public]
+\mathflattenmode 31
+
\appendtoks
\attribute\mathmodeattribute\plusone
\to \everydisplay
@@ -217,18 +220,20 @@
\unexpanded\def\startmathematics % no grouping, if ever then also an optional second
{\doifelsenextoptionalcs\math_mathematics_start_yes\math_mathematics_start_nop}
+\installmacrostack\currentmathematics
+
\unexpanded\def\math_mathematics_start_yes[#1]%
- {\pushmacro\currentmathematics
+ {\push_macro_currentmathematics
\edef\currentmathematics{#1}% check for valid
\the\everyswitchmathematics}
\unexpanded\def\math_mathematics_start_nop
- {\pushmacro\currentmathematics
+ {\push_macro_currentmathematics
\let\currentmathematics\empty
\the\everyswitchmathematics}
\unexpanded\def\stopmathematics
- {\popmacro\currentmathematics
+ {\pop_macro_currentmathematics
\the\everyswitchmathematics}
\definemathematics[\v!default] % not needed, but nicer when nesting back to normal
@@ -734,7 +739,6 @@
%
% \def\math_op{\ifx\nexttoken\bgroup\else\nexttoken\egroup\fi}
-
% this one too: \letvalue{\??mathcodecommand op}\mathop ?
\unexpanded\def\normalmbox
@@ -750,17 +754,15 @@
{\ifmmode\normalmbox\else\normalhbox\fi}
\unexpanded\def\enablembox
- {\appendtoks\math_enable_mbox\to \everymathematics}
- {\everymathematics\expandafter{\the\everymathematics\math_enable_mbox}}
+ {\toksapp\everymathematics{\math_enable_mbox}}
\def\math_enable_mbox
- {\ifdefined\normalhbox\else\let\normalhbox\hbox\fi % ?
- \let\hbox\mbox}
+ {\let\hbox\mbox}
\unexpanded\def\snappedmath#1% sort of \struttedbox
{\dontleavehmode
\begingroup
- \setbox\scratchbox\hbox\bgroup
+ \setbox\scratchbox\normalhbox\bgroup
\startimath#1\stopimath
\egroup
\ht\scratchbox\strutht
@@ -1077,8 +1079,8 @@
% most math fonts have messed up primes, just test this: $\prime^{\prime^{\prime}}$
-{ \catcode\circumflexasciicode\othercatcode \global\let\othercircumflextoken ^ }
-{ \catcode\circumflexasciicode\superscriptcatcode \global\let\superscriptcircumflextoken^ }
+{ \catcode\circumflexasciicode\othercatcode \glet\othercircumflextoken ^ }
+{ \catcode\circumflexasciicode\superscriptcatcode \glet\superscriptcircumflextoken^ }
\ifdefined \prime \else
\Umathchardef\prime "0 "0 "2032
@@ -1273,9 +1275,13 @@
%D Memory saver:
+\def\math_basics_check_compact
+ {\doifelse{\mathematicsparameter\c!compact}\v!yes
+ \enabledirectives\disabledirectives[math.virtual.optional]}
+
\appendtoks
\ifx\currentmathematics\empty
- \doifelse{\mathematicsparameter\c!compact}\v!yes\enabledirectives\disabledirectives[math.virtual.optional]%
+ \math_basics_check_compact % less tracing
\fi
\to \everysetupmathematics
@@ -1311,18 +1317,31 @@
%D \HL
%D \stoptabulate
+% We will use proper constants when we go numbers instead of XXX.
+
\newconditional\c_math_right_to_left
+\installcorenamespace{mathaligndirection}
+
+\setvalue{\??mathaligndirection r2l}{\settrue\c_math_right_to_left}
+\setvalue{\??mathaligndirection\v!righttoleft}{\settrue\c_math_right_to_left}
+
\appendtoks
- \doifelse{\mathematicsparameter\c!align}{r2l}\settrue\setfalse\c_math_right_to_left
+ \ifcsname\??mathaligndirection\mathematicsparameter\c!align\endcsname
+ \lastnamedcs
+ \else
+ \setfalse\c_math_right_to_left
+ \fi
\to \everyswitchmathematics
\unexpanded\def\math_basics_synchronize_direction
- {\mathdir T\ifconditional\c_math_right_to_left R\else L\fi T}
+ {\mathdirection\ifconditional\c_math_right_to_left\directionrighttoleft\else\directionlefttoright\fi}
+
+% Not \everymathematics as it comes too late and I'm not in the mood for a mixed mode
+% kludge now (should be a property of beginmath nodes and passed to callbacks).
\appendtoks
\math_basics_synchronize_direction
-%to \everymathematics % comes too late and I'm not in the mood for a mixed mode kludge now (should be a property of beginmath nodes and passed to callbacks)
\to \everyswitchmathematics
% experimental (needed for an article)
@@ -1337,11 +1356,6 @@
\letvalue{\??mathbidi\v!yes}\math_bidi_enable
\letvalue{\??mathbidi\v!no }\math_bidi_disable
-% \appendtoks
-% \edef\p_bidi{\mathematicsparameter\c!bidi}%
-% \csname\??mathbidi\ifcsname\??mathbidi\p_bidi\endcsname\p_bidi\else\v!no\fi\endcsname
-% \to \everysetupmathematics
-
\appendtoks
\edef\p_bidi{\mathematicsparameter\c!bidi}% still needed ?
\ifcsname\??mathbidi\p_bidi\endcsname\lastnamedcs\else\math_bidi_disable\fi
@@ -1434,7 +1448,7 @@
\def\math_collapsing_initialize
{\ifnum\c_math_collapsing_attribute=\attributeunsetvalue \else
\clf_initializemathcollapsing % one time
- \global\let\math_collapsing_initialize\relax
+ \glet\math_collapsing_initialize\relax
\fi}
\appendtoks
@@ -1471,7 +1485,7 @@
\def\math_italics_initialize
{\ifnum\c_math_italics_attribute=\attributeunsetvalue \else
\clf_initializemathitalics % one time
- \global\let\math_italics_initialize\relax
+ \glet\math_italics_initialize\relax
\fi}
\appendtoks
@@ -1511,7 +1525,7 @@
\def\math_kernpairs_initialize
{\ifnum\c_math_kernpairs_attribute=\attributeunsetvalue \else
\clf_initializemathkernpairs % one time
- \global\let\math_kernpairs_initialize\relax
+ \glet\math_kernpairs_initialize\relax
\fi}
\appendtoks
@@ -2343,7 +2357,7 @@
% \c_math_styles_state_cramped\zerocount
% \c_math_styles_state_size \zerocount
% \rawprocesscommacommand[\m_math_style_asked]\math_style_collect
-% \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
+% \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
% \csname\??mathstylecache\m_math_style_asked\endcsname}
\def\math_style_set_indeed
@@ -2365,7 +2379,7 @@
\c_math_styles_state_cramped\zerocount
\c_math_styles_state_size \zerocount
\rawprocesscommacommand[\m_math_style_asked]\math_style_collect
- \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
+ \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
\csname\??mathstylecache\m_math_style_asked\endcsname}
\letvalue{\??mathstyle \??mathstyle }\math_style_set_mathstyle_mathstyle % still needed?
@@ -2468,10 +2482,12 @@
% I need to decide:
%
-%mathscriptboxmode\zerocount % no kerning
-%mathscriptboxmode\plusone % lists
-\mathscriptboxmode\plustwo % lists and boxes
-%mathscriptboxmode\plusthree % lists and boxes with \boundary=1 (also for testing and demo)
+%mathscriptboxmode \zerocount % no kerning
+%mathscriptboxmode \plusone % lists
+\mathscriptboxmode \plustwo % lists and boxes
+\mathscriptcharmode \plusone % lists and boxes
+%mathscriptboxmode \plusthree % lists and boxes with \boundary=1 (also for testing and demo)
+\mathrulethicknessmode\plusone % adaptive
\unexpanded\def\mathtext {\mathortext{\math_text_choice_font\relax}\hbox}
\unexpanded\def\mathword {\mathortext{\math_text_choice_word\relax}\hbox}
@@ -2529,7 +2545,7 @@
% this can become an option:
\unexpanded\def\math_display_align_hack % I don't like the global, maybe we should push and pop
- {\global\let\math_display_align_hack_indeed\math_display_align_hack_remove_skip
+ {\glet\math_display_align_hack_indeed\math_display_align_hack_remove_skip
\math_openup\displayopenupvalue % was \math_openup\jot
\everycr{\noalign{\math_display_align_hack_indeed}}}
@@ -2537,7 +2553,7 @@
{\ifdim\prevdepth>-\thousandpoint
\vskip\dimexpr-\lineskiplimit+\normallineskiplimit\relax
\fi
- \global\let\math_display_align_hack_indeed\math_display_align_hack_insert_penalty}
+ \glet\math_display_align_hack_indeed\math_display_align_hack_insert_penalty}
\def\math_display_align_hack_insert_penalty
{\penalty\interdisplaylinepenalty}
@@ -2767,7 +2783,7 @@
\def\math_domain_initialize
{\ifnum\c_math_domain_attribute=\attributeunsetvalue \else
\clf_initializemathdomain % one time
- \global\let\math_domain_initialize\relax
+ \glet\math_domain_initialize\relax
\fi}
\appendtoks
@@ -2791,7 +2807,7 @@
\installcorenamespace{mathrules}
-\unexpanded\def\enablemathrules{\global\letvalue{\??mathrules\fontclass}\plusone}
+\unexpanded\def\enablemathrules{\letgvalue{\??mathrules\fontclass}\plusone}
\appendtoks
\mathrulesmode\ifcsname\??mathrules\fontclass\endcsname
@@ -2802,6 +2818,70 @@
\mathrulesfam\zerocount
\to \everymathematics
+%D Maybe:
+
+% \starttabulate[|||c|c|]
+% \BC positive \BC negative \BC text \BC math \NC \NR
+% \NC \tex {f1} \tex {hairspace} \tex{,} \NC \tex {b1} \tex {neghairspace} \NC {\darkred\vl}\f1{\darkblue\vl} \NC ${\darkred\vl}\f1{\darkblue\vl}$ \NC \NR
+% \NC \tex {f2} \tex {thinspace} \tex{:} \NC \tex {b2} \tex {negthinspace} \tex{!} \NC {\darkred\vl}\f2{\darkblue\vl} \NC ${\darkred\vl}\f2{\darkblue\vl}$ \NC \NR
+% \NC \tex {f3} \tex {medspace} \tex{;} \NC \tex {b3} \tex {negmedspace} \NC {\darkred\vl}\f3{\darkblue\vl} \NC ${\darkred\vl}\f3{\darkblue\vl}$ \NC \NR
+% \NC \tex {f4} \tex {thickspace} \NC \tex {b4} \tex {negthickspace} \NC {\darkred\vl}\f4{\darkblue\vl} \NC ${\darkred\vl}\f4{\darkblue\vl}$ \NC \NR
+% \NC \tex {f5} \tex {enspace} \NC \tex {b5} \NC {\darkred\vl}\f5{\darkblue\vl} \NC ${\darkred\vl}\f5{\darkblue\vl}$ \NC \NR
+% \NC \tex {f6} \tex {emspace} \NC \tex {b6} \NC {\darkred\vl}\f6{\darkblue\vl} \NC ${\darkred\vl}\f6{\darkblue\vl}$ \NC \NR
+% \stoptabulate
+
+% \unexpanded\def\negenspace{\kern-.5\emwidth}
+% \unexpanded\def\negemspace{\kern- \emwidth}
+%
+% \unexpanded\def\math_f#1%
+% {\ifcase#1\or
+% \hairspace
+% \or
+% \thinspace
+% \or
+% \medspace
+% \or
+% \thickspace
+% \or
+% \enspace
+% \or
+% \emspace
+% \fi}
+%
+% \unexpanded\def\math_b#1%
+% {\ifcase#1\or
+% \neghairspace
+% \or
+% \negthinspace
+% \or
+% \negmedspace
+% \or
+% \negthickspace
+% \or
+% \negenspace
+% \or
+% \negemspace
+% \fi}
+%
+% \appendtoks
+% \let\f\math_f
+% \let\b\math_b
+% \to \everymathematics
+
+%D Experiment
+
+\unexpanded\def\math_scripts_stack
+ {\attribute\mathunstackattribute\attributeunsetvalue}
+
+\unexpanded\def\math_scripts_unstack
+ {\clf_enablescriptunstacking
+ \attribute\mathunstackattribute\plusone}
+
+\appendtoks
+ \let\stackscripts \math_scripts_stack
+ \let\unstackscripts\math_scripts_unstack
+\to \everymathematics
+
\protect \endinput
% % not used (yet)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua b/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua
index 529837cfaa6..ea758358754 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua
@@ -19,7 +19,7 @@ if not modules then modules = { } end modules ['math-noa'] = {
-- 20D6 -> 2190
-- 20D7 -> 2192
--- todo: most is math_char so we can have simple dedicated loops
+-- todo: most is mathchar_code so we can have simple dedicated loops
-- nota bene: uunderdelimiter uoverdelimiter etc are radicals (we have 5 types)
@@ -31,177 +31,184 @@ local insert, remove = table.insert, table.remove
local div = math.div
local bor, band = bit32.bor, bit32.band
-local fonts = fonts
-local nodes = nodes
-local node = node
-local mathematics = mathematics
-local context = context
-
-local otf = fonts.handlers.otf
-local otffeatures = fonts.constructors.features.otf
-local registerotffeature = otffeatures.register
-
-local privateattribute = attributes.private
-local registertracker = trackers.register
-local registerdirective = directives.register
-local logreporter = logs.reporter
-local setmetatableindex = table.setmetatableindex
-
-local colortracers = nodes.tracers.colors
-
-local trace_remapping = false registertracker("math.remapping", function(v) trace_remapping = v end)
-local trace_processing = false registertracker("math.processing", function(v) trace_processing = v end)
-local trace_analyzing = false registertracker("math.analyzing", function(v) trace_analyzing = v end)
-local trace_normalizing = false registertracker("math.normalizing", function(v) trace_normalizing = v end)
-local trace_collapsing = false registertracker("math.collapsing", function(v) trace_collapsing = v end)
-local trace_fixing = false registertracker("math.fixing", function(v) trace_foxing = v end)
-local trace_patching = false registertracker("math.patching", function(v) trace_patching = v end)
-local trace_goodies = false registertracker("math.goodies", function(v) trace_goodies = v end)
-local trace_variants = false registertracker("math.variants", function(v) trace_variants = v end)
-local trace_alternates = false registertracker("math.alternates", function(v) trace_alternates = v end)
-local trace_italics = false registertracker("math.italics", function(v) trace_italics = v end)
-local trace_kernpairs = false registertracker("math.kernpairs", function(v) trace_kernpairs = v end)
-local trace_domains = false registertracker("math.domains", function(v) trace_domains = v end)
-local trace_families = false registertracker("math.families", function(v) trace_families = v end)
-local trace_fences = false registertracker("math.fences", function(v) trace_fences = v end)
-
-local check_coverage = true registerdirective("math.checkcoverage", function(v) check_coverage = v end)
-
-local report_processing = logreporter("mathematics","processing")
-local report_remapping = logreporter("mathematics","remapping")
-local report_normalizing = logreporter("mathematics","normalizing")
-local report_collapsing = logreporter("mathematics","collapsing")
-local report_fixing = logreporter("mathematics","fixing")
-local report_patching = logreporter("mathematics","patching")
-local report_goodies = logreporter("mathematics","goodies")
-local report_variants = logreporter("mathematics","variants")
-local report_alternates = logreporter("mathematics","alternates")
-local report_italics = logreporter("mathematics","italics")
-local report_kernpairs = logreporter("mathematics","kernpairs")
-local report_domains = logreporter("mathematics","domains")
-local report_families = logreporter("mathematics","families")
-local report_fences = logreporter("mathematics","fences")
-
-local a_mathrendering = privateattribute("mathrendering")
-local a_exportstatus = privateattribute("exportstatus")
-
-local nuts = nodes.nuts
-local nodepool = nuts.pool
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-local nutstring = nuts.tostring
-
-local setfield = nuts.setfield
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setnext = nuts.setnext
-local setprev = nuts.setprev
-local setchar = nuts.setchar
-local setfam = nuts.setfam
-local setsubtype = nuts.setsubtype
-local setattr = nuts.setattr
-local setattrlist = nuts.setattrlist
-
-local getfield = nuts.getfield
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getboth = nuts.getboth
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
-local getfont = nuts.getfont
-local getfam = nuts.getfam
-local getattr = nuts.getattr
-local getlist = nuts.getlist
-
-local getnucleus = nuts.getnucleus
-local getsub = nuts.getsub
-local getsup = nuts.getsup
-
-local setnucleus = nuts.setnucleus
-local setsub = nuts.setsub
-local setsup = nuts.setsup
-
-local flush_node = nuts.flush
-local copy_node = nuts.copy
-local slide_nodes = nuts.slide
-local set_visual = nuts.setvisual
-
-local mlist_to_hlist = nodes.mlist_to_hlist
-
-local font_of_family = node.family_font
-
-local new_kern = nodepool.kern
-local new_submlist = nodepool.submlist
-local new_noad = nodepool.noad
-local new_delimiter = nodepool.delimiter
-local new_fence = nodepool.fence
-
-local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
-local fontcharacters = fonthashes.characters
-local fontitalics = fonthashes.italics
-
-local variables = interfaces.variables
-local texsetattribute = tex.setattribute
-local texgetattribute = tex.getattribute
-local unsetvalue = attributes.unsetvalue
-local implement = interfaces.implement
-
-local v_reset = variables.reset
-
-local chardata = characters.data
-
-noads = noads or { } -- todo: only here
-local noads = noads
-
-noads.processors = noads.processors or { }
-local processors = noads.processors
-
-noads.handlers = noads.handlers or { }
-local handlers = noads.handlers
-
-local tasks = nodes.tasks
-local enableaction = tasks.enableaction
-local setaction = tasks.setaction
-
-local nodecodes = nodes.nodecodes
-local noadcodes = nodes.noadcodes
-local fencecodes = nodes.fencecodes
-
-local noad_ord = noadcodes.ord
-local noad_rel = noadcodes.rel
-local noad_bin = noadcodes.bin
-local noad_open = noadcodes.open
-local noad_close = noadcodes.close
-local noad_punct = noadcodes.punct
-local noad_opdisplaylimits = noadcodes.opdisplaylimits
-local noad_oplimits = noadcodes.oplimits
-local noad_opnolimits = noadcodes.opnolimits
-local noad_inner = noadcodes.inner
-
-local math_noad = nodecodes.noad -- attr nucleus sub sup
-local math_accent = nodecodes.accent -- attr nucleus sub sup accent
-local math_radical = nodecodes.radical -- attr nucleus sub sup left degree
-local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right
-local math_subbox = nodecodes.subbox -- attr list
-local math_submlist = nodecodes.submlist -- attr list
-local math_char = nodecodes.mathchar -- attr fam char
-local math_textchar = nodecodes.mathtextchar -- attr fam char
-local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char
------ math_style = nodecodes.style -- attr style
-local math_choice = nodecodes.choice -- attr display text script scriptscript
-local math_fence = nodecodes.fence -- attr subtype
-
-local left_fence_code = fencecodes.left
-local middle_fence_code = fencecodes.middle
-local right_fence_code = fencecodes.right
+local fonts = fonts
+local nodes = nodes
+local node = node
+local mathematics = mathematics
+local context = context
+
+local otf = fonts.handlers.otf
+local otffeatures = fonts.constructors.features.otf
+local registerotffeature = otffeatures.register
+
+local privateattribute = attributes.private
+local registertracker = trackers.register
+local registerdirective = directives.register
+local logreporter = logs.reporter
+local setmetatableindex = table.setmetatableindex
+
+local colortracers = nodes.tracers.colors
+
+local trace_remapping = false registertracker("math.remapping", function(v) trace_remapping = v end)
+local trace_processing = false registertracker("math.processing", function(v) trace_processing = v end)
+local trace_analyzing = false registertracker("math.analyzing", function(v) trace_analyzing = v end)
+local trace_normalizing = false registertracker("math.normalizing", function(v) trace_normalizing = v end)
+local trace_collapsing = false registertracker("math.collapsing", function(v) trace_collapsing = v end)
+local trace_fixing = false registertracker("math.fixing", function(v) trace_foxing = v end)
+local trace_patching = false registertracker("math.patching", function(v) trace_patching = v end)
+local trace_goodies = false registertracker("math.goodies", function(v) trace_goodies = v end)
+local trace_variants = false registertracker("math.variants", function(v) trace_variants = v end)
+local trace_alternates = false registertracker("math.alternates", function(v) trace_alternates = v end)
+local trace_italics = false registertracker("math.italics", function(v) trace_italics = v end)
+local trace_kernpairs = false registertracker("math.kernpairs", function(v) trace_kernpairs = v end)
+local trace_domains = false registertracker("math.domains", function(v) trace_domains = v end)
+local trace_families = false registertracker("math.families", function(v) trace_families = v end)
+local trace_fences = false registertracker("math.fences", function(v) trace_fences = v end)
+local trace_unstacking = false registertracker("math.unstack", function(v) trace_unstacking = v end)
+
+local check_coverage = true registerdirective("math.checkcoverage", function(v) check_coverage = v end)
+
+local report_processing = logreporter("mathematics","processing")
+local report_remapping = logreporter("mathematics","remapping")
+local report_normalizing = logreporter("mathematics","normalizing")
+local report_collapsing = logreporter("mathematics","collapsing")
+local report_fixing = logreporter("mathematics","fixing")
+local report_patching = logreporter("mathematics","patching")
+local report_goodies = logreporter("mathematics","goodies")
+local report_variants = logreporter("mathematics","variants")
+local report_alternates = logreporter("mathematics","alternates")
+local report_italics = logreporter("mathematics","italics")
+local report_kernpairs = logreporter("mathematics","kernpairs")
+local report_domains = logreporter("mathematics","domains")
+local report_families = logreporter("mathematics","families")
+local report_fences = logreporter("mathematics","fences")
+local report_unstacking = logreporter("mathematics","unstack")
+
+local a_mathrendering = privateattribute("mathrendering")
+local a_exportstatus = privateattribute("exportstatus")
+
+local nuts = nodes.nuts
+local nodepool = nuts.pool
+local tonut = nuts.tonut
+local nutstring = nuts.tostring
+
+local setfield = nuts.setfield
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setchar = nuts.setchar
+local setfam = nuts.setfam
+local setsubtype = nuts.setsubtype
+local setattr = nuts.setattr
+local setattrlist = nuts.setattrlist
+local setwidth = nuts.setwidth
+local setheight = nuts.setheight
+local setdepth = nuts.setdepth
+
+local getfield = nuts.getfield
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getboth = nuts.getboth
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getfam = nuts.getfam
+local getattr = nuts.getattr
+local getlist = nuts.getlist
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
+
+local getnucleus = nuts.getnucleus
+local getsub = nuts.getsub
+local getsup = nuts.getsup
+
+local setnucleus = nuts.setnucleus
+local setsub = nuts.setsub
+local setsup = nuts.setsup
+
+local flush_node = nuts.flush
+local copy_node = nuts.copy
+local slide_nodes = nuts.slide
+local set_visual = nuts.setvisual
+
+local mlist_to_hlist = nuts.mlist_to_hlist
+
+local font_of_family = node.family_font
+
+local new_kern = nodepool.kern
+local new_submlist = nodepool.submlist
+local new_noad = nodepool.noad
+local new_delimiter = nodepool.delimiter
+local new_fence = nodepool.fence
+
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontcharacters = fonthashes.characters
+local fontitalics = fonthashes.italics
+
+local variables = interfaces.variables
+local texsetattribute = tex.setattribute
+local texgetattribute = tex.getattribute
+local unsetvalue = attributes.unsetvalue
+local implement = interfaces.implement
+
+local v_reset = variables.reset
+
+local chardata = characters.data
+
+noads = noads or { } -- todo: only here
+local noads = noads
+
+noads.processors = noads.processors or { }
+local processors = noads.processors
+
+noads.handlers = noads.handlers or { }
+local handlers = noads.handlers
+
+local tasks = nodes.tasks
+local enableaction = tasks.enableaction
+local setaction = tasks.setaction
+
+local nodecodes = nodes.nodecodes
+local noadcodes = nodes.noadcodes
+local fencecodes = nodes.fencecodes
+
+local ordnoad_code = noadcodes.ord
+local relnode_code = noadcodes.rel
+local binnoad_code = noadcodes.bin
+local opennoad_code = noadcodes.open
+local closenoad_code = noadcodes.close
+local punctnoad_code = noadcodes.punct
+local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits
+local oplimitsnoad_code = noadcodes.oplimits
+local opnolimitsnoad_code = noadcodes.opnolimits
+local innernoad_code = noadcodes.inner
+
+local noad_code = nodecodes.noad -- attr nucleus sub sup
+local accent_code = nodecodes.accent -- attr nucleus sub sup accent
+local radical_code = nodecodes.radical -- attr nucleus sub sup left degree
+local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right
+local subbox_code = nodecodes.subbox -- attr list
+local submlist_code = nodecodes.submlist -- attr list
+local mathchar_code = nodecodes.mathchar -- attr fam char
+local mathtextchar_code = nodecodes.mathtextchar -- attr fam char
+local delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char
+----- style_code = nodecodes.style -- attr style
+local math_choice = nodecodes.choice -- attr display text script scriptscript
+local fence_code = nodecodes.fence -- attr subtype
+
+local leftfence_code = fencecodes.left
+local middlefence_code = fencecodes.middle
+local rightfence_code = fencecodes.right
-- local mathclasses = mathematics.classes
-- local fenceclasses = {
--- [left_fence_code] = mathclasses.open,
--- [middle_fence_code] = mathclasses.middle,
--- [right_fence_code] = mathclasses.close,
+-- [leftfence_code] = mathclasses.open,
+-- [middlefence_code] = mathclasses.middle,
+-- [rightfence_code] = mathclasses.close,
-- }
-- this initial stuff is tricky as we can have removed and new nodes with the same address
@@ -211,6 +218,7 @@ local right_fence_code = fencecodes.right
-- local sf = setfield local st = setmetatableindex("number") setfield = function(n,f,v) st[f] = st[f] + 1 sf(n,f,v) end mathematics.SETFIELD = st
local function process(start,what,n,parent)
+
if n then
n = n + 1
else
@@ -224,9 +232,9 @@ local function process(start,what,n,parent)
while start do
local id = getid(start)
if trace_processing then
- if id == math_noad then
+ if id == noad_code then
report_processing("%w%S, class %a",n*2,nutstring(start),noadcodes[getsubtype(start)])
- elseif id == math_char then
+ elseif id == mathchar_code then
local char = getchar(start)
local font = getfont(start)
local fam = getfam(start)
@@ -256,16 +264,16 @@ local function process(start,what,n,parent)
-- report_processing("stop processing")
end
end
- elseif id == math_noad then
+ elseif id == noad_code then
-- single characters are like this
local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list
noad = getsup (start) if noad then process(noad,what,n,start) end -- list
noad = getsub (start) if noad then process(noad,what,n,start) end -- list
- elseif id == math_char or id == math_textchar or id == math_delim then
+ elseif id == mathchar_code or id == mathtextchar_code or id == delim_code then
break
- elseif id == math_subbox or id == math_submlist then
+ elseif id == subbox_code or id == submlist_code then
local noad = getlist(start) if noad then process(noad,what,n,start) end -- list (not getlist !)
- elseif id == math_fraction then
+ elseif id == fraction_code then
local noad = getfield(start,"num") if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"denom") if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter
@@ -275,21 +283,21 @@ local function process(start,what,n,parent)
noad = getfield(start,"text") if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"script") if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"scriptscript") if noad then process(noad,what,n,start) end -- list
- elseif id == math_fence then
+ elseif id == fence_code then
local noad = getfield(start,"delim") if noad then process(noad,what,n,start) end -- delimiter
- elseif id == math_radical then
+ elseif id == radical_code then
local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list
noad = getsup (start) if noad then process(noad,what,n,start) end -- list
noad = getsub (start) if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter
noad = getfield(start,"degree") if noad then process(noad,what,n,start) end -- list
- elseif id == math_accent then
+ elseif id == accent_code then
local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list
noad = getsup (start) if noad then process(noad,what,n,start) end -- list
noad = getsub (start) if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"accent") if noad then process(noad,what,n,start) end -- list
noad = getfield(start,"bot_accent") if noad then process(noad,what,n,start) end -- list
- -- elseif id == math_style then
+ -- elseif id == style_code then
-- -- has a next
-- else
-- -- glue, penalty, etc
@@ -297,20 +305,20 @@ local function process(start,what,n,parent)
start = getnext(start)
end
if not parent then
- return initial, true -- only first level -- for now
+ return initial -- only first level -- for now
end
end
local function processnested(current,what,n)
local noad = nil
local id = getid(current)
- if id == math_noad then
+ if id == noad_code then
noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list
noad = getsup (current) if noad then process(noad,what,n,current) end -- list
noad = getsub (current) if noad then process(noad,what,n,current) end -- list
- elseif id == math_subbox or id == math_submlist then
+ elseif id == subbox_code or id == submlist_code then
noad = getlist(current) if noad then process(noad,what,n,current) end -- list (not getlist !)
- elseif id == math_fraction then
+ elseif id == fraction_code then
noad = getfield(current,"num") if noad then process(noad,what,n,current) end -- list
noad = getfield(current,"denom") if noad then process(noad,what,n,current) end -- list
noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter
@@ -320,15 +328,15 @@ local function processnested(current,what,n)
noad = getfield(current,"text") if noad then process(noad,what,n,current) end -- list
noad = getfield(current,"script") if noad then process(noad,what,n,current) end -- list
noad = getfield(current,"scriptscript") if noad then process(noad,what,n,current) end -- list
- elseif id == math_fence then
+ elseif id == fence_code then
noad = getfield(current,"delim") if noad then process(noad,what,n,current) end -- delimiter
- elseif id == math_radical then
+ elseif id == radical_code then
noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list
noad = getsup (current) if noad then process(noad,what,n,current) end -- list
noad = getsub (current) if noad then process(noad,what,n,current) end -- list
noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter
noad = getfield(current,"degree") if noad then process(noad,what,n,current) end -- list
- elseif id == math_accent then
+ elseif id == accent_code then
noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list
noad = getsup (current) if noad then process(noad,what,n,current) end -- list
noad = getsub (current) if noad then process(noad,what,n,current) end -- list
@@ -340,13 +348,13 @@ end
local function processstep(current,process,n,id)
local noad = nil
local id = id or getid(current)
- if id == math_noad then
+ if id == noad_code then
noad = getnucleus(current) if noad then process(noad,n,current) end -- list
noad = getsup (current) if noad then process(noad,n,current) end -- list
noad = getsub (current) if noad then process(noad,n,current) end -- list
- elseif id == math_subbox or id == math_submlist then
+ elseif id == subbox_code or id == submlist_code then
noad = getlist(current) if noad then process(noad,n,current) end -- list (not getlist !)
- elseif id == math_fraction then
+ elseif id == fraction_code then
noad = getfield(current,"num") if noad then process(noad,n,current) end -- list
noad = getfield(current,"denom") if noad then process(noad,n,current) end -- list
noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter
@@ -356,15 +364,15 @@ local function processstep(current,process,n,id)
noad = getfield(current,"text") if noad then process(noad,n,current) end -- list
noad = getfield(current,"script") if noad then process(noad,n,current) end -- list
noad = getfield(current,"scriptscript") if noad then process(noad,n,current) end -- list
- elseif id == math_fence then
+ elseif id == fence_code then
noad = getfield(current,"delim") if noad then process(noad,n,current) end -- delimiter
- elseif id == math_radical then
+ elseif id == radical_code then
noad = getnucleus(current) if noad then process(noad,n,current) end -- list
noad = getsup (current) if noad then process(noad,n,current) end -- list
noad = getsub (current) if noad then process(noad,n,current) end -- list
noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter
noad = getfield(current,"degree") if noad then process(noad,n,current) end -- list
- elseif id == math_accent then
+ elseif id == accent_code then
noad = getnucleus(current) if noad then process(noad,n,current) end -- list
noad = getsup (current) if noad then process(noad,n,current) end -- list
noad = getsub (current) if noad then process(noad,n,current) end -- list
@@ -374,15 +382,14 @@ local function processstep(current,process,n,id)
end
local function processnoads(head,actions,banner)
- local h, d
if trace_processing then
report_processing("start %a",banner)
- h, d = process(tonut(head),actions)
+ head = process(head,actions)
report_processing("stop %a",banner)
else
- h, d = process(tonut(head),actions)
+ head = process(head,actions)
end
- return h and tonode(h) or head, d == nil and true or d
+ return head
end
noads.process = processnoads
@@ -456,7 +463,35 @@ do
"pseudobold",
}
- families[math_char] = function(pointer)
+ families[fraction_code] = function(pointer,what,n,parent)
+ local a = getattr(pointer,a_mathfamily)
+ if a and a >= 0 then
+ if a > 0 then
+ setattr(pointer,a_mathfamily,0)
+ if a > 5 then
+ a = a - 3
+ end
+ end
+ setfam(pointer,a)
+ end
+ processnested(pointer,families,n+1)
+ end
+
+ families[noad_code] = function(pointer,what,n,parent)
+ local a = getattr(pointer,a_mathfamily)
+ if a and a >= 0 then
+ if a > 0 then
+ setattr(pointer,a_mathfamily,0)
+ if a > 5 then
+ a = a - 3
+ end
+ end
+ setfam(pointer,a)
+ end
+ processnested(pointer,families,n+1)
+ end
+
+ families[mathchar_code] = function(pointer)
if getfam(pointer) == 0 then
local a = getattr(pointer,a_mathfamily)
if a and a > 0 then
@@ -501,8 +536,7 @@ do
end
end
end
-
- families[math_delim] = function(pointer)
+ families[delim_code] = function(pointer)
if getfield(pointer,"small_fam") == 0 then
local a = getattr(pointer,a_mathfamily)
if a and a > 0 then
@@ -534,7 +568,7 @@ do
-- will become:
- -- families[math_delim] = function(pointer)
+ -- families[delim_code] = function(pointer)
-- if getfam(pointer) == 0 then
-- local a = getattr(pointer,a_mathfamily)
-- if a and a > 0 then
@@ -556,11 +590,11 @@ do
-- end
-- end
- families[math_textchar] = families[math_char]
+ families[mathtextchar_code] = families[mathchar_code]
function handlers.families(head,style,penalties)
processnoads(head,families,"families")
- return true
+ return true -- not needed
end
end
@@ -604,7 +638,7 @@ do
end
end
- relocate[math_char] = function(pointer)
+ relocate[mathchar_code] = function(pointer)
local g = getattr(pointer,a_mathgreek) or 0
local a = getattr(pointer,a_mathalphabet) or 0
local char = getchar(pointer)
@@ -671,13 +705,13 @@ do
end
end
- relocate[math_textchar] = function(pointer)
+ relocate[mathtextchar_code] = function(pointer)
if trace_analyzing then
setnodecolor(pointer,"font:init")
end
end
- relocate[math_delim] = function(pointer)
+ relocate[delim_code] = function(pointer)
if trace_analyzing then
setnodecolor(pointer,"font:fina")
end
@@ -685,7 +719,7 @@ do
function handlers.relocate(head,style,penalties)
processnoads(head,relocate,"relocate")
- return true
+ return true -- not needed
end
end
@@ -698,7 +732,7 @@ do
local rendersets = mathematics.renderings.numbers or { } -- store
- render[math_char] = function(pointer)
+ render[mathchar_code] = function(pointer)
local attr = getattr(pointer,a_mathrendering)
if attr and attr > 0 then
local char = getchar(pointer)
@@ -719,7 +753,7 @@ do
function handlers.render(head,style,penalties)
processnoads(head,render,"render")
- return true
+ return true -- not needed
end
end
@@ -739,51 +773,46 @@ do
local a_mathsize = privateattribute("mathsize") -- this might move into other fence code
local resize = { }
- resize[math_fence] = function(pointer)
+ resize[fence_code] = function(pointer)
local subtype = getsubtype(pointer)
- if subtype == left_fence_code or subtype == right_fence_code then
+ if subtype == leftfence_code or subtype == rightfence_code then
local a = getattr(pointer,a_mathsize)
if a and a > 0 then
- local method, size = div(a,100), a % 100
+ local method = div(a,100)
+ local size = a % 100
setattr(pointer,a_mathsize,0)
local delimiter = getfield(pointer,"delim")
- local chr = getfield(delimiter,"small_char")
+ local chr = getchar(delimiter)
if chr > 0 then
- local fam = getfield(delimiter,"small_fam")
+ local fam = getfam(delimiter)
local id = font_of_family(fam)
if id > 0 then
- setfield(delimiter,"small_char",mathematics.big(fontdata[id],chr,size,method))
+ local data = fontdata[id]
+ local char = mathematics.big(data,chr,size,method)
+ local ht = getheight(pointer)
+ local dp = getdepth(pointer)
+ if ht == 1 or dp == 1 then -- 1 scaled point is a signal
+ local chardata = data.characters[char]
+ if ht == 1 then
+ setheight(pointer,chardata.height)
+ end
+ if dp == 1 then
+ setdepth(pointer,chardata.depth)
+ end
+ end
+ if trace_fences then
+ report_fences("replacing %C by %C using method %a and size %a",chr,char,method,size)
+ end
+ setchar(delimiter,char)
end
end
end
end
end
- -- will become:
-
- -- resize[math_fence] = function(pointer)
- -- local subtype = getsubtype(pointer)
- -- if subtype == left_fence_code or subtype == right_fence_code then
- -- local a = getattr(pointer,a_mathsize)
- -- if a and a > 0 then
- -- local method, size = div(a,100), a % 100
- -- setattr(pointer,a_mathsize,0)
- -- local delimiter = getfield(pointer,"delim")
- -- local chr = getchar(delimiter)
- -- if chr > 0 then
- -- local fam = getfam(delimiter)
- -- local id = font_of_family(fam)
- -- if id > 0 then
- -- setchar(delimiter,mathematics.big(fontdata[id],chr,size,method))
- -- end
- -- end
- -- end
- -- end
- -- end
-
function handlers.resize(head,style,penalties)
processnoads(head,resize,"resize")
- return true
+ return true -- not needed
end
end
@@ -797,8 +826,8 @@ do
local dummyfencechar = 0x2E
local function makefence(what,char)
- local d = new_delimiter()
- local f = new_fence()
+ local d = new_delimiter() -- todo: attr
+ local f = new_fence() -- todo: attr
if char then
local sym = getnucleus(char)
local chr = getchar(sym)
@@ -821,8 +850,8 @@ do
-- will become
-- local function makefence(what,char)
- -- local d = new_delimiter()
- -- local f = new_fence()
+ -- local d = new_delimiter() -- todo: attr
+ -- local f = new_fence() -- todo: attr
-- if char then
-- local sym = getnucleus(char)
-- local chr = getchar(sym)
@@ -843,7 +872,7 @@ do
local function makelist(noad,f_o,o_next,c_prev,f_c,middle)
local list = new_submlist()
setlist(list,f_o)
- setsubtype(noad,noad_inner)
+ setsubtype(noad,innernoad_code)
setnucleus(noad,list)
setlink(f_o,o_next)
setlink(c_prev,f_c)
@@ -854,7 +883,7 @@ do
local m = middle[current]
if m then
local next = getnext(current)
- local fence = makefence(middle_fence_code,current)
+ local fence = makefence(middlefence_code,current)
setnucleus(current)
flush_node(current)
middle[current] = nil
@@ -876,8 +905,8 @@ do
if o_next == close then
return close
else
- local f_o = makefence(left_fence_code,open)
- local f_c = makefence(right_fence_code,close)
+ local f_o = makefence(leftfence_code,open)
+ local f_c = makefence(rightfence_code,close)
makelist(open,f_o,o_next,c_prev,f_c,middle)
setnucleus(close)
flush_node(close)
@@ -890,8 +919,8 @@ do
end
local function convert_open(open,last,middle)
- local f_o = makefence(left_fence_code,open)
- local f_c = makefence(right_fence_code)
+ local f_o = makefence(leftfence_code,open)
+ local f_c = makefence(rightfence_code)
local o_prev, o_next = getboth(open)
local l_prev, l_next = getboth(last)
makelist(open,f_o,o_next,last,f_c,middle)
@@ -903,8 +932,8 @@ do
end
local function convert_close(close,first,middle)
- local f_o = makefence(left_fence_code)
- local f_c = makefence(right_fence_code,close)
+ local f_o = makefence(leftfence_code)
+ local f_c = makefence(rightfence_code,close)
local c_prev = getprev(close)
makelist(close,f_o,first,c_prev,f_c,middle)
return close
@@ -922,7 +951,7 @@ do
local middle = nil -- todo: use properties
while current do
local id = getid(current)
- if id == math_noad then
+ if id == noad_code then
local a = getattr(current,a_autofence)
if a and a > 0 then
local stack = stacks[n]
@@ -1009,7 +1038,7 @@ do
function handlers.autofences(head,style,penalties)
if enabled then -- tex.modes.c_math_fences_auto
-- inspect(nodes.totree(head))
- processfences(tonut(head),1)
+ processfences(head,1)
-- inspect(nodes.totree(head))
end
end
@@ -1031,9 +1060,9 @@ do
local next = getnext(pointer)
local start_super, stop_super, start_sub, stop_sub
local mode = "unset"
- while next and getid(next) == math_noad do
+ while next and getid(next) == noad_code do
local nextnucleus = getnucleus(next)
- if nextnucleus and getid(nextnucleus) == math_char and not getsub(next) and not getsup(next) then
+ if nextnucleus and getid(nextnucleus) == mathchar_code and not getsub(next) and not getsup(next) then
local char = getchar(nextnucleus)
local s = superscripts[char]
if s then
@@ -1088,6 +1117,18 @@ do
setnext(stop_super)
end
if start_sub then
+
+-- if mode == "sub" then
+-- local sup = getsup(pointer)
+-- if sup and not getsub(pointer) then
+-- local nxt = getnext(pointer)
+-- local new = new_noad(pointer)
+-- setnucleus(new,new_submlist())
+-- setlink(pointer,new,nxt)
+-- pointer = new
+-- end
+-- end
+
if start_sub == stop_sub then
setsub(pointer,getnucleus(start_sub))
else
@@ -1103,16 +1144,57 @@ do
-- we could return stop
end
- unscript[math_char] = replace -- not noads as we need to recurse
+ unscript[mathchar_code] = replace -- not noads as we need to recurse
function handlers.unscript(head,style,penalties)
processnoads(head,unscript,"unscript")
- -- processnoads(head,checkers,"checkers")
- return true
+ return true -- not needed
end
end
+do
+
+ local unstack = { } noads.processors.unstack = unstack
+ local enabled = false
+ local a_unstack = privateattribute("mathunstack")
+
+ unstack[noad_code] = function(pointer)
+ if getattr(pointer,a_unstack) then
+ local sup = getsup(pointer)
+ local sub = getsub(pointer)
+ if sup and sub then
+ -- if trace_unstacking then
+ -- report_unstacking() -- todo ... what to show ...
+ -- end
+ local nxt = getnext(pointer)
+ local new = new_noad(pointer)
+ setnucleus(new,new_submlist())
+ setsub(pointer)
+ setsub(new,sub)
+ setlink(pointer,new,nxt)
+ end
+ end
+ end
+
+ function handlers.unstack(head,style,penalties)
+ if enabled then
+ processnoads(head,unstack,"unstack")
+ return true -- not needed
+ end
+ end
+
+ implement {
+ name = "enablescriptunstacking",
+ onlyonce = true,
+ actions = function()
+ enableaction("math","noads.handlers.unstack")
+ enabled = true
+ end
+ }
+
+end
+
do
local function collected(list)
@@ -1306,7 +1388,7 @@ do
arguments = { "integer", "string" }
}
- alternate[math_char] = function(pointer) -- slow
+ alternate[mathchar_code] = function(pointer) -- slow
local a = getattr(pointer,a_mathalternate)
if a and a > 0 then
setattr(pointer,a_mathalternate,0)
@@ -1347,7 +1429,7 @@ do
function handlers.alternates(head,style,penalties)
processnoads(head,alternate,"alternate")
- return true
+ return true -- not needed
end
end
@@ -1365,7 +1447,7 @@ end
-- in opentype the italic correction of a limop is added to the width and luatex does
-- some juggling that we want to avoid but we need to do something here (in fact, we could
--- better fix the width of the character
+-- better fix the width of the character)
do
@@ -1382,8 +1464,8 @@ do
local c_negative_d = "trace:dr"
local function insert_kern(current,kern)
- local sub = new_submlist()
- local noad = new_noad()
+ local sub = new_submlist() -- todo: attr
+ local noad = new_noad() -- todo: attr
setlist(sub,kern)
setnext(kern,noad)
setnucleus(noad,current)
@@ -1393,7 +1475,7 @@ do
registertracker("math.italics.visualize", function(v)
if v then
italic_kern = function(k)
- local n = new_kern(k)
+ local n = new_kern(k) -- todo: attr
set_visual(n,"italic")
return n
end
@@ -1454,7 +1536,7 @@ do
end
- italics[math_char] = function(pointer,what,n,parent)
+ italics[mathchar_code] = function(pointer,what,n,parent)
local method = getattr(pointer,a_mathitalics)
if method and method > 0 and method < 100 then
local char = getchar(pointer)
@@ -1485,7 +1567,7 @@ do
function handlers.italics(head,style,penalties)
processnoads(head,italics,"italics")
- return true
+ return true -- not needed
end
local enable = function()
@@ -1582,7 +1664,7 @@ do
-- no correction after prime because that moved to a superscript
- kernpairs[math_char] = function(pointer,what,n,parent)
+ kernpairs[mathchar_code] = function(pointer,what,n,parent)
if getattr(pointer,a_kernpairs) == 1 then
local font = getfont(pointer)
local list = hash[font]
@@ -1591,7 +1673,7 @@ do
local found = list[first]
if found then
local next = getnext(parent)
- if next and getid(next) == math_noad then
+ if next and getid(next) == noad_code then
pointer = getnucleus(next)
if pointer then
if getfont(pointer) == font then
@@ -1602,7 +1684,7 @@ do
if trace_kernpairs then
report_kernpairs("adding %p kerning between %C and %C",kern,first,second)
end
- setlink(parent,new_kern(kern),getnext(parent))
+ setlink(parent,new_kern(kern),getnext(parent)) -- todo: attr
end
end
end
@@ -1614,7 +1696,7 @@ do
function handlers.kernpairs(head,style,penalties)
processnoads(head,kernpairs,"kernpairs")
- return true
+ return true -- not needed
end
end
@@ -1629,20 +1711,20 @@ do
local collapse = { }
local mathlists = characters.mathlists
local validpair = {
- [noad_ord] = true,
- [noad_rel] = true,
- [noad_bin] = true, -- new
- [noad_open] = true, -- new
- [noad_close] = true, -- new
- [noad_punct] = true, -- new
- [noad_opdisplaylimits] = true,
- [noad_oplimits] = true,
- [noad_opnolimits] = true,
+ [ordnoad_code] = true,
+ [relnode_code] = true,
+ [binnoad_code] = true, -- new
+ [opennoad_code] = true, -- new
+ [closenoad_code] = true, -- new
+ [punctnoad_code] = true, -- new
+ [opdisplaylimitsnoad_code] = true,
+ [oplimitsnoad_code] = true,
+ [opnolimitsnoad_code] = true,
}
local reported = setmetatableindex("table")
- collapse[math_char] = function(pointer,what,n,parent)
+ collapse[mathchar_code] = function(pointer,what,n,parent)
if parent and mathlists[getchar(pointer)] then
local found, last, lucleus, lsup, lsub, category
@@ -1727,7 +1809,7 @@ do
function noads.handlers.collapse(head,style,penalties)
processnoads(head,collapse,"collapse")
- return true
+ return true -- not needed
end
local enable = function()
@@ -1784,7 +1866,7 @@ do
-- local function movesubscript(parent,current_nucleus,oldchar,newchar)
-- local prev = getprev(parent)
- -- if prev and getid(prev) == math_noad then
+ -- if prev and getid(prev) == noad_code then
-- local psup = getsup(prev)
-- local psub = getsub(prev)
-- if not psup and not psub then
@@ -1827,7 +1909,7 @@ do
setnucleus(parent,dummy)
end
- fixscripts[math_char] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off
+ fixscripts[mathchar_code] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off
if parent then
local oldchar = getchar(pointer)
local newchar = movesub[oldchar]
@@ -1846,7 +1928,7 @@ do
-- print("[char] --- sup")
else
local prev = getprev(parent)
- if prev and getid(prev) == math_noad then
+ if prev and getid(prev) == noad_code then
local psub = getsub(prev)
local psup = getsup(prev)
if psub then
@@ -1875,7 +1957,7 @@ do
function noads.handlers.fixscripts(head,style,penalties)
processnoads(head,fixscripts,"fixscripts")
- return true
+ return true -- not needed
end
end
@@ -1901,14 +1983,14 @@ do
[0x2ACB] = 0xFE00, [0x2ACC] = 0xFE00,
}
- variants[math_char] = function(pointer,what,n,parent) -- also set export value
+ variants[mathchar_code] = function(pointer,what,n,parent) -- also set export value
local char = getchar(pointer)
local selector = validvariants[char]
if selector then
local next = getnext(parent)
- if next and getid(next) == math_noad then
+ if next and getid(next) == noad_code then
local nucleus = getnucleus(next)
- if nucleus and getid(nucleus) == math_char and getchar(nucleus) == selector then
+ if nucleus and getid(nucleus) == mathchar_code and getchar(nucleus) == selector then
local variant
local tfmdata = fontdata[getfont(pointer)]
local mathvariants = tfmdata.resources.variants -- and variantdata
@@ -1939,7 +2021,7 @@ do
function handlers.variants(head,style,penalties)
processnoads(head,variants,"unicode variant")
- return true
+ return true -- not needed
end
end
@@ -1950,25 +2032,25 @@ do
local classes = { }
local colors = {
- [noad_rel] = "trace:dr",
- [noad_ord] = "trace:db",
- [noad_bin] = "trace:dg",
- [noad_open] = "trace:dm",
- [noad_close] = "trace:dm",
- [noad_punct] = "trace:dc",
- -- [noad_opdisplaylimits] = "",
- -- [noad_oplimits] = "",
- -- [noad_opnolimits] = "",
- -- [noad_inner = "",
- -- [noad_under = "",
- -- [noad_over = "",
- -- [noad_vcenter = "",
+ [relnode_code] = "trace:dr",
+ [ordnoad_code] = "trace:db",
+ [binnoad_code] = "trace:dg",
+ [opennoad_code] = "trace:dm",
+ [closenoad_code] = "trace:dm",
+ [punctnoad_code] = "trace:dc",
+ -- [opdisplaylimitsnoad_code] = "",
+ -- [oplimitsnoad_code] = "",
+ -- [opnolimitsnoad_code] = "",
+ -- [innernoad_code = "",
+ -- [undernoad_code] = "",
+ -- [overnoad_code] = "",
+ -- [vcenternoad_code] = "",
}
local setcolor = colortracers.set
local resetcolor = colortracers.reset
- classes[math_char] = function(pointer,what,n,parent)
+ classes[mathchar_code] = function(pointer,what,n,parent)
local color = colors[getsubtype(parent)]
if color then
setcolor(pointer,color)
@@ -1979,7 +2061,7 @@ do
function handlers.classes(head,style,penalties)
processnoads(head,classes,"classes")
- return true
+ return true -- not needed
end
registertracker("math.classes",function(v)
@@ -2006,11 +2088,11 @@ do
local a_mathdomain = privateattribute("mathdomain")
mathematics.domains = categories
local permitted = {
- ordinary = noad_ord,
- binary = noad_bin,
- relation = noad_rel,
- punctuation = noad_punct,
- inner = noad_inner,
+ ordinary = ordnoad_code,
+ binary = binnoad_code,
+ relation = relnode_code,
+ punctuation = punctnoad_code,
+ inner = innernoad_code,
}
function mathematics.registerdomain(data)
@@ -2113,7 +2195,7 @@ do
return hash
end
- domains[math_char] = function(pointer,what,n,parent)
+ domains[mathchar_code] = function(pointer,what,n,parent)
local attr = getattr(pointer,a_mathdomain)
if attr then
local domain = numbers[attr]
@@ -2140,7 +2222,7 @@ do
function handlers.domains(head,style,penalties)
processnoads(head,domains,"domains")
- return true
+ return true -- not needed
end
end
@@ -2148,7 +2230,7 @@ end
-- just for me
function handlers.showtree(head,style,penalties)
- inspect(nodes.totree(head))
+ inspect(nodes.totree(tonut(head)))
end
registertracker("math.showtree",function(v)
@@ -2163,7 +2245,7 @@ do
local visual = false
function handlers.makeup(head)
- applyvisuals(tonut(head),visual)
+ applyvisuals(head,visual)
end
registertracker("math.makeup",function(v)
@@ -2184,9 +2266,15 @@ do
-- end)
function builders.kernel.mlist_to_hlist(head,style,penalties)
- return mlist_to_hlist(head,style,force_penalties or penalties), true
+ return mlist_to_hlist(head,style,force_penalties or penalties)
end
+ -- function builders.kernel.mlist_to_hlist(head,style,penalties)
+ -- local h = mlist_to_hlist(head,style,force_penalties or penalties)
+ -- inspect(nodes.totree(h,true,true,true))
+ -- return h
+ -- end
+
implement {
name = "setmathpenalties",
arguments = "integer",
@@ -2197,41 +2285,15 @@ do
end
--- function builders.kernel.mlist_to_hlist(head,style,penalties)
--- print("!!!!!!! BEFORE",penalties)
--- for n in node.traverse(head) do print(n) end
--- print("!!!!!!!")
--- head = mlist_to_hlist(head,style,penalties)
--- print("!!!!!!! AFTER")
--- for n in node.traverse(head) do print(n) end
--- print("!!!!!!!")
--- return head, true
--- end
-
-tasks.new {
- name = "math",
- arguments = 2,
- processor = utilities.sequencers.nodeprocessor,
- sequence = {
- "before",
- "normalizers",
- "builders",
- "after",
- },
-}
-
-tasks.freezegroup("math", "normalizers") -- experimental
-tasks.freezegroup("math", "builders") -- experimental
-
local actions = tasks.actions("math") -- head, style, penalties
local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
function processors.mlist_to_hlist(head,style,penalties)
starttiming(noads)
- local head, done = actions(head,style,penalties)
+ head = actions(head,style,penalties)
stoptiming(noads)
- return head, done
+ return head
end
callbacks.register('mlist_to_hlist',processors.mlist_to_hlist,"preprocessing math list")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-pln.mkiv b/Master/texmf-dist/tex/context/base/mkiv/math-pln.mkiv
index d0e7e377d12..1003444b86b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-pln.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-pln.mkiv
@@ -171,7 +171,7 @@
\crcr
\noalign\bgroup
\kern\scratchdimentwo
- \global\let\cr\endline
+ \glet\cr\endline
\egroup
}%
\ialign{%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-spa.lua b/Master/texmf-dist/tex/context/base/mkiv/math-spa.lua
index 92ee662b9a6..33d9501d818 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-spa.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-spa.lua
@@ -8,24 +8,23 @@ if not modules then modules = { } end modules ['math-spa'] = {
-- for the moment (when testing) we use a penalty 1
-local penalty_code = nodes.nodecodes.penalty
-local glue_code = nodes.nodecodes.glue
+local penalty_code = nodes.nodecodes.penalty
+local glue_code = nodes.nodecodes.glue
-local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
-local getid = nuts.getid
-local getnext = nuts.getnext
-local getwidth = nuts.getwidth
-local setglue = nuts.setglue
-local getpenalty = nuts.getpenalty
-local setpenalty = nuts.setpenalty
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+local tonode = nodes.tonode
-local traverse_id = nuts.traverse_id
-local get_dimensions = nuts.dimensions
+local getid = nuts.getid
+local getnext = nuts.getnext
+local getwidth = nuts.getwidth
+local setglue = nuts.setglue
+local getpenalty = nuts.getpenalty
+local setpenalty = nuts.setpenalty
+local getdimensions = nuts.dimensions
+local nextglue = nuts.traversers.glue
-
-local texsetdimen = tex.setdimen
+local texsetdimen = tex.setdimen
local v_none = interfaces.variables.none
local v_auto = interfaces.variables.auto
@@ -33,9 +32,8 @@ local v_auto = interfaces.variables.auto
local method = v_none
local distance = 0
-function noads.handlers.align(l)
+function noads.handlers.align(h)
if method ~= v_none then
- local h = tonut(l)
if method == v_auto then
local s = h
while s do
@@ -47,7 +45,7 @@ function noads.handlers.align(l)
s = n
n = getnext(s)
end
- local w = get_dimensions(h,n) + distance
+ local w = getdimensions(h,n) + distance
texsetdimen("global","d_strc_math_indent",w)
break
end
@@ -56,13 +54,12 @@ function noads.handlers.align(l)
else
texsetdimen("global","d_strc_math_indent",distance)
end
- for n in traverse_id(glue_code,h) do
+ for n in nextglue, h do
setglue(n,getwidth(n),0,0)
end
else
-- texsetdimen("global","d_strc_math_indent",0)
end
- return l, true
end
interfaces.implement {
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-stc.mkvi b/Master/texmf-dist/tex/context/base/mkiv/math-stc.mkvi
index c9d469d617c..92325d0afd0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-stc.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-stc.mkvi
@@ -413,13 +413,13 @@
\fi
%
\ifdim\wd\scratchboxone<\scratchwidth
- \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work
+ \setbox\scratchboxone\hpack to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work
\fi
\ifdim\wd\scratchboxtwo<\scratchwidth
- \setbox\scratchboxtwo\hbox to \scratchwidth{\hss\unhbox\scratchboxtwo\hss}%
+ \setbox\scratchboxtwo\hpack to \scratchwidth{\hss\unhbox\scratchboxtwo\hss}%
\fi
\ifdim\wd\scratchboxthree<\scratchwidth
- \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
+ \setbox\scratchboxthree\hpack to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
\fi
%
\ifcsname\??mathstackerslocation\p_location\endcsname
@@ -448,7 +448,7 @@
\fi
%
\ifzeropt\scratchdistance\else
- \setbox\scratchboxthree\hbox{\lower\scratchdistance\box\scratchboxthree}%
+ \setbox\scratchboxthree\hpack{\lower\scratchdistance\box\scratchboxthree}%
\fi
%
\math_stackers_normalize_three
@@ -603,7 +603,7 @@
\advance\scratchwidth2\scratchhoffset
%
\setbox\scratchboxtwo\csname\??mathstackersalternative\p_alternative\endcsname
- \setbox\scratchboxthree\hbox to \scratchwidth{\hss\box\scratchboxthree\hss}%
+ \setbox\scratchboxthree\hpack to \scratchwidth{\hss\box\scratchboxthree\hss}%
%
\scratchunicode#codeextra\relax
\ifcase\scratchunicode\else
@@ -803,10 +803,10 @@
\advance\scratchwidth2\scratchhoffset
%
\ifdim\wd\scratchboxone<\scratchwidth
- \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}%
+ \setbox\scratchboxone\hpack to \scratchwidth{\hss\unhbox\scratchboxone\hss}%
\fi
\ifdim\wd\scratchboxthree<\scratchwidth
- \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
+ \setbox\scratchboxthree\hpack to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
\fi
%
\math_stackers_normalize_three
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua b/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua
index d1ed90d389b..03f9e70bbbb 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua
@@ -14,90 +14,92 @@ if not modules then modules = { } end modules ['math-tag'] = {
local find, match = string.find, string.match
local insert, remove, concat = table.insert, table.remove, table.concat
-local attributes = attributes
-local nodes = nodes
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-
-local getnext = nuts.getnext
-local getid = nuts.getid
-local getchar = nuts.getchar
-local getfont = nuts.getfont
-local getlist = nuts.getlist
-local getfield = nuts.getfield
-local getdisc = nuts.getdisc
-local getsubtype = nuts.getsubtype
-local getattr = nuts.getattr
-local setattr = nuts.setattr
-local getcomponents = nuts.getcomponents
-local getwidth = nuts.getwidth
-
-local getnucleus = nuts.getnucleus
-local getsub = nuts.getsub
-local getsup = nuts.getsup
-
-local set_attributes = nuts.setattributes
-local traverse_nodes = nuts.traverse
-
-local nodecodes = nodes.nodecodes
-
-local math_noad_code = nodecodes.noad -- attr nucleus sub sup
-local math_accent_code = nodecodes.accent -- attr nucleus sub sup accent
-local math_radical_code = nodecodes.radical -- attr nucleus sub sup left degree
-local math_fraction_code = nodecodes.fraction -- attr nucleus sub sup left right
-local math_box_code = nodecodes.subbox -- attr list
-local math_sub_code = nodecodes.submlist -- attr list
-local math_char_code = nodecodes.mathchar -- attr fam char
-local math_textchar_code = nodecodes.mathtextchar -- attr fam char
-local math_delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char
-local math_style_code = nodecodes.style -- attr style
-local math_choice_code = nodecodes.choice -- attr display text script scriptscript
-local math_fence_code = nodecodes.fence -- attr subtype
-
-local accentcodes = nodes.accentcodes
-
-local math_fixed_top = accentcodes.fixedtop
-local math_fixed_bottom = accentcodes.fixedbottom
-local math_fixed_both = accentcodes.fixedboth
-
-local kerncodes = nodes.kerncodes
-
-local fontkern_code = kerncodes.fontkern
-local italickern_code = kerncodes.italickern
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local glyph_code = nodecodes.glyph
-local disc_code = nodecodes.disc
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local math_code = nodecodes.math
-
-local processnoads = noads.process
-
-local a_tagged = attributes.private('tagged')
-local a_mathcategory = attributes.private('mathcategory')
-local a_mathmode = attributes.private('mathmode')
-
-local tags = structures.tags
-
-local start_tagged = tags.start
-local restart_tagged = tags.restart
-local stop_tagged = tags.stop
-local taglist = tags.taglist
-
-local chardata = characters.data
-
-local getmathcodes = tex.getmathcodes
-local mathcodes = mathematics.codes
-local ordinary_code = mathcodes.ordinary
-local variable_code = mathcodes.variable
-
-local fromunicode16 = fonts.mappings.fromunicode16
-local fontcharacters = fonts.hashes.characters
-
-local report_tags = logs.reporter("structure","tags")
+local attributes = attributes
+local nodes = nodes
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getlist = nuts.getlist
+local getfield = nuts.getfield
+local getdisc = nuts.getdisc
+local getsubtype = nuts.getsubtype
+local getattr = nuts.getattr
+local getattrlist = nuts.getattrlist
+local setattr = nuts.setattr
+local getcomponents = nuts.getcomponents -- not really needed
+local getwidth = nuts.getwidth
+
+local getnucleus = nuts.getnucleus
+local getsub = nuts.getsub
+local getsup = nuts.getsup
+
+local set_attributes = nuts.setattributes
+
+local nextnode = nuts.traversers.node
+
+local nodecodes = nodes.nodecodes
+
+local noad_code = nodecodes.noad -- attr nucleus sub sup
+local accent_code = nodecodes.accent -- attr nucleus sub sup accent
+local radical_code = nodecodes.radical -- attr nucleus sub sup left degree
+local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right
+local subbox_code = nodecodes.subbox -- attr list
+local submlist_code = nodecodes.submlist -- attr list
+local mathchar_code = nodecodes.mathchar -- attr fam char
+local mathtextchar_code = nodecodes.mathtextchar -- attr fam char
+local delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char
+local style_code = nodecodes.style -- attr style
+local choice_code = nodecodes.choice -- attr display text script scriptscript
+local fence_code = nodecodes.fence -- attr subtype
+
+local accentcodes = nodes.accentcodes
+
+local fixedtopaccent_code = accentcodes.fixedtop
+local fixedbottomaccent_code = accentcodes.fixedbottom
+local fixedbothaccent_code = accentcodes.fixedboth
+
+local kerncodes = nodes.kerncodes
+
+local fontkern_code = kerncodes.fontkern
+local italickern_code = kerncodes.italickern
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+local math_code = nodecodes.math
+
+local processnoads = noads.process
+
+local a_tagged = attributes.private('tagged')
+local a_mathcategory = attributes.private('mathcategory')
+local a_mathmode = attributes.private('mathmode')
+
+local tags = structures.tags
+
+local start_tagged = tags.start
+local restart_tagged = tags.restart
+local stop_tagged = tags.stop
+local taglist = tags.taglist
+
+local chardata = characters.data
+
+local getmathcodes = tex.getmathcodes
+local mathcodes = mathematics.codes
+local ordinary_mathcode = mathcodes.ordinary
+local variable_mathcode = mathcodes.variable
+
+local fromunicode16 = fonts.mappings.fromunicode16
+local fontcharacters = fonts.hashes.characters
+
+local report_tags = logs.reporter("structure","tags")
local process
@@ -154,12 +156,19 @@ local fencesstack = { }
-- glyph nodes and such can happen in under and over stuff
+-- local function getunicode(n) -- instead of getchar
+-- local char = getchar(n)
+-- -- local font = font_of_family(getfield(n,"fam")) -- font_of_family
+-- local font = getfont(n)
+-- local data = fontcharacters[font][char]
+-- return data.unicode or char
+-- end
+
local function getunicode(n) -- instead of getchar
- local char = getchar(n)
- -- local font = font_of_family(getfield(n,"fam")) -- font_of_family
- local font = getfont(n)
+ -- local char, font = isglyph(n) -- no, we have a mathchar
+ local char, font = getchar(n), getfont(n)
local data = fontcharacters[font][char]
- return data.unicode or char
+ return data.unicode or char -- can be a table but unlikely for math characters
end
-------------------
@@ -167,7 +176,7 @@ end
local content = { }
local found = false
-content[math_char_code] = function() found = true end
+content[mathchar_code] = function() found = true end
local function hascontent(head)
found = false
@@ -177,18 +186,25 @@ end
--------------------
-local function showtag(n,id)
- local attr = getattr(n,a_tagged)
- report_tags("%s = %s",nodecodes[id or getid(n)],attr and taglist[attr].tagname or "?")
-end
+-- todo: use properties
+
+-- local function showtag(n,id,old)
+-- local attr = getattr(n,a_tagged)
+-- local curr = tags.current()
+-- report_tags("%s, node %s, attr %s:%s (%s), top %s (%s)",
+-- old and "before" or "after ",
+-- nodecodes[id],
+-- getattrlist(n),
+-- attr or "?",attr and taglist[attr].tagname or "?",
+-- curr or "?",curr and taglist[curr].tagname or "?"
+-- )
+-- end
process = function(start) -- we cannot use the processor as we have no finalizers (yet)
local mtexttag = nil
while start do
local id = getid(start)
-
--- showtag(start,id)
-
+ -- showtag(start,id,true)
if id == glyph_code or id == disc_code then
if not mtexttag then
mtexttag = start_tagged("mtext")
@@ -201,11 +217,11 @@ process = function(start) -- we cannot use the processor as we have no finalizer
stop_tagged()
mtexttag = nil
end
- if id == math_char_code then
+ if id == mathchar_code then
local char = getchar(start)
local code = getmathcodes(char)
local tag
- if code == ordinary_code or code == variable_code then
+ if code == ordinary_mathcode or code == variable_mathcode then
local ch = chardata[char]
local mc = ch and ch.mathclass
if mc == "number" then
@@ -225,8 +241,9 @@ process = function(start) -- we cannot use the processor as we have no finalizer
setattr(start,a_tagged,start_tagged(tag)) -- todo: a_mathcategory
end
stop_tagged()
+ -- showtag(start,id,false)
break -- okay?
- elseif id == math_textchar_code then -- or id == glyph_code
+ elseif id == mathtextchar_code then -- or id == glyph_code
-- check for code
local a = getattr(start,a_mathcategory)
if a then
@@ -235,116 +252,127 @@ process = function(start) -- we cannot use the processor as we have no finalizer
setattr(start,a_tagged,start_tagged("ms")) -- mtext
end
stop_tagged()
+ -- showtag(start,id,false)
break
- elseif id == math_delim_code then
+ elseif id == delim_code then
-- check for code
setattr(start,a_tagged,start_tagged("mo"))
stop_tagged()
+ -- showtag(start,id,false)
break
- elseif id == math_style_code then
+ elseif id == style_code then
-- has a next
- elseif id == math_noad_code then
+ elseif id == noad_code then
+ -- setattr(start,a_tagged,tags.current())
processsubsup(start)
- elseif id == math_box_code or id == hlist_code or id == vlist_code then
- -- keep an eye on math_box_code and see what ends up in there
+ elseif id == dubbox_code or id == hlist_code or id == vlist_code then
+ -- keep an eye on subbox_code and see what ends up in there
local attr = getattr(start,a_tagged)
-if not attr then
- -- just skip
-else
- local specification = taglist[attr]
- if specification then
- local tag = specification.tagname
- if tag == "formulacaption" then
- -- skip
- elseif tag == "mstacker" then
- local list = getlist(start)
- if list then
- process(list)
- end
- else
- if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then
- tag = "mtext"
- end
- local text = start_tagged(tag)
- setattr(start,a_tagged,text)
- local list = getlist(start)
- if not list then
- -- empty list
- elseif not attr then
- -- box comes from strange place
- set_attributes(list,a_tagged,text) -- only the first node ?
+ if not attr then
+ -- just skip
+ else
+ local specification = taglist[attr]
+ if specification then
+ local tag = specification.tagname
+ if tag == "formulacaption" then
+ -- skip
+ elseif tag == "mstacker" then
+ local list = getlist(start)
+ if list then
+ process(list)
+ end
else
- -- Beware, the first node in list is the actual list so we definitely
- -- need to nest. This approach is a hack, maybe I'll make a proper
- -- nesting feature to deal with this at another level. Here we just
- -- fake structure by enforcing the inner one.
- --
- -- todo: have a local list with local tags that then get appended
- --
- local tagdata = specification.taglist
- local common = #tagdata + 1
- local function runner(list,depth) -- quite inefficient
- local cache = { } -- we can have nested unboxed mess so best local to runner
- local keep = nil
- -- local keep = { } -- win case we might need to move keep outside
- for n in traverse_nodes(list) do
- local id = getid(n)
- local mth = id == math_code and getsubtype(n)
- if mth == 0 then
- -- insert(keep,text)
- keep = text
- text = start_tagged("mrow")
- common = common + 1
- end
- local aa = getattr(n,a_tagged)
- if aa then
- local ac = cache[aa]
- if not ac then
- local tagdata = taglist[aa].taglist
- local extra = #tagdata
- if common <= extra then
- for i=common,extra do
- ac = restart_tagged(tagdata[i]) -- can be made faster
- end
- for i=common,extra do
- stop_tagged() -- can be made faster
+ if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then
+ tag = "mtext"
+ end
+ local text = start_tagged(tag)
+ setattr(start,a_tagged,text)
+ local list = getlist(start)
+ if not list then
+ -- empty list
+ elseif not attr then
+ -- box comes from strange place
+ set_attributes(list,a_tagged,text) -- only the first node ?
+ else
+ -- Beware, the first node in list is the actual list so we definitely
+ -- need to nest. This approach is a hack, maybe I'll make a proper
+ -- nesting feature to deal with this at another level. Here we just
+ -- fake structure by enforcing the inner one.
+ --
+ -- todo: have a local list with local tags that then get appended
+ --
+ local tagdata = specification.taglist
+ local common = #tagdata + 1
+ local function runner(list,depth) -- quite inefficient
+ local cache = { } -- we can have nested unboxed mess so best local to runner
+ local keep = nil
+ -- local keep = { } -- win case we might need to move keep outside
+ for n, id, subtype in nextnode, list do
+ local mth = id == math_code and subtype
+ if mth == 0 then -- hm left_code
+ -- insert(keep,text)
+ keep = text
+ text = start_tagged("mrow")
+ common = common + 1
+ end
+ local aa = getattr(n,a_tagged)
+ if aa then
+ local ac = cache[aa]
+ if not ac then
+ local tagdata = taglist[aa].taglist
+ local extra = #tagdata
+ if common <= extra then
+ for i=common,extra do
+ ac = restart_tagged(tagdata[i]) -- can be made faster
+ end
+ for i=common,extra do
+ stop_tagged() -- can be made faster
+ end
+ else
+ ac = text
end
- else
- ac = text
+ cache[aa] = ac
end
- cache[aa] = ac
+ setattr(n,a_tagged,ac)
+ else
+ setattr(n,a_tagged,text)
+ end
+ if id == hlist_code or id == vlist_code then
+ runner(getlist(n),depth+1)
+ elseif id == glyph_code then
+ -- this should not be needed
+ local components = getcomponents(n) -- unlikely set
+ if components then
+ runner(getcomponent,depth+1)
+ end
+ elseif id == disc_code then
+ -- this should not be needed
+ local pre, post, replace = getdisc(n)
+ if pre then
+ runner(pre,depth+1)
+ end
+ if post then
+ runner(post,depth+1)
+ end
+ if replace then
+ runner(replace,depth+1)
+ end
+ end
+ if mth == 1 then
+ stop_tagged()
+ -- text = remove(keep)
+ text = keep
+ common = common - 1
end
- setattr(n,a_tagged,ac)
- else
- setattr(n,a_tagged,text)
- end
-
- if id == hlist_code or id == vlist_code then
- runner(getlist(n),depth+1)
- elseif id == glyph_code then
- -- this should not be needed (todo: use tounicode info)
- runner(getcomponents(n),depth+1)
- elseif id == disc_code then
- local pre, post, replace = getdisc(n)
- runner(pre,depth+1) -- idem
- runner(post,depth+1) -- idem
- runner(replace,depth+1) -- idem
- end
- if mth == 1 then
- stop_tagged()
- -- text = remove(keep)
- text = keep
- common = common - 1
end
end
+ runner(list,0)
end
- runner(list,0)
+ stop_tagged()
end
- stop_tagged()
end
end
-end
- elseif id == math_sub_code then -- normally a hbox
+ elseif id == submlistcode then -- normally a hbox
local list = getlist(start)
if list then
local attr = getattr(start,a_tagged)
@@ -370,7 +398,7 @@ end
end
elseif tag == "mstacker" then -- or tag == "mstackertop" or tag == "mstackermid" or tag == "mstackerbot" then
-- looks like it gets processed twice
--- do we still end up here ?
+ -- do we still end up here ?
setattr(start,a_tagged,restart_tagged(attr)) -- so we just reuse the attribute
process(list)
stop_tagged()
@@ -385,7 +413,7 @@ end
stop_tagged()
end
end
- elseif id == math_fraction_code then
+ elseif id == fraction_code then
local num = getfield(start,"num")
local denom = getfield(start,"denom")
local left = getfield(start,"left")
@@ -404,7 +432,7 @@ end
process(right)
stop_tagged()
end
- elseif id == math_choice_code then
+ elseif id == choice_code then
local display = getfield(start,"display")
local text = getfield(start,"text")
local script = getfield(start,"script")
@@ -421,7 +449,7 @@ end
if scriptscript then
process(scriptscript)
end
- elseif id == math_fence_code then
+ elseif id == fence_code then
local delim = getfield(start,"delim")
local subtype = getfield(start,"subtype")
if subtype == 1 then
@@ -478,7 +506,7 @@ end
else
-- can't happen
end
- elseif id == math_radical_code then
+ elseif id == radical_code then
local left = getfield(start,"left")
local degree = getfield(start,"degree")
if left then
@@ -496,7 +524,7 @@ end
processsubsup(start)
stop_tagged()
end
- elseif id == math_accent_code then
+ elseif id == accent_code then
local accent = getfield(start,"accent")
local bot_accent = getfield(start,"bot_accent")
local subtype = getsubtype(start)
@@ -506,8 +534,8 @@ end
accent = true,
top = getunicode(accent),
bottom = getunicode(bot_accent),
- topfixed = subtype == math_fixed_top or subtype == math_fixed_both,
- bottomfixed = subtype == math_fixed_bottom or subtype == math_fixed_both,
+ topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code,
+ bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code,
}))
processsubsup(start)
process(bot_accent)
@@ -517,7 +545,7 @@ end
setattr(start,a_tagged,start_tagged("munder", {
accent = true,
bottom = getunicode(bot_accent),
- bottomfixed = subtype == math_fixed_bottom or subtype == math_fixed_both,
+ bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code,
}))
processsubsup(start)
process(bot_accent)
@@ -527,7 +555,7 @@ end
setattr(start,a_tagged,start_tagged("mover", {
accent = true,
top = getunicode(accent),
- topfixed = subtype == math_fixed_top or subtype == math_fixed_both,
+ topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code,
}))
processsubsup(start)
process(accent)
@@ -544,6 +572,7 @@ end
stop_tagged()
end
end
+-- showtag(start,id,false)
start = getnext(start)
end
if mtexttag then
@@ -552,12 +581,10 @@ end
end
function noads.handlers.tags(head,style,penalties)
- head = tonut(head)
- local v_mode = getattr(head,a_mathmode)
- local v_math = start_tagged("math", { mode = v_mode == 1 and "display" or "inline" })
+ start_tagged("math", { mode = (getattr(head,a_mathmode) == 1) and "display" or "inline" })
+-- start_tagged("mrow")
setattr(head,a_tagged,start_tagged("mrow"))
process(head)
stop_tagged()
stop_tagged()
- return true
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-vfu.lua b/Master/texmf-dist/tex/context/base/mkiv/math-vfu.lua
index 4767ffa90f6..ed6f69f41d9 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/math-vfu.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/math-vfu.lua
@@ -46,9 +46,18 @@ fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vecto
local vfmath = allocate()
fonts.handlers.vf.math = vfmath
+local helpers = fonts.helpers
+local vfcommands = helpers.commands
+local rightcommand = vfcommands.right
+local leftcommand = vfcommands.left
+local downcommand = vfcommands.down
+local upcommand = vfcommands.up
+local push = vfcommands.push
+local pop = vfcommands.pop
+
local shared = { }
--- local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 }
+-- local back = { "slot", 1, 0x2215 }
--
-- local function negate(main,characters,id,size,unicode,basecode)
-- if not characters[unicode] then
@@ -64,8 +73,8 @@ local shared = { }
-- commands = {
-- { "slot", 1, basecode },
-- push,
--- { "down", ht/5},
--- { "right", - wd/2},
+-- downcommand[ht/5],
+-- leftcommand[wd/2],
-- back,
-- push,
-- }
@@ -139,107 +148,96 @@ local function parent(main,characters,id,size,unicode,first,rule,last)
end
end
-local push, pop, step = { "push" }, { "pop" }, 0.2 -- 0.1 is nicer but gives larger files
+local step = 0.2 -- 0.1 is nicer but gives larger files
local function make(main,characters,id,size,n,m)
local old = 0xFF000 + n
- local c = characters[old]
+ local c = characters[old]
if c then
- local upslot, dnslot, uprule, dnrule = 0xFF100 + n, 0xFF200 + n, 0xFF300 + m, 0xFF400 + m
- local xu = main.parameters.x_height + 0.3*size
- local xd = 0.3*size
- local w, h, d = c.width, c.height, c.depth
+ local upslot = 0xFF100 + n
+ local dnslot = 0xFF200 + n
+ local uprule = 0xFF300 + m
+ local dnrule = 0xFF400 + m
+ local xu = main.parameters.x_height + 0.3*size
+ local xd = 0.3*size
+ local w = c.width or 0
+ local h = c.height or 0
+ local d = c.depth or 0
local thickness = h - d
local rulewidth = step*size -- we could use an overlap
- local slot = { "slot", id, old }
- local rule = { "rule", thickness, rulewidth }
- local up = { "down", -xu }
- local dn = { "down", xd }
- local ht, dp = xu + 3*thickness, 0
+ local slot = { "slot", id, old }
+ local rule = { "rule", thickness, rulewidth }
+ local up = upcommand[xu]
+ local dn = downcommand[xd]
+ local ht = xu + 3*thickness
+ local dp = 0
if not characters[uprule] then
- characters[uprule] = { width = rulewidth, height = ht, depth = dp, commands = { push, up, rule, pop } }
+ characters[uprule] = {
+ width = rulewidth,
+ height = ht,
+ depth = dp,
+ commands = { push, up, rule, pop },
+ }
end
- characters[upslot] = { width = w, height = ht, depth = dp, commands = { push, up, slot, pop } }
- local ht, dp = 0, xd + 3*thickness
+ characters[upslot] = {
+ width = w,
+ height = ht,
+ depth = dp,
+ commands = { push, up, slot, pop },
+ }
+ local ht = 0
+ local dp = xd + 3*thickness
if not characters[dnrule] then
- characters[dnrule] = { width = rulewidth, height = ht, depth = dp, commands = { push, dn, rule, pop } }
+ characters[dnrule] = {
+ width = rulewidth,
+ height = ht,
+ depth = dp,
+ commands = { push, dn, rule, pop }
+ }
end
- characters[dnslot] = { width = w, height = ht, depth = dp, commands = { push, dn, slot, pop } }
+ characters[dnslot] = {
+ width = w,
+ height = ht,
+ depth = dp,
+ commands = { push, dn, slot, pop },
+ }
end
end
local function clipped(main,characters,id,size,unicode,original) -- push/pop needed?
local minus = characters[original]
if minus then
- local mu = size/18
- local step = 3*mu
+ local mu = size/18
+ local step = 3*mu
local width = minus.width
if width > step then
width = width - step
- step = step / 2
+ step = step / 2
else
width = width / 2
- step = width
+ step = width
end
characters[unicode] = {
width = width,
height = minus.height,
depth = minus.depth,
- commands = { push, { "right", -step }, { "slot", id, original }, pop }
+ commands = {
+ push,
+ leftcommand[step],
+ { "slot", id, original },
+ pop,
+ }
}
end
end
--- fails: pdf:page: pdf:direct: ... some funny displacement
-
--- this does not yet work ... { "scale", 2, 0, 0, 3 } .. commented code
---
--- this does not work ... no interpretation going on here
---
--- local nodeinjections = backends.nodeinjections
--- { "node", nodeinjections.save() },
--- { "node", nodeinjections.transform(.7,0,0,.7) },
--- commands[#commands+1] = { "node", nodeinjections.restore() }
-
--- local done = { }
---
--- local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess
--- local raised = characters[private]
--- if raised then
--- if not done[unicode] then
--- report_virtual("temporary too large %U due to issues in luatex backend",unicode)
--- done[unicode] = true
--- end
--- local up = 0.85 * main.parameters.x_height
--- local slot = { "slot", id, private }
--- local commands = {
--- push,
--- { "down", - up },
--- -- { "scale", .7, 0, 0, .7 },
--- slot,
--- }
--- for i=2,n do
--- commands[#commands+1] = slot
--- end
--- commands[#commands+1] = pop
--- characters[unicode] = {
--- width = .7 * n * raised.width,
--- height = .7 * (raised.height + up),
--- depth = .7 * (raised.depth - up),
--- commands = commands,
--- }
--- end
--- end
-
local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess
local raised = fonts.hashes.characters[main.fonts[id_of_smaller].id][private] -- characters[private]
if raised then
- local up = 0.85 * main.parameters.x_height
+ local up = 0.85 * main.parameters.x_height
local slot = { "slot", id_of_smaller, private }
local commands = {
- push,
- { "down", - up },
- slot,
+ push, upcommand[up], slot,
}
for i=2,n do
commands[#commands+1] = slot
@@ -258,65 +256,85 @@ end
local function dots(main,characters,id,size,unicode)
local c = characters[0x002E]
if c then
- local w, h, d = c.width, c.height, c.depth
- local mu = size/18
- local right3mu = { "right", 3*mu }
- local right1mu = { "right", 1*mu }
- local up1size = { "down", -.1*size }
- local up4size = { "down", -.4*size }
- local up7size = { "down", -.7*size }
- local right2muw = { "right", 2*mu + w }
- local slot = { "slot", id, 0x002E }
+ local w = c.width
+ local h = c.height
+ local d = c.depth
+ local mu = size/18
+ local right3mu = rightcommand[3*mu]
+ local right1mu = rightcommand[1*mu]
+ local up1size = upcommand[.1*size]
+ local up4size = upcommand[.4*size]
+ local up7size = upcommand[.7*size]
+ local right2muw = rightcommand[2*mu + w]
+ local slot = { "slot", id, 0x002E }
if unicode == 0x22EF then
local c = characters[0x022C5]
if c then
- local w, h, d = c.width, c.height, c.depth
- local slot = { "slot", id, 0x022C5 }
+ local width = c.width
+ local height = c.height
+ local depth = c.depth
+ local slot = { "slot", id, 0x022C5 }
characters[unicode] = {
- width = 3*w + 2*3*mu, height = h, depth = d,
- commands = { push, slot, right3mu, slot, right3mu, slot, pop }
+ width = 3*width + 2*3*mu,
+ height = height,
+ depth = depth,
+ commands = {
+ push, slot, right3mu, slot, right3mu, slot, pop,
+ }
}
end
elseif unicode == 0x22EE then
-- weird height !
characters[unicode] = {
- width = w, height = h+(1.4)*size, depth = 0,
- commands = { push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop }
+ width = w,
+ height = h+(1.4)*size,
+ depth = 0,
+ commands = {
+ push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop,
+ }
}
elseif unicode == 0x22F1 then
characters[unicode] = {
- width = 3*w + 6*size/18, height = 1.5*size, depth = 0,
+ width = 3*w + 6*size/18,
+ height = 1.5*size,
+ depth = 0,
commands = {
push,
- right1mu,
- push, up7size, slot, pop,
- right2muw,
- push, up4size, slot, pop,
- right2muw,
- push, up1size, slot, pop,
- right1mu,
+ right1mu,
+ push, up7size, slot, pop,
+ right2muw,
+ push, up4size, slot, pop,
+ right2muw,
+ push, up1size, slot, pop,
+ right1mu,
pop
}
}
elseif unicode == 0x22F0 then
characters[unicode] = {
- width = 3*w + 6*size/18, height = 1.5*size, depth = 0,
+ width = 3*w + 6*size/18,
+ height = 1.5*size,
+ depth = 0,
commands = {
push,
- right1mu,
- push, up1size, slot, pop,
- right2muw,
- push, up4size, slot, pop,
- right2muw,
- push, up7size, slot, pop,
- right1mu,
+ right1mu,
+ push, up1size, slot, pop,
+ right2muw,
+ push, up4size, slot, pop,
+ right2muw,
+ push, up7size, slot, pop,
+ right1mu,
pop
}
}
else
characters[unicode] = {
- width = 3*w + 2*3*mu, height = h, depth = d,
- commands = { push, slot, right3mu, slot, right3mu, slot, pop }
+ width = 3*w + 2*3*mu,
+ height = h,
+ depth = d,
+ commands = {
+ push, slot, right3mu, slot, right3mu, slot, pop,
+ }
}
end
end
@@ -331,21 +349,23 @@ local function vertbar(main,characters,id,size,parent,scale,unicode)
width = cp.width,
height = cp.height + sc,
depth = cp.depth + sc,
+ next = cp.next, -- can be extensible
commands = {
- push, { "down", -sc }, pc, pop,
- push, { "down", sc }, pc, pop,
+ push, upcommand [sc], pc, pop,
+ push, downcommand[sc], pc, pop,
pc,
},
- next = cp.next -- can be extensible
}
cp.next = unicode
end
end
local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what)
- local c1, c2 = characters[u1], characters[u2]
+ local c1 = characters[u1]
+ local c2 = characters[u2]
if c1 and c2 then
- local w1, w2 = c1.width, c2.width
+ local w1 = c1.width
+ local w2 = c2.width
local mu = size/18
characters[unicode] = {
width = w1 + w2 - d12 * mu,
@@ -353,7 +373,7 @@ local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what)
depth = max(c1.depth or 0, c2.depth or 0),
commands = {
{ "slot", id, u1 },
- { "right", -d12*mu } ,
+ leftcommand[d12*mu],
{ "slot", id, u2 },
},
}
@@ -361,19 +381,23 @@ local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what)
end
local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3)
- local c1, c2, c3 = characters[u1], characters[u2], characters[u3]
+ local c1 = characters[u1]
+ local c2 = characters[u2]
+ local c3 = characters[u3]
if c1 and c2 and c3 then
- local w1, w2, w3 = c1.width, c2.width, c3.width
+ local w1 = c1.width
+ local w2 = c2.width
+ local w3 = c3.width
local mu = size/18
characters[unicode] = {
width = w1 + w2 + w3 - d12*mu - d23*mu,
height = max(c1.height or 0, c2.height or 0, c3.height or 0),
- depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0),
+ depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0),
commands = {
{ "slot", id, u1 },
- { "right", - d12*mu } ,
+ leftcommand[d12*mu],
{ "slot", id, u2 },
- { "right", - d23*mu },
+ leftcommand[d23*mu],
{ "slot", id, u3 },
}
}
@@ -381,24 +405,32 @@ local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3)
end
local function stack(main,characters,id,size,unicode,u1,d12,u2)
- local c1, c2 = characters[u1], characters[u2]
- if c1 and c2 then
- local w1, w2 = c1.width, c2.width
- local h1, h2 = c1.height, c2.height
- local d1, d2 = c1.depth, c2.depth
- local mu = size/18
- characters[unicode] = {
- width = w1,
- height = h1 + h2 + d12,
- depth = d1,
- commands = {
- { "slot", id, u1 },
- { "right", - w1/2 - w2/2 } ,
- { "down", -h1 + d2 -d12*mu } ,
- { "slot", id, u2 },
- }
- }
+ local c1 = characters[u1]
+ if not c1 then
+ return
+ end
+ local c2 = characters[u2]
+ if not c2 then
+ return
end
+ local w1 = c1.width or 0
+ local h1 = c1.height or 0
+ local d1 = c1.depth or 0
+ local w2 = c2.width or 0
+ local h2 = c2.height or 0
+ local d2 = c2.depth or 0
+ local mu = size/18
+ characters[unicode] = {
+ width = w1,
+ height = h1 + h2 + d12,
+ depth = d1,
+ commands = {
+ { "slot", id, u1 },
+ leftcommand[w1/2 + w2/2],
+ downcommand[-h1 + d2 -d12*mu],
+ { "slot", id, u2 },
+ }
+ }
end
local function repeated(main,characters,id,size,unicode,u,n,private,fraction) -- math-fbk.lua
@@ -406,16 +438,14 @@ local function repeated(main,characters,id,size,unicode,u,n,private,fraction) --
if c then
local width = c.width
local italic = fraction*width -- c.italic or 0 -- larger ones have funny italics
- local tc = { "slot", id, u }
- local tr = { "right", -italic } -- see hack elsewhere
+ local tc = { "slot", id, u }
+ local tr = leftcommand[italic] -- see hack elsewhere
local commands = { }
for i=1,n-1 do
commands[#commands+1] = tc
commands[#commands+1] = tr
end
commands[#commands+1] = tc
--- inspect(c)
--- inspect(commands)
local next = c.next
if next then
repeated(main,characters,id,size,private,next,n,private+1,fraction)
@@ -589,7 +619,8 @@ setmetatableindex(reverse, function(t,name)
if trace_virtual then
report_virtual("initializing math vector %a",name)
end
- local m, r = mathencodings[name], { }
+ local m = mathencodings[name]
+ local r = { }
for u, i in next, m do
r[i] = u
end
@@ -597,6 +628,10 @@ setmetatableindex(reverse, function(t,name)
return r
end)
+-- use char and font hash
+--
+-- commands = { { "font", slot }, { "char", unicode } },
+
local function copy_glyph(main,target,original,unicode,slot)
local addprivate = fonts.helpers.addprivate
local olddata = original[unicode]
@@ -623,7 +658,6 @@ local function copy_glyph(main,target,original,unicode,slot)
}
local newnextglyph = addprivate(main,formatters["M-N-%H"](nextglyph),newnextdata)
newdata.next = newnextglyph
--- report_virtual("copied next: %X",newdata.next)
local nextnextglyph = oldnextdata.next
if nextnextglyph == nextglyph then
break
@@ -649,7 +683,6 @@ local function copy_glyph(main,target,original,unicode,slot)
commands = { { "slot", slot, oldglyph } },
}
hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata)
--- report_virtual("copied h variant: %X at index %i",hvi.glyph,i)
end
end
local vv = olddata.vert_variants
@@ -668,7 +701,6 @@ local function copy_glyph(main,target,original,unicode,slot)
commands = { { "slot", slot, oldglyph } },
}
vvi.glyph = addprivate(main,formatters["M-V-%H"](oldglyph),newdata)
--- report_virtual("copied v variant: %X at index %i",vvi.glyph,i)
end
end
return newdata
@@ -678,13 +710,17 @@ end
vfmath.copy_glyph = copy_glyph
function vfmath.define(specification,set,goodies)
- local name = specification.name -- symbolic name
- local size = specification.size -- given size
- local loaded, fontlist, names, main = { }, { }, { }, nil
- local start = (trace_virtual or trace_timings) and os.clock()
- local okset, n = { }, 0
+ local name = specification.name -- symbolic name
+ local size = specification.size -- given size
+ local loaded = { }
+ local fontlist = { }
+ local names = { }
+ local main = nil
+ local start = (trace_virtual or trace_timings) and os.clock()
+ local okset = { }
+ local n = 0
for s=1,#set do
- local ss = set[s]
+ local ss = set[s]
local ssname = ss.name
if add_optional and ss.optional then
if trace_virtual then
@@ -828,11 +864,11 @@ function vfmath.define(specification,set,goodies)
elseif add_optional and ss.optional then
-- skip, redundant
else
- local newparameters = fs.parameters
+ local newparameters = fs.parameters
local newmathparameters = fs.mathparameters
if newmathparameters then
if not parameters_done or ss.parameters then
- mathparameters = newmathparameters
+ mathparameters = newmathparameters
parameters_done = true
end
elseif not newparameters then
@@ -867,7 +903,7 @@ function vfmath.define(specification,set,goodies)
-- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size)
end
if ss.overlay then
- local fc = fs.characters
+ local fc = fs.characters
local first = ss.first
if first then
local last = ss.last or first
@@ -882,12 +918,14 @@ function vfmath.define(specification,set,goodies)
else
local vectorname = ss.vector
if vectorname then
- local offset = 0xFF000
- local vector = mathencodings[vectorname]
- local rotcev = reverse[vectorname]
+ local offset = 0xFF000
+ local vector = mathencodings[vectorname]
+ local rotcev = reverse[vectorname]
local isextension = ss.extension
if vector and rotcev then
- local fc, fd, si = fs.characters, fs.descriptions, shared[s]
+ local fc = fs.characters
+ local fd = fs.descriptions
+ local si = shared[s]
local skewchar = ss.skewchar
for unicode, index in next, vector do
local fci = fc[index]
@@ -913,8 +951,8 @@ function vfmath.define(specification,set,goodies)
ref = { { 'slot', s, index } }
si[index] = ref
end
- local kerns = fci.kerns
- local width = fci.width
+ local kerns = fci.kerns
+ local width = fci.width
local italic = fci.italic
if italic and italic > 0 then
-- int_a^b
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua
new file mode 100644
index 00000000000..e1c0de74f37
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua
@@ -0,0 +1,322 @@
+if not modules then modules = { } end modules ['meta-blb'] = {
+ version = 1.001,
+ comment = "companion to mlib-ctx.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- This could be integrated in other modules but for me it also serves
+-- as an example of usign the plugin mechanism.
+
+local tonumber = tonumber
+
+local setmetatableindex = table.setmetatableindex
+local insert, remove = table.insert, table.remove
+local formatters = string.formatters
+
+local topoints = number.topoints
+local mpprint = mp.print
+local mpinteger = mp.integer
+local mppoints = mp.points
+local mptriplet = mp.triplet
+local mptripletpoints = mp.tripletpoints
+
+local nuts = nodes.nuts
+local hpack = nuts.hpack
+local setbox = nuts.setbox
+local getwhd = nuts.getwhd
+local getwidth = nuts.getwidth
+local toutf = nuts.toutf
+
+local trace = false
+local report = logs.reporter("metapost","blobs")
+
+trackers.register("metapost.blobs", function(v) trace = v end)
+
+local allblobs = { }
+
+local function newcategory(t,k)
+ if trace then
+ report("new category %a",k)
+ end
+ local v = {
+ name = k,
+ text = "",
+ blobs = { },
+ }
+ t[k] = v
+ return v
+end
+
+local texblobs = setmetatableindex(newcategory)
+
+local function blob_raw_reset(category)
+ -- we need to keep the allblobs
+ if category then
+ if trace then
+ report("reset category %a",category)
+ end
+ texblobs[category] = nil
+ else
+ if trace then
+ report("reset all")
+ end
+ texblobs = setmetatableindex(newcategory)
+ end
+end
+
+local function blob_raw_dimensions(i)
+ local blob = allblobs[i]
+ if blob then
+ return getwhd(blob)
+ else
+ return 0, 0, 0
+ end
+end
+
+local function blob_raw_content(i)
+ return allblobs[i]
+end
+
+local function blob_raw_toutf(i)
+ return toutf(allblobs[i])
+end
+
+local function blob_raw_wipe(i)
+ allblobs[i] = false
+end
+
+mp.mf_blob_raw_dimensions = blob_raw_dimensions
+mp.mf_blob_raw_content = blob_raw_content
+mp.mf_blob_raw_reset = blob_raw_reset
+mp.mf_blob_raw_wipe = blob_raw_wipe
+mp.mf_blob_raw_toutf = blob_raw_toutf
+
+function mp.mf_blob_new(category,text)
+ if trace then
+ report("category %a, text %a",category,text)
+ end
+ texblobs[category].text = text
+end
+
+function mp.mf_blob_add(category,blob)
+ local tb = texblobs[category].blobs
+ local tn = #allblobs + 1
+ blob = hpack(blob)
+ allblobs[tn] = blob
+ tb[#tb+1] = tn
+ if trace then
+ report("category %a, blob %a set, content %a",category,tn,blob_raw_toutf(tn))
+ end
+end
+
+function mp.mf_blob_width(category,i)
+ local index = texblobs[category].blobs[i]
+ local blob = allblobs[index]
+ if blob then
+ mppoints(getwidth(blob) or 0)
+ else
+ mpinteger(0)
+ end
+end
+
+function mp.mf_blob_size(category,i)
+ mpprint(#texblobs[category].blobs or 0)
+end
+
+function mp.mf_blob_index(category,i)
+ mpprint(texblobs[category].blobs[i] or 0)
+end
+
+function mp.mf_blob_dimensions(category,i)
+ local index = texblobs[category].blobs[i]
+ local blob = allblobs[index]
+ if blob then
+ mptripletpoints(getwhd(blob))
+ else
+ mptriplet(0,0,0)
+ end
+end
+
+local sxsy = metapost.sxsy
+local cm = metapost.cm
+
+local f_f = formatters["%.6F"]
+
+directives.register("pdf.stripzeros",function()
+ f_f = formatters["%.6N"]
+end)
+
+local function injectblob(object,blob)
+ local sx, rx, ry, sy, tx, ty = cm(object)
+ local wd, ht, dp = blob_raw_dimensions(blob)
+ if wd then
+ object.path = false
+ object.color = false
+ object.grouped = true
+ object.istext = true
+ return function()
+ if trace then
+ report("injecting blob %a, width %p, heigth %p, depth %p, text %a",blob,wd,ht,dp,blob_raw_toutf(blob))
+ end
+ context.MPLIBgetblobscaledcm(blob,
+ f_f(sx), f_f(rx), f_f(ry),
+ f_f(sy), f_f(tx), f_f(ty),
+ sxsy(wd,ht,dp))
+ end
+ end
+end
+
+-- mp.mf_blob_inject = injectblob
+
+local function getblob(box,blob)
+ setbox(box,blob_raw_content(blob))
+ blob_raw_wipe(blob)
+end
+
+interfaces.implement {
+ name = "mpgetblob",
+ actions = getblob,
+ arguments = { "integer", "integer" },
+}
+
+-- the plug:
+
+
+local function reset()
+ blob_raw_reset()
+end
+
+local function process(object,prescript,before,after)
+-- if prescript.tb_stage == "inject" then
+ local tb_blob = tonumber(prescript.tb_blob)
+ if tb_blob then
+ before[#before+1] = injectblob(object,tb_blob)
+ end
+-- end
+end
+
+metapost.installplugin {
+ name = "texblob",
+ reset = reset,
+ process = process,
+}
+
+-- Here follows an example of usage of the above: a more modern
+-- version of followokens (in meta-imp-txt.mkiv).
+
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
+
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+
+local fontkern_code = kerncodes.fontkern
+local italickern_code = kerncodes.italickern
+
+local a_fontkern = attributes.private("fontkern")
+
+local nuts = nodes.nuts
+local takebox = nuts.takebox
+local getlist = nuts.getlist
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local getnext = nuts.getnext
+local flatten_list = nuts.flatten_discretionaries
+local remove_node = nuts.remove
+local flush_node = nuts.flush
+
+local addblob = mp.mf_blob_add
+local newblob = mp.mf_blob_new
+
+local visible_codes = {
+ [nodecodes.glyph] = true,
+ [nodecodes.glue] = true,
+ [nodecodes.hlist] = true,
+ [nodecodes.vlist] = true,
+ [nodecodes.rule] = true,
+}
+
+local function initialize(category,box)
+ local wrap = takebox(box)
+ if wrap then
+ local head = getlist(wrap)
+ local tail = nil
+ local temp = nil
+ if head then
+ local n = { }
+ local s = 0
+ head = flatten_list(head)
+ local current = head
+ while current do
+ local id = getid(current)
+ if visible_codes[id] then
+ head, current, tail = remove_node(head,current)
+ s = s + 1
+ n[s] = tail
+ elseif id == kern_code then
+ local subtype = getsubtype(current)
+ if subtype == fontkern_code or subtype == italickern_code then -- or current[a_fontkern]
+ head, current, temp = remove_node(head,current)
+ setlink(tail,temp)
+ else
+ head, current, temp = remove_node(head,current)
+ s = s + 1
+ n[s] = temp
+ end
+ elseif id == glue_code then
+ head, current, temp = remove_node(head,current)
+ s = s + 1
+ n[s] = temp
+ else
+ current = getnext(current)
+ end
+ end
+ for i=1,s do
+ n[i] = addblob(category,n[i])
+ end
+ setlist(wrap,head)
+ end
+ flush_node(wrap)
+ end
+end
+
+interfaces.implement {
+ name = "MPLIBconvertfollowtext",
+ arguments = { "integer","integer" },
+ actions = initialize,
+}
+
+local mp_category = 0
+local mp_str = ""
+
+function mp.mf_inject_blob(category,str)
+ newblob(category,str) -- only for tracing
+ mp_category = category
+ mp_str = str
+ tex.runtoks("mpblobtext")
+end
+
+interfaces.implement {
+ name = "mpblobtext",
+ actions = function()
+ context.MPLIBfollowtext(mp_category,mp_str)
+ end
+}
+
+local process = function(object,prescript,before,after)
+ if prescript.ft_category then
+ object.path = false
+ object.color = false
+ object.grouped = true
+ object.istext = true
+ end
+end
+
+metapost.installplugin {
+ name = "followtext",
+ process = process,
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-blb.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.mkiv
new file mode 100644
index 00000000000..4a5381dfc43
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.mkiv
@@ -0,0 +1,56 @@
+%D \module
+%D [ file=meta-blb,
+%D version=2018.04.12,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Blobs,
+%D author=Hans Hagen,
+%D date=\ currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{MetaPost Graphics / Blobs}
+
+\registerctxluafile{meta-blb}{}
+
+\unprotect
+
+\unexpanded\def\MPLIBgetblobscaledcm#1#2#3#4#5#6#7#8#9%
+ {\clf_mpgetblob\MPtextbox#1\relax
+ \setbox\MPbox\hpack\bgroup
+ \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}%
+ \vpack to \zeropoint\bgroup
+ \vss
+ \hpack to \zeropoint \bgroup
+ % \fastsxsy{#8}{#9}{\raise\dp\MPtextbox\box\MPtextbox}%
+ \fastsxsy{#8}{#9}{\box\MPtextbox}%
+ \hss
+ \egroup
+ \egroup
+ \egroup
+ \smashbox\MPbox
+ \box\MPbox}
+
+%D An example of usage:
+
+\definefontfeature[followtext][liga=no]
+
+\unexpanded\def\MPLIBfollowtext#1#2%
+ {\begingroup
+ \scratchcounter#1\relax
+ \setbox\scratchbox\hbox{\addff{followtext}#2}%
+ \clf_MPLIBconvertfollowtext\scratchcounter\scratchbox
+ \endgroup}
+
+% \def\reversedtext#1%
+% {\cldcontext{table.concat(table.reverse(utf.totable(\!!bs#1\!!es)))}}
+
+%D New:
+
+\newtoks\mpblobtext
+
+\mpblobtext{\global\setbox\mptextbox\vbox{\clf_mpblobtext}}
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-fnt.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-fnt.lua
index d061c926a57..69212d08c79 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-fnt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-fnt.lua
@@ -108,19 +108,17 @@ local function process(mpxformat,name,instances,scalefactor)
for i=1,instances do
characters = { }
descriptions = { }
- metapost.process(
- mpxformat,
- {
+ metapost.process {
+ mpx = mpxformat,
+ flusher = flusher,
+ askedfig = "all",
+ -- incontext = false,
+ data = {
formatters["randomseed := %s ;"](i*10),
formatters["charscale := %s ;"](scalefactor),
data,
},
- false,
- flusher,
- false,
- false,
- "all"
- )
+ }
lists[i] = {
characters = characters,
descriptions = descriptions,
@@ -191,9 +189,9 @@ statistics.register("metapost font generation", function()
if total > 0 then
local time = statistics.elapsedtime(flusher)
if total > 0 then
- return format("%i glyphs, %.3f seconds runtime, %.1f glyphs/second", total, time, total/time)
+ return format("%i glyphs, %s seconds runtime, %.1f glyphs/second", total, time, total/tonumber(time))
else
- return format("%i glyphs, %.3f seconds runtime", total, time)
+ return format("%i glyphs, %s seconds runtime", total, time)
end
end
end)
@@ -202,9 +200,9 @@ statistics.register("metapost font loading",function()
if variants > 0 then
local time = statistics.elapsedtime(metapost.fonts)
if variants > 0 then
- return format("%.3f seconds, %i instances, %.3f instances/second", time, variants, variants/time)
+ return format("%s seconds, %i instances, %.3f instances/second", time, variants, variants/tonumber(time))
else
- return format("%.3f seconds, %i instances", time, variants)
+ return format("%s seconds, %i instances", time, variants)
end
end
end)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-dum.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-dum.mkiv
index e6ccc234c6d..481afe82a54 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-dum.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-dum.mkiv
@@ -59,7 +59,7 @@
% clip currentpicture to p ;
% \stopuseMPgraphic
-\startuseMPgraphic{figure:placeholder}{width,height,reduction,color}
+\startuseMPgraphic{minifun::figure:placeholder}{width,height,reduction,color}
begingroup ;
save w, h, d, r, p, c, b ;
numeric w, h, d, r ; path p ;
@@ -88,7 +88,7 @@
\defineoverlay
[figure:placeholder:graphic]
[\useMPgraphic
- {figure:placeholder}%
+ {minifun::figure:placeholder}%
{width=\figurewidth,%
height=\figureheight,%
reduction=\externalfigureparameter\c!reduction,%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-mat.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-mat.mkiv
index 19a5ba38539..495864a9eeb 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-mat.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-mat.mkiv
@@ -15,8 +15,16 @@
%
% / for cambria
-\startMPextensions
+%D We need this for Alan, who nests math in \METAPOST:
+
+\unprotect
+
+\setupmathstackers
+ [\c!mp=minifun::math:stacker:\number\scratchunicode]
+\protect
+
+\startMPextensions
vardef math_stacker_bracket_shape(expr delta, rotate) =
image (
draw
@@ -129,55 +137,55 @@
enddef ;
\stopMPextensions
-\startuniqueMPgraphic{math:stacker:\number"FE3B4}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3B4}{axis,ex,em}
math_stacker_draw_accent(math_stacker_bracket_shape(OverlayHeight,false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE3B5}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3B5}{axis,ex,em}
math_stacker_draw_accent(math_stacker_bracket_shape(OverlayDepth,true)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE3DC}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DC}{axis,ex,em}
math_stacker_draw_accent(math_stacker_parent_shape(OverlayHeight,false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE3DD}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DD}{axis,ex,em}
math_stacker_draw_accent(math_stacker_parent_shape(OverlayDepth,true)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE3DE}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DE}{axis,ex,em}
math_stacker_draw_accent(math_stacker_brace_shape(OverlayHeight,false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE3DF}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DF}{axis,ex,em}
math_stacker_draw_accent(math_stacker_brace_shape(OverlayDepth,true)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE33E}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE33E}{axis,ex,em}
math_stacker_draw_accent(math_stacker_bar_shape(false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"FE33F}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"FE33F}{axis,ex,em}
math_stacker_draw_accent(math_stacker_bar_shape(true)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"2190}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"2190}{axis,ex,em}
math_stacker_draw_arrow(math_stacker_arrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"2192}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"2192}{axis,ex,em}
math_stacker_draw_arrow(math_stacker_arrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},true)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"2194}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"2194}{axis,ex,em}
math_stacker_draw_arrow(math_stacker_leftrightarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"27F7}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"27F7}{axis,ex,em}
math_stacker_draw_arrow(math_stacker_leftrightarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ;
\stopuniqueMPgraphic
-\startuniqueMPgraphic{math:stacker:\number"21C4}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:stacker:\number"21C4}{axis,ex,em}
math_stacker_draw_arrow(math_stacker_rightoverleftarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ;
\stopuniqueMPgraphic
@@ -193,7 +201,7 @@
enddef ;
\stopMPextensions
-\startuniqueMPgraphic{math:radical:default}{axis,ex,em}
+\startuniqueMPgraphic{minifun::math:radical:default}{axis,ex,em}
draw
math_radical_simple(OverlayWidth,OverlayHeight,OverlayDepth,OverlayOffset)
withpen pencircle xscaled (2OverlayLineWidth) yscaled (3OverlayLineWidth/4) rotated 30
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-txt.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-txt.mkiv
index e9660b3a7e2..d4329cd6ffd 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-imp-txt.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-imp-txt.mkiv
@@ -202,7 +202,10 @@
\stopMPdefinitions
\startluacode
+ local context = context
+
local nodecodes = nodes.nodecodes
+ local kerncodes = nodes.kerncodes
local visible_code = {
[nodecodes.glyph] = true,
@@ -212,72 +215,66 @@
[nodecodes.rule] = true,
}
- local disc_code = nodecodes.disc
- local kern_code = nodecodes.kern
-
- local c_userkern = nodes.kerncodes.userkern
+ local kern_code = nodecodes.kern
+ local c_userkern = kerncodes.userkern
local a_fontkern = attributes.private("fontkern")
+ local copynode = nodes.copy
+ local freenode = nodes.free
+
+ local topoints = number.topoints
+ local mpprint = mp.print
+
local n = nil
local s = 0
function mp.follow_reset()
- r = nil
+ for i=1,#n do
+ freenode(n[i])
+ end
+ n = nil
s = 0
end
function mp.follow_initialize(b)
- if not r then
- local l = tex.takebox(b).list
- n = { }
- s = 0
- while l do
- local c = l
- l = l.next
- local id = c.id
- if visible_code[id] then
- s = s + 1
- n[s] = c
- c.prev = nil
- c.next = nil
- elseif id == kern_code then
- if c.subtype == c_userkern and not c[a_fontkern] then
+ if not n then
+ local head = tex.takebox(b).list
+ if head then
+ n = { }
+ s = 0
+ head = node.flatten_discretionaries(head)
+ local current = head
+ while current do
+ local id = current.id
+ if visible_code[id] then
s = s + 1
- n[s] = c
- c.prev = nil
- else
- n[s].next = c
- c.prev = n[s]
- end
- c.next = nil
- elseif id == disc_code then
- local r = c.replace
- while r do
+ head, current, n[s] = nodes.remove(head,current)
+ elseif id == kern_code and current.subtype == c_userkern and not current[a_fontkern] then
s = s + 1
- n[s] = r
- r = r.next
- r.prev = nil
- r.next = nil
+ head, current, n[s] = nodes.remove(head,current)
+ else
+ current = current.next
end
end
+ nodes.flush_list(head)
end
end
end
function mp.follow_size()
- mp.print(s)
+ mpprint(s)
end
function mp.follow_slot(i)
- mp.print('textext("\\getfollowtoken{' .. i .. '}")')
+ mpprint('textext("\\getfollowtoken{' .. i .. '}")')
end
function mp.follow_text(s)
- context(n[s])
+ context(copynode(n[s]))
end
function mp.follow_width(i)
- mp.print(number.topoints(n[i].width))
+ mpprint(topoints(n[i].width))
end
\stopluacode
@@ -373,9 +370,8 @@
[medium]
\startuniqueMPgraphic{EnglishRule}{height,width,color}
- height = \MPvar{height} ;
x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ;
- y1 = y3 = 0 ; y2 = -y4 = height/2 ;
+ y1 = y3 = 0 ; y2 = -y4 = \MPvar{height}/2 ;
fill z1..z2..z3 & z3..z4..z1 & cycle withcolor \MPvar{color} ;
\stopuniqueMPgraphic
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-ini.lua
index 6c4768671f1..f320efe2046 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-ini.lua
@@ -117,23 +117,23 @@ do
local data = false
- function mp.start_saving_data(n)
+ function mp.mf_start_saving_data(n)
data = { }
end
- function mp.stop_saving_data()
+ function mp.mf_stop_saving_data()
if data then
-- nothing
end
end
- function mp.finish_saving_data()
+ function mp.mf_finish_saving_data()
if data then
-- nothing
end
end
- function mp.save_data(str)
+ function mp.mf_save_data(str)
if data then
data[#data+1] = str
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv
index 61e3523e667..89c7699deb5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv
@@ -97,7 +97,7 @@
\ifx\currentMPinstance\empty
\let\currentMPinstance\defaultMPinstance
\fi
- \global\t_meta_definitions\expandafter{\the\t_meta_definitions#2}%
+ \gtoksapp\t_meta_definitions{#2}%
\let\currentMPinstance\m_meta_saved_instance}
\let\stopMPdefinitions\relax
@@ -111,7 +111,7 @@
\let\stopMPextensions\relax
\unexpanded\def\startMPinitializations#1\stopMPinitializations % for all instances, when enabled
- {\global\t_meta_initializations\expandafter{\the\t_meta_initializations#1}}
+ {\gtoksapp\t_meta_initializations{#1}}
\let\stopMPinitializations\relax
@@ -131,7 +131,7 @@
\ifx\m_meta_option\!!plustoken \else
\global\t_meta_inclusions\emptytoks
\fi
- \global\t_meta_inclusions\expandafter{\the\t_meta_inclusions#2}%
+ \gtoksapp\t_meta_inclusions{#2}%
\let\currentMPinstance\m_meta_saved_instance}
\let\stopMPinclusions\relax
@@ -152,7 +152,7 @@
\ifx\m_meta_option\!!plustoken \else
\global\t_meta_inclusions\emptytoks
\fi
- \global\t_meta_inclusions\expandafter{\the\t_meta_inclusions#2}%
+ \gtoksapp\t_meta_inclusions{#2}%
\let\currentMPinstance\m_meta_saved_instance}
\installcommandhandler \??mpinstance {MPinstance} \??mpinstance
@@ -211,6 +211,7 @@
\def\currentMPformat {\currentMPinstance}
\defineMPinstance[metafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]
+\defineMPinstance[minifun] [\s!format=minifun,\s!extensions=\v!yes,\s!initializations=\v!yes]
\defineMPinstance[extrafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]
\defineMPinstance[lessfun] [\s!format=metafun]
\defineMPinstance[doublefun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
@@ -275,11 +276,13 @@
\endgroup}
\def\meta_process_graphic_start
- {\setbox\b_meta_graphic\hpack\bgroup}
+ {\pushMPboundingbox
+ \setbox\b_meta_graphic\hpack\bgroup}
\def\meta_process_graphic_stop
{\egroup
- \meta_place_graphic}
+ \meta_place_graphic
+ \popMPboundingbox}
\unexpanded\def\meta_process_graphic_instance#1%
{\edef\currentMPinstance{#1}%
@@ -365,12 +368,12 @@
\let\MPdrawingdata\empty
\unexpanded\def\resetMPdrawing
- {\global\let\MPdrawingdata\empty
+ {\glet\MPdrawingdata\empty
\global\MPdrawingdonefalse}
\unexpanded\def\pushMPdrawing
{\globalpushmacro\MPdrawingdata
- \global\let\MPdrawingdata\empty}
+ \glet\MPdrawingdata\empty}
\unexpanded\def\popMPdrawing
{\globalpopmacro\MPdrawingdata}
@@ -728,7 +731,7 @@
% \def\meta_start_use_graphic#1#2#3\stopuseMPgraphic
% %{\setgvalue{\??mpgraphic#1}{\meta_handle_use_graphic{#1}{#2}{#3}}}
% %{\setxvalue{\??mpgraphic#1}{\noexpand\meta_handle_use_graphic{#1}{\normalunexpanded{#2}}{\normalunexpanded{#3}}}}
-% {\global\expandafter\gdef\csname\??mpgraphic#1\expandafter\endcsname\expandafter{\expandafter\meta_handle_use_graphic\expandafter{\normalexpanded{#1}}{#2}{#3}}}
+% {\expandafter\gdef\csname\??mpgraphic#1\expandafter\endcsname\expandafter{\expandafter\meta_handle_use_graphic\expandafter{\normalexpanded{#1}}{#2}{#3}}}
%
% cleaner:
@@ -785,11 +788,28 @@
\unexpanded\def\useMPgraphic
{\dodoublegroupempty\meta_use_graphic}
+% \def\meta_use_graphic#1#2%
+% {\meta_begin_graphic_group{#1}%
+% %\doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}%
+% \doifsomething{#2}{\setupMPvariables[#1][#2]}%
+% \csname\??mpgraphic#1\endcsname\empty
+% \meta_end_graphic_group}
+
\def\meta_use_graphic#1#2%
{\meta_begin_graphic_group{#1}%
-% \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}%
- \doifsomething{#2}{\setupMPvariables[#1][#2]}%
- \csname\??mpgraphic#1\endcsname\empty
+ \ifcsname\??mpgraphic#1\endcsname
+ \edef\usedMPgraphicname{#1}%
+ \else\ifcsname\??mpgraphic\currentMPgraphicname\endcsname
+ \let\usedMPgraphicname\currentMPgraphicname
+ \else
+ \let\usedMPgraphicname\empty
+ \fi\fi
+ \ifx\usedMPgraphicname\empty
+ % message
+ \else
+ \doifsomething{#2}{\setupMPvariables[\usedMPgraphicname][#2]}%
+ \csname\??mpgraphic\usedMPgraphicname\endcsname
+ \fi
\meta_end_graphic_group}
\let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed
@@ -861,19 +881,6 @@
{\meta_prepare_instance_variable{#1}%
\edef\overlaystamp{\overlaystamp:\MPvariable{#1}}}
-%D \macros
-%D {MPdatafile}
-%D
-%D We redefine a macro from \type {supp-mps.tex}:
-
-% This will change ...
-
-\def\MPdataMPYfile{\jobname-mpgraph.mpy}
-
-\startMPextensions
- def data_mpy_file = "\noexpand\MPdataMPYfile" enddef ;
-\stopMPextensions
-
\unexpanded\def\getMPdata {\clf_getMPdata}
\let\rawMPdata \clf_getMPdata
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-nod.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-nod.lua
new file mode 100644
index 00000000000..422b4ee14d2
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-nod.lua
@@ -0,0 +1,81 @@
+if not modules then modules = { } end modules ['meta-nod'] = {
+ version = 1.001,
+ comment = "companion to meta-nod.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tonumber = tonumber
+local P, R, Cs, lpegmatch = lpeg.P, lpeg.R, lpeg.Cs, lpeg.match
+
+local references = { }
+local trace = false
+local report = logs.reporter("metapost","nodes")
+
+local context = context
+local implement = interfaces.implement
+
+trackers.register("metapost.nodes", function(v) trace = v end)
+
+local word = R("AZ","az","__")^1
+
+local pattern = Cs (
+ (
+ word / function(s) return references[s] or s end
+ + P("{") / "["
+ + P("}") / "]"
+ + P(1)
+ )^1
+)
+
+implement {
+ name = "grph_nodes_initialize",
+ actions = function()
+ references = { }
+ end
+}
+
+implement {
+ name = "grph_nodes_reset",
+ actions = function()
+ references = { }
+ end
+}
+
+implement {
+ name = "grph_nodes_register",
+ arguments = { "string", "integer" },
+ actions = function(s,r)
+ if not tonumber(s) then
+ if trace then
+ report("register %i as %a",t,s)
+ end
+ references[s] = r
+ end
+ end
+}
+
+implement {
+ name = "grph_nodes_resolve",
+ arguments = "string",
+ actions = function(s)
+ local r = references[s]
+ if r then
+ if trace then
+ report("resolve %a to %i",s,r)
+ end
+ context(r)
+ return
+ end
+ local n = lpegmatch(pattern,s)
+ if s ~= n then
+ if trace then
+ report("resolve '%s' to %s",s,n)
+ end
+ context(n)
+ return
+ end
+ context(s)
+ end
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-nod.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-nod.mkiv
index 5c7b3d503dd..9f966349c15 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-nod.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-nod.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\registerctxluafile{meta-nod}{}
+
\unprotect
\defineMPinstance
@@ -105,6 +107,11 @@
\let\stopnodes\relax
+%D Hm, we started out simple but it now quickly becomes the usual mess of
+%D \TEX, \METAPOST\ and \LUA. Hard to understand.
+
+\newcount\c_meta_nodes_n
+
\unexpanded\def\startnodes
{\dosingleempty\meta_nodes_start}
@@ -116,10 +123,12 @@
\edef\p_meta_option{\metanodesparameter\c!option}%
\edef\p_meta_alternative{\metanodesparameter\c!alternative}%
\the\t_every_meta_nodes
+ \c_meta_nodes_n\zerocount
\t_meta_nodes\emptytoks
#2\removeunwantedspaces
% for alan, will be commented:
\writestatus{metanodes}{\detokenize\expandafter{\the\t_meta_nodes}}%
+ \clf_grph_nodes_initialize
\startMPcode
mfun_node_init(%
\the\dimexpr\metanodesparameter\c!dx\relax,%
@@ -129,11 +138,9 @@
\the\t_meta_nodes ;
mfun_node_flush ;
\stopMPcode
+ \clf_grph_nodes_reset
\egroup}
-% \unexpanded\def\grph_nodes_node[#1,#2]#3%
-% {\etoksapp\t_meta_nodes{mfun_node_make(\number#1,\number#2,"\metanodesparameter\c!command{#3}");}}
-
\unexpanded\def\grph_nodes_node
{\dodoubleempty\grph_nodes_node_two}
@@ -146,13 +153,20 @@
\setupcurrentmetanodes[#3]%
\fi
\edef\p_label{#4}%
+ \edef\p_reference{\metanodesparameter\c!reference}%
+ \ifx\p_reference\empty\else
+ \clf_grph_nodes_register{\p_reference}\c_meta_nodes_n\relax
+ \fi
\normalexpanded{\endgroup\noexpand\etoksapp\t_meta_nodes{%
mfun_node_make(\number#1,\number#2%
- \ifx\p_label\empty \else
+ \ifx\p_label\empty
+ ,""%
+ \else
,"\metanodesparameter\c!command{\p_label}"%
\fi
);%
- }}}
+ }}%
+ \advance\c_meta_nodes_n\plusone}
\appendtoks
\let\placenode\grph_nodes_node
@@ -199,8 +213,11 @@
\space
mfun_nodes_fromto\begincsname\??metanodesposition\metanodesparameter\c!position\endcsname(%
\metanodesparameter\c!offset,%
- \number#1,\number#2%
- \ifx\p_label\empty \else
+ % \number#1,\number#2%
+ \clf_grph_nodes_resolve{#1},\clf_grph_nodes_resolve{#2}%
+ \ifx\p_label\empty
+ ,""%
+ \else
,"\ifx\p_command\empty\p_label\else\p_command{\p_label}\fi"%
\fi
)%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-pdf.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-pdf.lua
index 4a185cebd4d..5bcd161c02f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-pdf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-pdf.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['meta-pdf'] = {
license = "see context related readme files"
}
+-- This module is not used in practice but we keep it around for historic
+-- reasons.
+
-- Finally we used an optimized version. The test code can be found in
-- meta-pdh.lua but since we no longer want to overload functione we use
-- more locals now. This module keeps changing as it is also a testbed.
@@ -35,20 +38,24 @@ local pdfgraycode = lpdf.graycode
local pdfspotcode = lpdf.spotcode
local pdftransparencycode = lpdf.transparencycode
local pdffinishtransparencycode = lpdf.finishtransparencycode
------ pdfpageliteral = nodes.pool.pdfpageliteral
metapost.mptopdf = metapost.mptopdf or { }
local mptopdf = metapost.mptopdf
mptopdf.nofconverted = 0
-local f_translate = formatters["1 0 0 0 1 %F %F cm"] -- no %s due to 1e-035 issues
-local f_concat = formatters["%F %F %F %F %F %F cm"] -- no %s due to 1e-035 issues
+local f_translate = formatters["1 0 0 0 1 %.6F %.6F cm"]
+local f_concat = formatters["%.6F %.6F %.6F %.6F %.6F %.6F cm"]
+
+directives.register("pdf.stripzeros",function()
+ f_translate = formatters["1 0 0 0 1 %.6N %.6N cm"]
+ f_concat = formatters["%.6N %.6N %.6N %.6N %.6N %.6N cm"]
+end)
local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false
local m_stack_close, m_stack_path, m_stack_concat = false, { }, nil
-local extra_path_code, ignore_path = nil, false
+local extra_path_data, ignore_path = nil, false
local specials = { }
local function resetpath()
@@ -57,28 +64,21 @@ end
local function resetall()
m_path, m_stack, m_texts, m_version, m_shortcuts = { }, { }, { }, 0, false
- extra_path_code, ignore_path = nil, false
+ extra_path_data, ignore_path = nil, false
specials = { }
resetpath()
end
resetall()
--- -- this does not work as expected (displacement of text) beware, needs another
--- -- comment hack
---
--- local function pdfcode(str)
--- context(pdfpageliteral(str))
--- end
-
local pdfcode = context.pdfliteral
local function mpscode(str)
if ignore_path then
pdfcode("h W n")
- if extra_path_code then
- pdfcode(extra_path_code)
- extra_path_code = nil
+ if extra_path_data then
+ pdfcode(extra_path_data)
+ extra_path_data = nil
end
ignore_path = false
else
@@ -99,16 +99,28 @@ local function flushpath(cmd)
if #m_stack_path > 0 then
local path = { }
if m_stack_concat then
- local sx, sy = m_stack_concat[1], m_stack_concat[4]
- local rx, ry = m_stack_concat[2], m_stack_concat[3]
- local tx, ty = m_stack_concat[5], m_stack_concat[6]
+ local sx = m_stack_concat[1]
+ local sy = m_stack_concat[4]
+ local rx = m_stack_concat[2]
+ local ry = m_stack_concat[3]
+ local tx = m_stack_concat[5]
+ local ty = m_stack_concat[6]
local d = (sx*sy) - (rx*ry)
for k=1,#m_stack_path do
- local v = m_stack_path[k]
- local px, py = v[1], v[2] ; v[1], v[2] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[1],v[2])
+ local v = m_stack_path[k]
+ local px = v[1]
+ local py = v[2]
+ v[1] = (sy*(px-tx)-ry*(py-ty))/d
+ v[2] = (sx*(py-ty)-rx*(px-tx))/d
if #v == 7 then
- local px, py = v[3], v[4] ; v[3], v[4] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[3],v[4])
- local px, py = v[5], v[6] ; v[5], v[6] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[5],v[6])
+ px = v[3]
+ py = v[4]
+ v[3] = (sy*(px-tx)-ry*(py-ty))/d
+ v[4] = (sx*(py-ty)-rx*(px-tx))/d
+ px = v[5]
+ py = v[6]
+ v[5] = (sy*(px-tx)-ry*(py-ty))/d
+ v[6] = (sx*(py-ty)-rx*(px-tx))/d
end
path[k] = concat(v," ")
end
@@ -161,7 +173,8 @@ function mps.lineto(x,y)
end
function mps.rlineto(x,y)
- local dx, dy = 0, 0
+ local dx = 0
+ local dy = 0
local topofstack = #m_stack_path
if topofstack > 0 then
local msp = m_stack_path[topofstack]
@@ -238,7 +251,8 @@ function mps.clip()
end
function mps.textext(font, scale, str) -- old parser
- local dx, dy = 0, 0
+ local dx = 0
+ local dy = 0
if #m_stack_path > 0 then
dx, dy = m_stack_path[1][1], m_stack_path[1][2]
end
@@ -279,7 +293,7 @@ local function linearshade(colorspace,domain,ca,cb,coordinates)
nofshades = nofshades + 1
local name = formatters["MpsSh%s"](nofshades)
lpdf.linearshade(name,domain,ca,cb,1,colorspace,coordinates)
- extra_path_code, ignore_path = formatters["/%s sh Q"](name), true
+ extra_path_data, ignore_path = formatters["/%s sh Q"](name), true
pdfcode("q /Pattern cs")
end
@@ -288,7 +302,7 @@ local function circularshade(colorspace,domain,ca,cb,coordinates)
nofshades = nofshades + 1
local name = formatters["MpsSh%s"](nofshades)
lpdf.circularshade(name,domain,ca,cb,1,colorspace,coordinates)
- extra_path_code, ignore_path = formatters["/%s sh Q"](name), true
+ extra_path_data, ignore_path = formatters["/%s sh Q"](name), true
pdfcode("q /Pattern cs")
end
@@ -333,9 +347,12 @@ handlers[50] = function() report_mptopdf("skipping special %s",50) end
--end of not supported
function mps.setrgbcolor(r,g,b) -- extra check
- r, g, b = tonumber(r), tonumber(g), tonumber(b) -- needed when we use lpeg
+ r = tonumber(r) -- needed when we use lpeg
+ g = tonumber(g) -- needed when we use lpeg
+ b = tonumber(b) -- needed when we use lpeg
if r == 0.0123 and g < 0.1 then
- g, b = round(g*10000), round(b*10000)
+ g = round(g*10000)
+ b = round(b*10000)
local s = specials[b]
local h = round(s[#s])
local handler = handlers[h]
@@ -345,7 +362,8 @@ function mps.setrgbcolor(r,g,b) -- extra check
report_mptopdf("unknown special handler %s (1)",h)
end
elseif r == 0.123 and g < 0.1 then
- g, b = round(g*1000), round(b*1000)
+ g = round(g*1000)
+ b = round(b*1000)
local s = specials[b]
local h = round(s[#s])
local handler = handlers[h]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-pdh.mkiv b/Master/texmf-dist/tex/context/base/mkiv/meta-pdh.mkiv
index f9eff73caaa..e4ac92fb404 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-pdh.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-pdh.mkiv
@@ -92,15 +92,15 @@
{\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi}
\def\resetMPvariables#1#2#3%
- {\global\let\MPwidth \!!zeropoint
- \global\let\MPheight\!!zeropoint
- \global\let\MPllx \!!zerocount
- \global\let\MPlly \!!zerocount
- \global\let\MPurx \!!zerocount
- \global\let\MPury \!!zerocount
- \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi
- \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi
- \xdef\MPfilename {#1}}
+ {\glet\MPwidth \!!zeropoint
+ \glet\MPheight \!!zeropoint
+ \glet\MPllx \!!zerocount
+ \glet\MPlly \!!zerocount
+ \glet\MPurx \!!zerocount
+ \glet\MPury \!!zerocount
+ \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi
+ \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi
+ \xdef\MPfilename {#1}}
%D The main macro:
@@ -164,7 +164,7 @@
\else
\getMPPDFobject
\fi
- \global\let\currentPDFresources\empty
+ \glet\currentPDFresources\empty
\else
\box#1%
\fi}
@@ -250,12 +250,12 @@
%D Some day we may consider collecting local resources.
\appendtoks
- \global\let\currentPDFresources\empty % kind of redundant
+ \glet\currentPDFresources\empty % kind of redundant
\to \MPstartresources
% \appendtoks
% \collectPDFresources
-% \global\let\currentPDFresources\collectedPDFresources
+% \glet\currentPDFresources\collectedPDFresources
% \to \MPstopresources
\appendtoksonce
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-tex.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-tex.lua
index fdf11842428..c2f72bcf3c7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/meta-tex.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/meta-tex.lua
@@ -126,11 +126,7 @@ do
arguments = "2 strings",
}
- if LUAVERSION < 5.2 then
- utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp")
- else
- utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp })
- end
+ utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp })
local f_textext = formatters[ [[textext("%s")]] ]
local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/metatex.tex b/Master/texmf-dist/tex/context/base/mkiv/metatex.tex
deleted file mode 100644
index 7c8a7ff0104..00000000000
--- a/Master/texmf-dist/tex/context/base/mkiv/metatex.tex
+++ /dev/null
@@ -1,30 +0,0 @@
-%D \module
-%D [ file=metatex,
-%D version=2008.10.10,
-%D title=\METATEX,
-%D subtitle=\METATEX\ Format Generation,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-%D We can experiment here with runtime loading, i.e. no longer
-%D use a format. However, we still need a stub then but it could
-%D as well be luatools (mtxrun) itself then.
-
-%D This format is just a minimal layer on top of the \LUATEX\
-%D engine and will not provide high level functionality. It can
-%D be used as basis for dedicated (specialized) macro packages.
-%D
-%D A format is generated with the command;
-%D
-%D \starttyping
-%D mtxrun --script metatex --make
-%D \stoptyping
-%D
-%D For the moment this is a placeholder. Maybe some day ... the old
-%D file history/metatex/metatex.tex so I can pick up from there if
-%D needed.
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-ctx.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-ctx.lua
index c568b92a3f1..89f2fa0eeb1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-ctx.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-ctx.lua
@@ -11,46 +11,29 @@ local format, concat = string.format, table.concat
local settings_to_hash = utilities.parsers.settings_to_hash
local formatters = string.formatters
-local report_metapost = logs.reporter("metapost")
+local report_metapost = logs.reporter ("metapost")
+local status_metapost = logs.messenger("metapost")
-local starttiming = statistics.starttiming
-local stoptiming = statistics.stoptiming
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
-local mplib = mplib
+local trace_graphic = false
-metapost = metapost or { }
-local metapost = metapost
-local context = context
+trackers.register("metapost.graphics",
+ function(v) trace_graphic = v end
+);
-local setters = tokens.setters
-local setmacro = setters.macro
-local implement = interfaces.implement
+local mplib = mplib
-local v_no = interfaces.variables.no
+metapost = metapost or { }
+local metapost = metapost
+local context = context
-metapost.defaultformat = "metafun"
-metapost.defaultinstance = "metafun"
-metapost.defaultmethod = "default"
+local setters = tokens.setters
+local setmacro = setters.macro
+local implement = interfaces.implement
-local function setmpsformat(specification)
- local instance = specification.instance
- local format = specification.format
- local method = specification.method
- if not instance or instance == "" then
- instance = metapost.defaultinstance
- specification.instance = instance
- end
- if not format or format == "" then
- format = metapost.defaultformat
- specification.format = format
- end
- if not method or method == "" then
- method = metapost.defaultmethod
- specification.method = method
- end
- specification.mpx = metapost.format(instance,format,method)
- return specification
-end
+local v_no = interfaces.variables.no
local extensiondata = metapost.extensiondata or storage.allocate { }
metapost.extensiondata = extensiondata
@@ -96,9 +79,6 @@ implement {
arguments = "string"
}
-local report_metapost = logs.reporter ("metapost")
-local status_metapost = logs.messenger("metapost")
-
local patterns = {
"meta-imp-%s.mkiv",
"meta-imp-%s.tex",
@@ -192,7 +172,9 @@ implement {
-- or just move the scanners to pps
function metapost.graphic(specification)
- metapost.graphic_base_pass(setmpsformat(specification))
+ metapost.pushformat(specification)
+ metapost.graphic_base_pass(specification)
+ metapost.popformat()
end
function metapost.startgraphic(t)
@@ -208,9 +190,6 @@ function metapost.startgraphic(t)
if not t.method then
t.method = metapost.defaultmethod
end
- if not t.definitions then
- t.definitions = ""
- end
t.data = { }
return t
end
@@ -218,8 +197,10 @@ end
function metapost.stopgraphic(t)
if t then
t.data = concat(t.data or { },"\n")
+ if trace_graphic then
+ report_metapost("\n"..t.data.."\n")
+ end
metapost.graphic(t)
- t.data = ""
end
end
@@ -265,8 +246,7 @@ implement {
}
function metapost.getclippath(specification) -- why not a special instance for this
- setmpsformat(specification)
- local mpx = specification.mpx
+ local mpx = metapost.pushformat(specification)
local data = specification.data or ""
if mpx and data ~= "" then
starttiming(metapost)
@@ -285,7 +265,10 @@ function metapost.getclippath(specification) -- why not a special instance for t
result = metapost.filterclippath(result)
end
stoptiming(metapost)
+ metapost.pushformat()
return result
+ else
+ metapost.pushformat()
end
end
@@ -337,23 +320,17 @@ implement {
}
}
-statistics.register("metapost processing time", function()
+statistics.register("metapost", function()
local n = metapost.n
if n and n > 0 then
- local nofconverted = metapost.makempy.nofconverted
local elapsedtime = statistics.elapsedtime
- local elapsed = statistics.elapsed
- local instances, memory = metapost.getstatistics(true)
- local str = format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, memory: %0.3f M",
+ local elapsed = statistics.elapsed
+ local instances,
+ memory = metapost.getstatistics(true)
+ return format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, luacalls: %i, memory: %0.3f M",
elapsedtime(metapost), elapsedtime(mplib), elapsedtime(metapost.exectime), n,
elapsedtime((elapsed(metapost) + elapsed(mplib) + elapsed(metapost.exectime)) / n),
- instances, memory/(1024*1024))
- if nofconverted > 0 then
- return format("%s, external: %s (%s calls)",
- str, elapsedtime(metapost.makempy), nofconverted)
- else
- return str
- end
+ instances, metapost.nofscriptruns(),memory/(1024*1024))
else
return nil
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-int.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-int.lua
index bd3ba213f86..63e7278dae7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-int.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-int.lua
@@ -7,11 +7,14 @@ if not modules then modules = { } end modules ['mlib-int'] = {
}
local factor = number.dimenfactors.bp
-local mpprint = mp.print
------ mpboolean = mp.boolean
------ mpquoted = mp.quoted
+----- mpprint = mp.print
+local mpnumeric = mp.numeric
+local mpboolean = mp.boolean
+local mpstring = mp.string
+local mpquoted = mp.quoted
local getdimen = tex.getdimen
local getcount = tex.getcount
+local getmacro = tokens.getters.macro
local get = tex.get
local mpcolor = attributes.colors.mpcolor
local emwidths = fonts.hashes.emwidths
@@ -19,90 +22,90 @@ local exheights = fonts.hashes.exheights
local mpgetdimen = mp.getdimen
-function mp.PaperHeight () mpprint(getdimen("paperheight") *factor) end
-function mp.PaperWidth () mpprint(getdimen("paperwidth") *factor) end
-function mp.PrintPaperHeight () mpprint(getdimen("printpaperheight") *factor) end
-function mp.PrintPaperWidth () mpprint(getdimen("printpaperwidth") *factor) end
-function mp.TopSpace () mpprint(getdimen("topspace") *factor) end
-function mp.BottomSpace () mpprint(getdimen("bottomspace") *factor) end
-function mp.BackSpace () mpprint(getdimen("backspace") *factor) end
-function mp.CutSpace () mpprint(getdimen("cutspace") *factor) end
-function mp.MakeupHeight () mpprint(getdimen("makeupheight") *factor) end
-function mp.MakeupWidth () mpprint(getdimen("makeupwidth") *factor) end
-function mp.TopHeight () mpprint(getdimen("topheight") *factor) end
-function mp.TopDistance () mpprint(getdimen("topdistance") *factor) end
-function mp.HeaderHeight () mpprint(getdimen("headerheight") *factor) end
-function mp.HeaderDistance () mpprint(getdimen("headerdistance") *factor) end
-function mp.TextHeight () mpprint(getdimen("textheight") *factor) end
-function mp.FooterDistance () mpprint(getdimen("footerdistance") *factor) end
-function mp.FooterHeight () mpprint(getdimen("footerheight") *factor) end
-function mp.BottomDistance () mpprint(getdimen("bottomdistance") *factor) end
-function mp.BottomHeight () mpprint(getdimen("bottomheight") *factor) end
-function mp.LeftEdgeWidth () mpprint(getdimen("leftedgewidth") *factor) end
-function mp.LeftEdgeDistance () mpprint(getdimen("leftedgedistance") *factor) end
-function mp.LeftMarginWidth () mpprint(getdimen("leftmarginwidth") *factor) end
-function mp.LeftMarginDistance () mpprint(getdimen("leftmargindistance") *factor) end
-function mp.TextWidth () mpprint(getdimen("textwidth") *factor) end
-function mp.RightMarginDistance () mpprint(getdimen("rightmargindistance") *factor) end
-function mp.RightMarginWidth () mpprint(getdimen("rightmarginwidth") *factor) end
-function mp.RightEdgeDistance () mpprint(getdimen("rightedgedistance") *factor) end
-function mp.RightEdgeWidth () mpprint(getdimen("rightedgewidth") *factor) end
-function mp.InnerMarginDistance () mpprint(getdimen("innermargindistance") *factor) end
-function mp.InnerMarginWidth () mpprint(getdimen("innermarginwidth") *factor) end
-function mp.OuterMarginDistance () mpprint(getdimen("outermargindistance") *factor) end
-function mp.OuterMarginWidth () mpprint(getdimen("outermarginwidth") *factor) end
-function mp.InnerEdgeDistance () mpprint(getdimen("inneredgedistance") *factor) end
-function mp.InnerEdgeWidth () mpprint(getdimen("inneredgewidth") *factor) end
-function mp.OuterEdgeDistance () mpprint(getdimen("outeredgedistance") *factor) end
-function mp.OuterEdgeWidth () mpprint(getdimen("outeredgewidth") *factor) end
-function mp.PageOffset () mpprint(getdimen("pagebackgroundoffset")*factor) end
-function mp.PageDepth () mpprint(getdimen("pagebackgrounddepth") *factor) end
-function mp.LayoutColumns () mpprint(getcount("layoutcolumns")) end
-function mp.LayoutColumnDistance() mpprint(getdimen("layoutcolumndistance")*factor) end
-function mp.LayoutColumnWidth () mpprint(getdimen("layoutcolumnwidth") *factor) end
-function mp.SpineWidth () mpprint(getdimen("spinewidth") *factor) end
-function mp.PaperBleed () mpprint(getdimen("paperbleed") *factor) end
-
-function mp.RealPageNumber () mpprint(getcount("realpageno")) end
-function mp.LastPageNumber () mpprint(getcount("lastpageno")) end
-
-function mp.PageNumber () mpprint(getcount("pageno")) end
-function mp.NOfPages () mpprint(getcount("lastpageno")) end
-
-function mp.SubPageNumber () mpprint(getcount("subpageno")) end
-function mp.NOfSubPages () mpprint(getcount("lastsubpageno")) end
-
-function mp.CurrentColumn () mpprint(getcount("mofcolumns")) end
-function mp.NOfColumns () mpprint(getcount("nofcolumns")) end
-
-function mp.BaseLineSkip () mpprint(get ("baselineskip",true) *factor) end
-function mp.LineHeight () mpprint(getdimen("lineheight") *factor) end
-function mp.BodyFontSize () mpprint(getdimen("bodyfontsize") *factor) end
-
-function mp.TopSkip () mpprint(get ("topskip",true) *factor) end
-function mp.StrutHeight () mpprint(getdimen("strutht") *factor) end
-function mp.StrutDepth () mpprint(getdimen("strutdp") *factor) end
-
-function mp.PageNumber () mpprint(getcount("pageno")) end
-function mp.RealPageNumber () mpprint(getcount("realpageno")) end
-function mp.NOfPages () mpprint(getcount("lastpageno")) end
-
-function mp.CurrentWidth () mpprint(get ("hsize") *factor) end
-function mp.CurrentHeight () mpprint(get ("vsize") *factor) end
-
-function mp.EmWidth () mpprint(emwidths [false]*factor) end
-function mp.ExHeight () mpprint(exheights[false]*factor) end
+function mp.PaperHeight () mpnumeric(getdimen("paperheight") *factor) end
+function mp.PaperWidth () mpnumeric(getdimen("paperwidth") *factor) end
+function mp.PrintPaperHeight () mpnumeric(getdimen("printpaperheight") *factor) end
+function mp.PrintPaperWidth () mpnumeric(getdimen("printpaperwidth") *factor) end
+function mp.TopSpace () mpnumeric(getdimen("topspace") *factor) end
+function mp.BottomSpace () mpnumeric(getdimen("bottomspace") *factor) end
+function mp.BackSpace () mpnumeric(getdimen("backspace") *factor) end
+function mp.CutSpace () mpnumeric(getdimen("cutspace") *factor) end
+function mp.MakeupHeight () mpnumeric(getdimen("makeupheight") *factor) end
+function mp.MakeupWidth () mpnumeric(getdimen("makeupwidth") *factor) end
+function mp.TopHeight () mpnumeric(getdimen("topheight") *factor) end
+function mp.TopDistance () mpnumeric(getdimen("topdistance") *factor) end
+function mp.HeaderHeight () mpnumeric(getdimen("headerheight") *factor) end
+function mp.HeaderDistance () mpnumeric(getdimen("headerdistance") *factor) end
+function mp.TextHeight () mpnumeric(getdimen("textheight") *factor) end
+function mp.FooterDistance () mpnumeric(getdimen("footerdistance") *factor) end
+function mp.FooterHeight () mpnumeric(getdimen("footerheight") *factor) end
+function mp.BottomDistance () mpnumeric(getdimen("bottomdistance") *factor) end
+function mp.BottomHeight () mpnumeric(getdimen("bottomheight") *factor) end
+function mp.LeftEdgeWidth () mpnumeric(getdimen("leftedgewidth") *factor) end
+function mp.LeftEdgeDistance () mpnumeric(getdimen("leftedgedistance") *factor) end
+function mp.LeftMarginWidth () mpnumeric(getdimen("leftmarginwidth") *factor) end
+function mp.LeftMarginDistance () mpnumeric(getdimen("leftmargindistance") *factor) end
+function mp.TextWidth () mpnumeric(getdimen("textwidth") *factor) end
+function mp.RightMarginDistance () mpnumeric(getdimen("rightmargindistance") *factor) end
+function mp.RightMarginWidth () mpnumeric(getdimen("rightmarginwidth") *factor) end
+function mp.RightEdgeDistance () mpnumeric(getdimen("rightedgedistance") *factor) end
+function mp.RightEdgeWidth () mpnumeric(getdimen("rightedgewidth") *factor) end
+function mp.InnerMarginDistance () mpnumeric(getdimen("innermargindistance") *factor) end
+function mp.InnerMarginWidth () mpnumeric(getdimen("innermarginwidth") *factor) end
+function mp.OuterMarginDistance () mpnumeric(getdimen("outermargindistance") *factor) end
+function mp.OuterMarginWidth () mpnumeric(getdimen("outermarginwidth") *factor) end
+function mp.InnerEdgeDistance () mpnumeric(getdimen("inneredgedistance") *factor) end
+function mp.InnerEdgeWidth () mpnumeric(getdimen("inneredgewidth") *factor) end
+function mp.OuterEdgeDistance () mpnumeric(getdimen("outeredgedistance") *factor) end
+function mp.OuterEdgeWidth () mpnumeric(getdimen("outeredgewidth") *factor) end
+function mp.PageOffset () mpnumeric(getdimen("pagebackgroundoffset")*factor) end
+function mp.PageDepth () mpnumeric(getdimen("pagebackgrounddepth") *factor) end
+function mp.LayoutColumns () mpnumeric(getcount("layoutcolumns")) end
+function mp.LayoutColumnDistance() mpnumeric(getdimen("layoutcolumndistance")*factor) end
+function mp.LayoutColumnWidth () mpnumeric(getdimen("layoutcolumnwidth") *factor) end
+function mp.SpineWidth () mpnumeric(getdimen("spinewidth") *factor) end
+function mp.PaperBleed () mpnumeric(getdimen("paperbleed") *factor) end
+
+function mp.RealPageNumber () mpnumeric(getcount("realpageno")) end
+function mp.LastPageNumber () mpnumeric(getcount("lastpageno")) end
+
+function mp.PageNumber () mpnumeric(getcount("pageno")) end
+function mp.NOfPages () mpnumeric(getcount("lastpageno")) end
+
+function mp.SubPageNumber () mpnumeric(getcount("subpageno")) end
+function mp.NOfSubPages () mpnumeric(getcount("lastsubpageno")) end
+
+function mp.CurrentColumn () mpnumeric(getcount("mofcolumns")) end
+function mp.NOfColumns () mpnumeric(getcount("nofcolumns")) end
+
+function mp.BaseLineSkip () mpnumeric(get ("baselineskip",true) *factor) end
+function mp.LineHeight () mpnumeric(getdimen("lineheight") *factor) end
+function mp.BodyFontSize () mpnumeric(getdimen("bodyfontsize") *factor) end
+
+function mp.TopSkip () mpnumeric(get ("topskip",true) *factor) end
+function mp.StrutHeight () mpnumeric(getdimen("strutht") *factor) end
+function mp.StrutDepth () mpnumeric(getdimen("strutdp") *factor) end
+
+function mp.PageNumber () mpnumeric(getcount("pageno")) end
+function mp.RealPageNumber () mpnumeric(getcount("realpageno")) end
+function mp.NOfPages () mpnumeric(getcount("lastpageno")) end
+
+function mp.CurrentWidth () mpnumeric(get ("hsize") *factor) end
+function mp.CurrentHeight () mpnumeric(get ("vsize") *factor) end
+
+function mp.EmWidth () mpnumeric(emwidths [false]*factor) end
+function mp.ExHeight () mpnumeric(exheights[false]*factor) end
mp.HSize = mp.CurrentWidth
mp.VSize = mp.CurrentHeight
mp.LastPageNumber = mp.NOfPages
-function mp.PageFraction ()
+function mp.PageFraction()
local lastpage = getcount("lastpageno")
if lastpage > 1 then
- mpprint((getcount("realpageno")-1)/(lastpage-1))
+ mpnumeric((getcount("realpageno")-1)/(lastpage-1))
else
- mpprint(1)
+ mpnumeric(1)
end
end
@@ -112,30 +115,22 @@ local on_right = structures.pages.on_right
local is_odd = structures.pages.is_odd
local in_body = structures.pages.in_body
-mp.OnRightPage = function() mpprint(on_right()) end -- needs checking
-mp.OnOddPage = function() mpprint(is_odd ()) end -- needs checking
-mp.InPageBody = function() mpprint(in_body ()) end -- needs checking
+mp.OnRightPage = function() mpboolean(on_right()) end -- needs checking
+mp.OnOddPage = function() mpboolean(is_odd ()) end -- needs checking
+mp.InPageBody = function() mpboolean(in_body ()) end -- needs checking
-- mp.CurrentLayout : \currentlayout
-function mp.OverlayWidth () mpprint(getdimen("d_overlay_width") *factor) end
-function mp.OverlayHeight () mpprint(getdimen("d_overlay_height") *factor) end
-function mp.OverlayDepth () mpprint(getdimen("d_overlay_depth") *factor) end
-function mp.OverlayLineWidth () mpprint(getdimen("d_overlay_linewidth")*factor) end
-function mp.OverlayOffset () mpprint(getdimen("d_overlay_offset") *factor) end
+function mp.OverlayWidth () mpnumeric(getdimen("d_overlay_width") * factor) end
+function mp.OverlayHeight () mpnumeric(getdimen("d_overlay_height") * factor) end
+function mp.OverlayDepth () mpnumeric(getdimen("d_overlay_depth") * factor) end
+function mp.OverlayLineWidth() mpnumeric(getdimen("d_overlay_linewidth") * factor) end
+function mp.OverlayOffset () mpnumeric(getdimen("d_overlay_offset") * factor) end
+function mp.OverlayRegion () mpstring(getmacro("m_overlay_region")) end
-function mp.defaultcolormodel()
+function mp.mf_default_color_model()
local colormethod = getcount("MPcolormethod")
- -- if colormethod == 0 then
- -- return 1
- -- elseif colormethod == 1 then
- -- return 1
- -- elseif colormethod == 2 then
- -- return 3
- -- else
- -- return 3
- -- end
- return (colormethod == 0 or colormethod == 1) and 1 or 3
+ return mpnumeric((colormethod == 0 or colormethod == 1) and 1 or 3)
end
-- not much difference (10000 calls in a graphic neither as expansion seems to win
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
index 19e731b8569..d7c2a0fc3f2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
@@ -10,11 +10,11 @@ if not modules then modules = { } end modules ['mlib-lua'] = {
-- maybe we need mplib.model, but how with instances
-local type, tostring, select, loadstring = type, tostring, select, loadstring
+local type, tostring, tonumber, select, loadstring = type, tostring, tonumber, select, loadstring
local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch
+local concat, insert, remove = table.concat, table.insert, table.remove
local formatters = string.formatters
-local concat = table.concat
local lpegmatch = lpeg.match
local lpegpatterns = lpeg.patterns
@@ -26,105 +26,18 @@ local report_message = logs.reporter("metapost")
local trace_luarun = false trackers.register("metapost.lua",function(v) trace_luarun = v end)
local trace_enabled = true
-local be_tolerant = true directives.register("metapost.lua.tolerant",function(v) be_tolerant = v end)
+local be_tolerant = true directives.register("metapost.lua.tolerant", function(v) be_tolerant = v end)
-mp = mp or { } -- system namespace
-MP = MP or { } -- user namespace
+local get, set, aux = { }, { }, { }
-local buffer, n, max = { }, 0, 10 -- we reuse upto max
-
-function mp._f_()
- if trace_enabled and trace_luarun then
- local result = concat(buffer," ",1,n)
- if n > max then
- buffer = { }
- end
- n = 0
- report_luarun("data: %s",result)
- return result
- else
- if n == 0 then
- return ""
- end
- local result
- if n == 1 then
- result = buffer[1]
- else
- result = concat(buffer," ",1,n)
- end
- if n > max then
- buffer = { }
- end
- n = 0
- return result
- end
-end
-
-local f_code = formatters["%s return mp._f_()"]
-
-local f_numeric = formatters["%.16f"]
-local f_integer = formatters["%i"]
-local f_pair = formatters["(%.16f,%.16f)"]
-local f_triplet = formatters["(%.16f,%.16f,%.16f)"]
-local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"]
-
-local function mpprint(...) -- we can optimize for n=1
- for i=1,select("#",...) do
- local value = select(i,...)
- if value ~= nil then
- n = n + 1
- local t = type(value)
- if t == "number" then
- buffer[n] = f_numeric(value)
- elseif t == "string" then
- buffer[n] = value
- elseif t == "table" then
- buffer[n] = "(" .. concat(value,",") .. ")"
- else -- boolean or whatever
- buffer[n] = tostring(value)
- end
- end
- end
-end
-
-local r = P('%') / "percent"
- + P('"') / "dquote"
- + P('\n') / "crlf"
- -- + P(' ') / "space"
-local a = Cc("&")
-local q = Cc('"')
-local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q)
-
-local function mpvprint(...) -- variable print
- for i=1,select("#",...) do
- local value = select(i,...)
- if value ~= nil then
- n = n + 1
- local t = type(value)
- if t == "number" then
- buffer[n] = f_numeric(value)
- elseif t == "string" then
- buffer[n] = lpegmatch(p,value)
- elseif t == "table" then
- local m = #t
- if m == 2 then
- buffer[n] = f_pair(unpack(t))
- elseif m == 3 then
- buffer[n] = f_triplet(unpack(t))
- elseif m == 4 then
- buffer[n] = f_quadruple(unpack(t))
- else -- error
- buffer[n] = ""
- end
- else -- boolean or whatever
- buffer[n] = tostring(value)
- end
- end
- end
-end
+mp = mp or { -- system namespace
+ set = set,
+ get = get,
+ aux = aux,
+}
-mp.print = mpprint
-mp.vprint = mpvprint
+MP = MP or { -- user namespace
+}
-- We had this:
--
@@ -139,150 +52,540 @@ mp.vprint = mpvprint
-- lua.mp("somedefdname","foo")
table.setmetatablecall(mp,function(t,k,...) return t[k](...) end)
+table.setmetatablecall(MP,function(t,k,...) return t[k](...) end)
-function mp.boolean(b)
- n = n + 1
- buffer[n] = b and "true" or "false"
-end
+do
-function mp.numeric(f)
- n = n + 1
- buffer[n] = f and f_numeric(f) or "0"
-end
+ local currentmpx = nil
+ local stack = { }
-function mp.integer(i)
- n = n + 1
- -- buffer[n] = i and f_integer(i) or "0"
- buffer[n] = i or "0"
-end
+ local get_numeric = mplib.get_numeric
+ local get_string = mplib.get_string
+ local get_boolean = mplib.get_boolean
+ local get_path = mplib.get_path
+ local set_path = mplib.set_path
+
+ get.numeric = function(s) return get_numeric(currentmpx,s) end
+ get.string = function(s) return get_string (currentmpx,s) end
+ get.boolean = function(s) return get_boolean(currentmpx,s) end
+ get.path = function(s) return get_path (currentmpx,s) end
+ get.number = function(s) return get_numeric(currentmpx,s) end
-function mp.pair(x,y)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_pair(x[1],x[2])
- else
- buffer[n] = f_pair(x,y)
+ set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet
+
+ function metapost.pushscriptrunner(mpx)
+ insert(stack,mpx)
+ currentmpx = mpx
end
-end
-function mp.triplet(x,y,z)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_triplet(x[1],x[2],x[3])
- else
- buffer[n] = f_triplet(x,y,z)
+ function metapost.popscriptrunner()
+ currentmpx = remove(stack,mpx)
end
+
end
-function mp.quadruple(w,x,y,z)
- n = n + 1
- if type(w) == "table" then
- buffer[n] = f_quadruple(w[1],w[2],w[3],w[4])
- else
- buffer[n] = f_quadruple(w,x,y,z)
+do
+
+ local buffer = { }
+ local n = 0
+ local max = 20 -- we reuse upto max
+ local nesting = 0
+ local runs = 0
+
+ local function _f_()
+ if trace_enabled and trace_luarun then
+ local result = concat(buffer," ",1,n)
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ report_luarun("%i: data: %s",nesting,result)
+ return result
+ else
+ if n == 0 then
+ return ""
+ end
+ local result
+ if n == 1 then
+ result = buffer[1]
+ else
+ result = concat(buffer," ",1,n)
+ end
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ return result
+ end
+ end
+
+ mp._f_ = _f_ -- convenient to have it in a top module
+ aux.flush = _f_
+
+ ----- f_code = formatters["%s return mp._f_()"]
+
+ local f_integer = formatters["%i"]
+
+ local f_numeric = formatters["%n"] -- maybe %N
+ local f_pair = formatters["(%n,%n)"]
+ local f_ctrl = formatters["(%n,%n) .. controls (%n,%n) and (%n,%n)"]
+ local f_triplet = formatters["(%n,%n,%n)"]
+ local f_quadruple = formatters["(%n,%n,%n,%n)"]
+
+ local f_points = formatters["%p"]
+ local f_pair_pt = formatters["(%p,%p)"]
+ local f_ctrl_pt = formatters["(%p,%p) .. controls (%p,%p) and (%p,%p)"]
+ local f_triplet_pt = formatters["(%p,%p,%p)"]
+ local f_quadruple_pt = formatters["(%p,%p,%p,%p)"]
+
+ local r = P('%') / "percent"
+ + P('"') / "dquote"
+ + P('\n') / "crlf"
+ -- + P(' ') / "space"
+ local a = Cc("&")
+ local q = Cc('"')
+ local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q)
+
+ mp.cleaned = function(s) return lpegmatch(p,s) or s end
+
+ -- local function mpprint(...) -- we can optimize for n=1
+ -- for i=1,select("#",...) do
+ -- local value = (select(i,...))
+ -- if value ~= nil then
+ -- n = n + 1
+ -- local t = type(value)
+ -- if t == "number" then
+ -- buffer[n] = f_numeric(value)
+ -- elseif t == "string" then
+ -- buffer[n] = value
+ -- elseif t == "table" then
+ -- buffer[n] = "(" .. concat(value,",") .. ")"
+ -- else -- boolean or whatever
+ -- buffer[n] = tostring(value)
+ -- end
+ -- end
+ -- end
+ -- end
+
+ local function mpp(value)
+ n = n + 1
+ local t = type(value)
+ if t == "number" then
+ buffer[n] = f_numeric(value)
+ elseif t == "string" then
+ buffer[n] = value
+ elseif t == "table" then
+ buffer[n] = "(" .. concat(value,",") .. ")"
+ else -- boolean or whatever
+ buffer[n] = tostring(value)
+ end
+ end
+
+ local function mpprint(first,second,...)
+ if second == nil then
+ if first ~= nil then
+ mpp(first)
+ end
+ else
+ for i=1,select("#",first,second,...) do
+ local value = (select(i,first,second,...))
+ if value ~= nil then
+ mpp(value)
+ end
+ end
+ end
end
-end
-function mp.path(t,connector,cycle)
- if type(t) == "table" then
- local tn = #t
- if tn > 0 then
- if connector == true then
- connector = "--"
- cycle = true
- elseif not connector then
- connector = "--"
+ local function mpp(value)
+ n = n + 1
+ local t = type(value)
+ if t == "number" then
+ buffer[n] = f_numeric(value)
+ elseif t == "string" then
+ buffer[n] = lpegmatch(p,value)
+ elseif t == "table" then
+ if #t > 4 then
+ buffer[n] = ""
+ else
+ buffer[n] = "(" .. concat(value,",") .. ")"
end
- local ti = t[1]
- n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2])
- for i=2,tn do
- local ti = t[i]
- n = n + 1 ; buffer[n] = connector
- n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2])
+ else -- boolean or whatever
+ buffer[n] = tostring(value)
+ end
+ end
+
+ local function mpvprint(first,second,...) -- variable print
+ if second == nil then
+ if first ~= nil then
+ mpp(first)
end
- if cycle then
- n = n + 1 ; buffer[n] = connector
- n = n + 1 ; buffer[n] = "cycle"
+ else
+ for i=1,select("#",first,second,...) do
+ local value = (select(i,first,second,...))
+ if value ~= nil then
+ mpp(value)
+ end
end
end
end
-end
-function mp.size(t)
- n = n + 1
- buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
-end
+ local function mpstring(value)
+ n = n + 1
+ buffer[n] = lpegmatch(p,value)
+ end
-local mpnamedcolor = attributes.colors.mpnamedcolor
+ local function mpboolean(b)
+ n = n + 1
+ buffer[n] = b and "true" or "false"
+ end
-mp.NamedColor = function(str)
- mpprint(mpnamedcolor(str))
-end
+ local function mpnumeric(f)
+ n = n + 1
+ if not f or f == 0 then
+ buffer[n] = "0"
+ else
+ buffer[n] = f_numeric(f)
+ end
+ end
--- experiment: names can change
+ local function mpinteger(i)
+ n = n + 1
+ -- buffer[n] = i and f_integer(i) or "0"
+ buffer[n] = i or "0"
+ end
-local datasets = { }
-mp.datasets = datasets
+ local function mppoints(i)
+ n = n + 1
+ if not i or i == 0 then
+ buffer[n] = "0pt"
+ else
+ buffer[n] = f_points(i)
+ end
+ end
-function datasets.load(tag,filename)
- if not filename then
- tag, filename = file.basename(tag), tag
+ local function mppair(x,y)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_pair(x[1],x[2])
+ else
+ buffer[n] = f_pair(x,y)
+ end
end
- local data = mp.dataset(io.loaddata(filename) or "")
- datasets[tag] = {
- Data = data,
- Line = function(n) mp.path(data[n or 1]) end,
- Size = function() mp.size(data) end,
- }
-end
---
+ local function mppairpoints(x,y)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_pair_pt(x[1],x[2])
+ else
+ buffer[n] = f_pair_pt(x,y)
+ end
+ end
+
+ local function mptriplet(x,y,z)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_triplet(x[1],x[2],x[3])
+ else
+ buffer[n] = f_triplet(x,y,z)
+ end
+ end
-local replacer = lpeg.replacer("@","%%")
+ local function mptripletpoints(x,y,z)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_triplet_pt(x[1],x[2],x[3])
+ else
+ buffer[n] = f_triplet_pt(x,y,z)
+ end
+ end
-function mp.fprint(fmt,...)
- n = n + 1
- if not find(fmt,"%",1,true) then
- fmt = lpegmatch(replacer,fmt)
+ local function mpquadruple(w,x,y,z)
+ n = n + 1
+ if type(w) == "table" then
+ buffer[n] = f_quadruple(w[1],w[2],w[3],w[4])
+ else
+ buffer[n] = f_quadruple(w,x,y,z)
+ end
end
- buffer[n] = formatters[fmt](...)
-end
-local function mpquoted(fmt,s,...)
- n = n + 1
- if s then
+ local function mpquadruplepoints(w,x,y,z)
+ n = n + 1
+ if type(w) == "table" then
+ buffer[n] = f_quadruple_pt(w[1],w[2],w[3],w[4])
+ else
+ buffer[n] = f_quadruple_pt(w,x,y,z)
+ end
+ end
+
+ -- we have three kind of connectors:
+ --
+ -- .. ... -- (true)
+
+ local function mp_path(f2,f6,t,connector,cycle)
+ if type(t) == "table" then
+ local tn = #t
+ if tn == 1 then
+ local t1 = t[1]
+ n = n + 1 ; buffer[n] = f2(t1[1],t1[2])
+ elseif tn > 0 then
+ if connector == true or connector == nil then
+ connector = ".."
+ elseif connector == false then
+ connector = "--"
+ end
+ if cycle == nil then
+ cycle = t.cycle
+ if cycle == nil then
+ cycle = true
+ end
+ end
+ local six = connector == ".." -- otherwise we use whatever gets asked for
+ local controls = connector -- whatever
+ local a = t[1]
+ local b = t[2]
+ n = n + 1
+ if six and #a == 6 and #b == 6 then
+ buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
+ controls = ".."
+ else
+ buffer[n] = f2(a[1],a[2])
+ controls = connector
+ end
+ for i=2,tn-1 do
+ a = b
+ b = t[i+1]
+ n = n + 1
+ buffer[n] = connector
+ n = n + 1
+ if six and #a == 6 and #b == 6 then
+ buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
+ controls = ".."
+ else
+ buffer[n] = f2(a[1],a[2])
+ controls = connector
+ end
+ end
+ n = n + 1
+ buffer[n] = connector
+ a = b
+ b = t[1]
+ n = n + 1
+ if cycle then
+ if six and #a == 6 and #b == 6 then
+ buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
+ controls = ".."
+ else
+ buffer[n] = f2(a[1],a[2])
+ controls = connector
+ end
+ n = n + 1
+ buffer[n] = connector
+ n = n + 1
+ buffer[n] = "cycle"
+ else
+ buffer[n] = f2(a[1],a[2])
+ end
+ end
+ end
+ end
+
+ local function mppath(...)
+ mp_path(f_pair,f_ctrl,...)
+ end
+
+ local function mppathpoints(...)
+ mp_path(f_pair_pt,f_ctrl_pt,...)
+ end
+
+ local function mpsize(t)
+ n = n + 1
+ buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
+ end
+
+ local replacer = lpeg.replacer("@","%%")
+
+ local function mpfprint(fmt,...)
+ n = n + 1
if not find(fmt,"%",1,true) then
fmt = lpegmatch(replacer,fmt)
end
- -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"'
- buffer[n] = lpegmatch(p,formatters[fmt](s,...))
- elseif fmt then
- -- buffer[n] = '"' .. fmt .. '"'
- buffer[n] = lpegmatch(p,fmt)
- else
- -- something is wrong
+ buffer[n] = formatters[fmt](...)
end
+
+ local function mpquoted(fmt,s,...)
+ if s then
+ n = n + 1
+ if not find(fmt,"%",1,true) then
+ fmt = lpegmatch(replacer,fmt)
+ end
+ -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"'
+ buffer[n] = lpegmatch(p,formatters[fmt](s,...))
+ elseif fmt then
+ n = n + 1
+ -- buffer[n] = '"' .. fmt .. '"'
+ buffer[n] = lpegmatch(p,fmt)
+ else
+ -- something is wrong
+ end
+ end
+
+ aux.print = mpprint
+ aux.vprint = mpvprint
+ aux.boolean = mpboolean
+ aux.string = mpstring
+ aux.numeric = mpnumeric
+ aux.number = mpnumeric
+ aux.integer = mpinteger
+ aux.points = mppoints
+ aux.pair = mppair
+ aux.pairpoints = mppairpoints
+ aux.triplet = mptriplet
+ aux.tripletpoints = mptripletpoints
+ aux.quadruple = mpquadruple
+ aux.quadruplepoints = mpquadruplepoints
+ aux.path = mppath
+ aux.pathpoints = mppathpoints
+ aux.size = mpsize
+ aux.fprint = mpfprint
+ aux.quoted = mpquoted
+
+ -- we need access to the variables
+
+ function metapost.nofscriptruns()
+ return runs
+ end
+
+ -- sometimes we gain (e.g. .5 sec on the sync test)
+
+ local cache = table.makeweak()
+
+ function metapost.runscript(code)
+ nesting = nesting + 1
+ local trace = trace_enabled and trace_luarun
+ if trace then
+ report_luarun("%i: code: %s",nesting,code)
+ end
+ runs = runs + 1
+ local f = cache[code]
+ if not f then
+ f = loadstring(code .. " return mp._f_()")
+ if f then
+ cache[code] = f
+ elseif be_tolerant then
+ f = loadstring(code)
+ if f then
+ cache[code] = f
+ end
+ end
+ end
+ if f then
+ local _buffer_ = buffer
+ local _n_ = n
+ buffer = { }
+ n = 0
+ local result = f()
+ if result then
+ local t = type(result)
+ if t == "number" then
+ result = f_numeric(result)
+ elseif t ~= "string" then
+ result = tostring(result)
+ end
+ if trace then
+ if #result == 0 then
+ report_luarun("%i: no result",nesting)
+ else
+ report_luarun("%i: result: %s",nesting,result)
+ end
+ end
+ buffer = _buffer_
+ n = _n_
+ nesting = nesting - 1
+ return result
+ elseif trace then
+ report_luarun("%i: no result",nesting)
+ end
+ buffer, n = _buffer_, _n_
+ else
+ report_luarun("%i: no result, invalid code: %s",nesting,code)
+ end
+ nesting = nesting - 1
+ return ""
+ end
+
+ -- for the moment
+
+ for k, v in next, aux do mp[k] = v end
+
end
-mp.quoted = mpquoted
+do
+
+ local mpnamedcolor = attributes.colors.mpnamedcolor
+ local mpprint = aux.print
-function mp.n(t)
+ mp.mf_named_color = function(str)
+ mpprint(mpnamedcolor(str))
+ end
+
+end
+
+function mp.n(t) -- used ?
return type(t) == "table" and #t or 0
end
-local whitespace = lpegpatterns.whitespace
-local newline = lpegpatterns.newline
-local setsep = newline^2
-local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0
-local value = (1-whitespace)^1 / tonumber
-local entry = Ct( value * whitespace * value)
-local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1)
-local series = Ct((set * whitespace^0)^1)
+do
+
+ -- experiment: names can change
+
+ local mppath = aux.path
+ local mpsize = aux.size
+
+ local whitespace = lpegpatterns.whitespace
+ local newline = lpegpatterns.newline
+ local setsep = newline^2
+ local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0
+ local value = (1-whitespace)^1 / tonumber
+ local entry = Ct( value * whitespace * value)
+ local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1)
+ local series = Ct((set * whitespace^0)^1)
+
+ local pattern = whitespace^0 * series
-local pattern = whitespace^0 * series
+ local datasets = { }
+ mp.datasets = datasets
+
+ function mp.dataset(str)
+ return lpegmatch(pattern,str)
+ end
+
+ function datasets.load(tag,filename)
+ if not filename then
+ tag, filename = file.basename(tag), tag
+ end
+ local data = lpegmatch(pattern,io.loaddata(filename) or "")
+ datasets[tag] = {
+ data = data,
+ line = function(n) mppath(data[n or 1]) end,
+ size = function() mpsize(data) end,
+ }
+ end
+
+ table.setmetatablecall(datasets,function(t,k,f,...)
+ local d = datasets[k]
+ local t = type(d)
+ if t == "table" then
+ d = d[f]
+ if type(d) == "function" then
+ d(...)
+ else
+ mpvprint(...)
+ end
+ elseif t == "function" then
+ d(f,...)
+ end
+ end)
-function mp.dataset(str)
- return lpegmatch(pattern,str)
end
-- \startluacode
@@ -314,255 +617,157 @@ end
-- endfor ;
-- \stopMPpage
-local cache, n = { }, 0 -- todo: when > n then reset cache or make weak
-
-function metapost.runscript(code)
- local trace = trace_enabled and trace_luarun
- if trace then
- report_luarun("code: %s",code)
- end
- local f
- if n > 100 then
- cache = nil -- forget about caching
- f = loadstring(f_code(code))
- if not f and be_tolerant then
- f = loadstring(code)
- end
- else
- f = cache[code]
- if not f then
- f = loadstring(f_code(code))
- if f then
- n = n + 1
- cache[code] = f
- elseif be_tolerant then
- f = loadstring(code)
- if f then
- n = n + 1
- cache[code] = f
- end
- end
- end
- end
- if f then
- local result = f()
- if result then
- local t = type(result)
- if t == "number" then
- result = f_numeric(result)
- elseif t ~= "string" then
- result = tostring(result)
- end
- if trace then
- report_luarun("result: %s",result)
- end
- return result
- elseif trace then
- report_luarun("no result")
- end
- else
- report_luarun("no result, invalid code: %s",code)
- end
- return ""
-end
-
--- function metapost.initializescriptrunner(mpx)
--- mp.numeric = function(s) return mpx:get_numeric(s) end
--- mp.string = function(s) return mpx:get_string (s) end
--- mp.boolean = function(s) return mpx:get_boolean(s) end
--- mp.number = mp.numeric
--- end
-
-local get_numeric = mplib.get_numeric
-local get_string = mplib.get_string
-local get_boolean = mplib.get_boolean
-local get_number = get_numeric
-
--- function metapost.initializescriptrunner(mpx)
--- mp.numeric = function(s) return get_numeric(mpx,s) end
--- mp.string = function(s) return get_string (mpx,s) end
--- mp.boolean = function(s) return get_boolean(mpx,s) end
--- mp.number = mp.numeric
--- end
-
-local currentmpx = nil
-
-local get = { }
-mp.get = get
-
-get.numeric = function(s) return get_numeric(currentmpx,s) end
-get.string = function(s) return get_string (currentmpx,s) end
-get.boolean = function(s) return get_boolean(currentmpx,s) end
-get.number = mp.numeric
-
-function metapost.initializescriptrunner(mpx,trialrun)
- currentmpx = mpx
- if trace_luarun then
- report_luarun("type of run: %s", trialrun and "trial" or "final")
- end
- -- trace_enabled = not trialrun blocks too much
-end
-
-- texts:
-local factor = 65536*(7227/7200)
-local textexts = nil
-local mptriplet = mp.triplet
-local nbdimensions = nodes.boxes.dimensions
-
-function mp.tt_initialize(tt)
- textexts = tt
-end
+do
--- function mp.tt_wd(n)
--- local box = textexts and textexts[n]
--- mpprint(box and box.width/factor or 0)
--- end
--- function mp.tt_ht(n)
--- local box = textexts and textexts[n]
--- mpprint(box and box.height/factor or 0)
--- end
--- function mp.tt_dp(n)
--- local box = textexts and textexts[n]
--- mpprint(box and box.depth/factor or 0)
--- end
-
-function mp.tt_dimensions(n)
- local box = textexts and textexts[n]
- if box then
- -- could be made faster with nuts but not critical
- mptriplet(box.width/factor,box.height/factor,box.depth/factor)
- else
- mptriplet(0,0,0)
- end
-end
+ local mptriplet = mp.triplet
-function mp.tb_dimensions(category,name)
- local w, h, d = nbdimensions(category,name)
- mptriplet(w/factor,h/factor,d/factor)
-end
+ local bpfactor = number.dimenfactors.bp
+ local textexts = nil
+ local mptriplet = mp.triplet
+ local nbdimensions = nodes.boxes.dimensions
-function mp.report(a,b)
- if b then
- report_message("%s : %s",a,b)
- elseif a then
- report_message("%s : %s","message",a)
+ function mp.mf_tt_initialize(tt)
+ textexts = tt
end
-end
---
+ function mp.mf_tt_dimensions(n)
+ local box = textexts and textexts[n]
+ if box then
+ -- could be made faster with nuts but not critical
+ mptriplet(box.width*bpfactor,box.height*bpfactor,box.depth*bpfactor)
+ else
+ mptriplet(0,0,0)
+ end
+ end
-local hashes = { }
+ function mp.mf_tb_dimensions(category,name)
+ local w, h, d = nbdimensions(category,name)
+ mptriplet(w*bpfactor,h*bpfactor,d*bpfactor)
+ end
-function mp.newhash()
- for i=1,#hashes+1 do
- if not hashes[i] then
- hashes[i] = { }
- mpprint(i)
- return
+ function mp.report(a,b,c,...)
+ if c then
+ report_message("%s : %s",a,formatters[(gsub(b,"@","%%"))](c,...))
+ elseif b then
+ report_message("%s : %s",a,b)
+ elseif a then
+ report_message("%s : %s","message",a)
end
end
-end
-function mp.disposehash(n)
- hashes[n] = nil
end
-function mp.inhash(n,key)
- local h = hashes[n]
- mpprint(h and h[key] and true or false)
-end
+do
+
+ local mpprint = aux.print
+ local modes = tex.modes
+ local systemmodes = tex.systemmodes
-function mp.tohash(n,key)
- local h = hashes[n]
- if h then
- h[key] = true
+ function mp.mode(s)
+ mpprint(modes[s] and true or false)
end
-end
-local modes = tex.modes
-local systemmodes = tex.systemmodes
+ function mp.systemmode(s)
+ mpprint(systemmodes[s] and true or false)
+ end
-function mp.mode(s)
- mpprint(modes[s] and true or false)
-end
+ mp.processingmode = mp.mode
-function mp.systemmode(s)
- mpprint(systemmodes[s] and true or false)
end
-- for alan's nodes:
-function mp.isarray(str)
- mpprint(find(str,"%d") and true or false)
-end
+do
+
+ local mpprint = aux.print
+ local mpquoted = aux.quoted
+
+ function mp.isarray(str)
+ mpprint(find(str,"%d") and true or false)
+ end
+
+ function mp.prefix(str)
+ mpquoted(match(str,"^(.-)[%d%[]") or str)
+ end
+
+ -- function mp.dimension(str)
+ -- local n = 0
+ -- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
+ -- n = n + 1
+ -- end
+ -- mpprint(n)
+ -- end
+
+ mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
+
+ -- faster and okay as we don't have many variables but probably only
+ -- basename makes sense and even then it's not called that often
+
+ -- local hash = table.setmetatableindex(function(t,k)
+ -- local v = find(k,"%d") and true or false
+ -- t[k] = v
+ -- return v
+ -- end)
+ --
+ -- function mp.isarray(str)
+ -- mpprint(hash[str])
+ -- end
+ --
+ -- local hash = table.setmetatableindex(function(t,k)
+ -- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"'
+ -- t[k] = v
+ -- return v
+ -- end)
+ --
+ -- function mp.prefix(str)
+ -- mpprint(hash[str])
+ -- end
-function mp.prefix(str)
- mpquoted(match(str,"^(.-)[%d%[]") or str)
end
--- function mp.dimension(str)
--- local n = 0
--- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
--- n = n + 1
--- end
--- mpprint(n)
--- end
+do
-mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
+ local getmacro = tex.getmacro
+ local getdimen = tex.getdimen
+ local getcount = tex.getcount
+ local gettoks = tex.gettoks
+ local setmacro = tex.setmacro
+ local setdimen = tex.setdimen
+ local setcount = tex.setcount
+ local settoks = tex.settoks
--- faster and okay as we don't have many variables but probably only
--- basename makes sense and even then it's not called that often
+ local mpprint = mp.print
+ local mpquoted = mp.quoted
--- local hash = table.setmetatableindex(function(t,k)
--- local v = find(k,"%d") and true or false
--- t[k] = v
--- return v
--- end)
---
--- function mp.isarray(str)
--- mpprint(hash[str])
--- end
---
--- local hash = table.setmetatableindex(function(t,k)
--- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"'
--- t[k] = v
--- return v
--- end)
---
--- function mp.prefix(str)
--- mpprint(hash[str])
--- end
+ local bpfactor = number.dimenfactors.bp
-local getdimen = tex.getdimen
-local getcount = tex.getcount
-local gettoks = tex.gettoks
-local setdimen = tex.setdimen
-local setcount = tex.setcount
-local settoks = tex.settoks
+ -- more helpers
-local mpprint = mp.print
-local mpquoted = mp.quoted
+ local function getmacro(k) mpprint (getmacro(k)) end
+ local function getdimen(k) mpprint (getdimen(k)*bpfactor) end
+ local function getcount(k) mpprint (getcount(k)) end
+ local function gettoks (k) mpquoted(gettoks (k)) end
-local factor = number.dimenfactors.bp
+ local function setmacro(k,v) setmacro(k,v) end
+ local function setdimen(k,v) setdimen(k,v/bpfactor) end
+ local function setcount(k,v) setcount(k,v) end
+ local function settoks (k,v) settoks (k,v) end
--- more helpers
+ -- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
-function mp.getdimen(k) mpprint (getdimen(k)*factor) end
-function mp.getcount(k) mpprint (getcount(k)) end
-function mp.gettoks (k) mpquoted(gettoks (k)) end
-function mp.setdimen(k,v) setdimen(k,v/factor) end
-function mp.setcount(k,v) setcount(k,v) end
-function mp.settoks (k,v) settoks (k,v) end
+ mp._get_macro_ = getmacro mp.getmacro = getmacro
+ mp._get_dimen_ = getdimen mp.getdimen = getdimen
+ mp._get_count_ = getcount mp.getcount = getcount
+ mp._get_toks_ = gettoks mp.gettoks = gettoks
--- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
+ mp._set_macro_ = setmacro mp.setmacro = setmacro
+ mp._set_dimen_ = setdimen mp.setdimen = setdimen
+ mp._set_count_ = setcount mp.setcount = setcount
+ mp._set_toks_ = settoks mp.settoks = settoks
-mp._get_dimen_ = mp.getdimen
-mp._get_count_ = mp.getcount
-mp._get_toks_ = mp.gettoks
-mp._set_dimen_ = mp.setdimen
-mp._set_count_ = mp.setcount
-mp._set_toks_ = mp.settoks
+end
-- position fun
@@ -656,6 +861,21 @@ do
end
+do
+
+ local mppair = mp.pair
+
+ function mp.textextanchor(s)
+ local x, y = match(s,"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
+ if x and y then
+ x = tonumber(x)
+ y = tonumber(y)
+ end
+ mppair(x or 0,y or 0)
+ end
+
+end
+
do
local mprint = mp.print
@@ -674,31 +894,65 @@ end
do
- local mpvprint = mp.vprint
+ local mpprint = aux.print
+ local mpvprint = aux.vprint
- local stores = { }
+ local hashes = { }
- function mp.newstore(name)
- stores[name] = { }
+ function mp.newhash(name)
+ if name then
+ hashes[name] = { }
+ else
+ for i=1,#hashes+1 do
+ if not hashes[i] then
+ hashes[i] = { }
+ mpvprint(i)
+ return
+ end
+ end
+ end
end
- function mp.disposestore(name)
- stores[name] = nil
+ function mp.disposehash(n)
+ if tonumber(n) then
+ hashes[n] = false
+ else
+ hashes[n] = nil
+ end
end
- function mp.tostore(name,key,value)
- stores[name][key] = value
+ function mp.inhash(n,key)
+ local h = hashes[n]
+ mpvprint(h and h[key] and true or false)
end
- function mp.fromstore(name,key)
- mpvprint(stores[name][key]) -- type specific
+ function mp.tohash(n,key,value)
+ local h = hashes[n]
+ if h then
+ if value == nil then
+ h[key] = true
+ else
+ h[key] = value
+ end
+ end
+ end
+
+ function mp.fromhash(n,key)
+ local h = hashes[n]
+ mpvprint(h and h[key] or false)
end
interfaces.implement {
- name = "getMPstored",
+ name = "MPfromhash",
arguments = "2 strings",
actions = function(name,key)
- context(stores[name][key])
+ local h = hashes[name] or hashes[tonumber(name)]
+ if h then
+ local v = h[key] or h[tonumber(key)]
+ if v then
+ context(v)
+ end
+ end
end
}
@@ -706,11 +960,70 @@ end
do
- local mpprint = mp.print
- local texmodes = tex.modes
+ -- a bit overkill: just a find(str,"mf_object=") can be enough
- function mp.processingmode(s)
- mpprint(tostring(texmodes[s]))
+ local mpboolean = aux.boolean
+
+ local p1 = P("mf_object=")
+ local p2 = lpegpatterns.eol * p1
+ local pattern = (1-p2)^0 * p2 + p1
+
+ function mp.isobject(str)
+ mpboolean(pattern and str ~= "" and lpegmatch(pattern,str))
end
end
+
+do
+
+ local mpnumeric = aux.numeric
+ local mppair = aux.pair
+ local mpgetpath = get.path
+
+ local p = nil
+ local n = 0
+
+ local function mf_path_length(name)
+ p = mpgetpath(name)
+ n = p and #p or 0
+ mpnumeric(n)
+ end
+
+ local function mf_path_point(i)
+ if i > 0 and i <= n then
+ local pi = p[i]
+ mppair(pi[1],pi[2])
+ end
+ end
+
+ local function mf_path_left(i)
+ if i > 0 and i <= n then
+ local pi = p[i]
+ mppair(pi[5],pi[6])
+ end
+ end
+
+ local function mf_path_right(i)
+ if i > 0 and i <= n then
+ local pn
+ if i == 1 then
+ pn = p[2] or p[1]
+ else
+ pn = p[i+1] or p[1]
+ end
+ mppair(pn[3],pn[4])
+ end
+ end
+
+ local function mf_path_reset()
+ p = nil
+ n = 0
+ end
+
+ mp.mf_path_length = mf_path_length mp.pathlength = mf_path_length
+ mp.mf_path_point = mf_path_point mp.pathpoint = mf_path_point
+ mp.mf_path_left = mf_path_left mp.pathleft = mf_path_left
+ mp.mf_path_right = mf_path_right mp.pathright = mf_path_right
+ mp.mf_path_reset = mf_path_reset mp.pathreset = mf_path_reset
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.lua
index 75f810fb33b..92fde5e1369 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.lua
@@ -6,9 +6,8 @@ if not modules then modules = { } end modules ['mlib-pdf'] = {
license = "see context related readme files",
}
--- maybe %s is better than %f
-
-local format, concat, gsub = string.format, table.concat, string.gsub
+local gsub = string.gsub
+local concat, insert, remove = table.concat, table.insert, table.remove
local abs, sqrt, round = math.abs, math.sqrt, math.round
local setmetatable, rawset, tostring, tonumber, type = setmetatable, rawset, tostring, tonumber, type
local P, S, C, Ct, Cc, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Carg
@@ -41,23 +40,34 @@ local pdfflusher = { }
metapost.flushers.pdf = pdfflusher
metapost.n = 0
-metapost.optimize = true -- false
local experiment = true -- uses context(node) that already does delayed nodes
local savedliterals = nil -- needs checking
-local mpsliteral = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) -- pdfliteral.mode = 1
-
-local f_f = formatters["%F"]
-
-local f_m = formatters["%F %F m"]
-local f_c = formatters["%F %F %F %F %F %F c"]
-local f_l = formatters["%F %F l"]
-local f_cm = formatters["%F %F %F %F %F %F cm"]
-local f_M = formatters["%F M"]
+local mpsliteral = nodes.pool.originliteral
+
+local f_f = formatters["%.6F"]
+local f_m = formatters["%.6F %.6F m"]
+local f_c = formatters["%.6F %.6F %.6F %.6F %.6F %.6F c"]
+local f_l = formatters["%.6F %.6F l"]
+local f_cm = formatters["%.6F %.6F %.6F %.6F %.6F %.6F cm"]
+local f_M = formatters["%.6F M"]
local f_j = formatters["%i j"]
local f_J = formatters["%i J"]
-local f_d = formatters["[%s] %F d"]
-local f_w = formatters["%F w"]
+local f_d = formatters["[%s] %.6F d"]
+local f_w = formatters["%.3F w"]
+
+directives.register("metapost.stripzeros",function()
+ f_f = formatters["%.6N"]
+ f_m = formatters["%.6N %.6N m"]
+ f_c = formatters["%.6N %.6N %.6N %.6N %.6N %.6N c"]
+ f_l = formatters["%.6N %.6N l"]
+ f_cm = formatters["%.6N %.6N %.6N %.6N %.6N %.6N cm"]
+ f_M = formatters["%.6N M"]
+ f_j = formatters["%i j"]
+ f_J = formatters["%i J"]
+ f_d = formatters["[%s] %.6N d"]
+ f_w = formatters["%.3N w"]
+end)
directives.register("metapost.savetable",function(v)
if type(v) == "string" then
@@ -73,60 +83,28 @@ trackers.register("metapost.forcestroke",function(v)
force_stroke = v
end)
-local pdfliteral = function(pdfcode)
- local literal = copy_node(mpsliteral)
- literal.data = pdfcode
- return literal
-end
-
-- Because in MKiV we always have two passes, we save the objects. When an extra
-- mp run is done (due to for instance texts identifier in the parse pass), we
-- get a new result table and the stored objects are forgotten. Otherwise they
-- are reused.
local function getobjects(result,figure,index)
- if metapost.optimize then
- local robjects = result.objects
- if not robjects then
- robjects = { }
- result.objects = robjects
- end
- local fobjects = robjects[index or 1]
- if not fobjects then
- fobjects = figure:objects()
- robjects[index] = fobjects
- end
- return fobjects
- else
- return figure:objects()
- end
+ return figure:objects()
end
-function metapost.convert(result, trialrun, flusher, multipass, askedfig)
- if trialrun then
- local multipassindeed = metapost.parse(result,askedfig)
- if multipass and not multipassindeed and metapost.optimize then
- if save_table then
- table.save(save_table,metapost.totable(result,1)) -- direct
- end
- metapost.flush(result,flusher,askedfig) -- saves a run
- else
- return false
- end
- else
- if save_table then
- table.save(save_table,metapost.totable(result,1)) -- direct
- end
- metapost.flush(result,flusher,askedfig)
+function metapost.convert(specification,result)
+ local flusher = specification.flusher
+ local askedfig = specification.askedfig
+ if save_table then
+ table.save(save_table,metapost.totable(result,1)) -- direct
end
+ metapost.flush(specification,result)
return true -- done
end
function metapost.flushliteral(d)
if savedliterals then
- local literal = copy_node(mpsliteral)
- literal.data = savedliterals[d]
- write_node(literal)
+ write_node(mpsliteral(savedliterals[d]))
else
report_metapost("problem flushing literal %a",d)
end
@@ -140,7 +118,7 @@ function pdfflusher.comment(message)
if message then
message = formatters["%% mps graphic %s: %s"](metapost.n,message)
if experiment then
- context(pdfliteral(message))
+ context(mpsliteral(message))
elseif savedliterals then
local last = #savedliterals + 1
savedliterals[last] = message
@@ -169,7 +147,7 @@ function pdfflusher.flushfigure(pdfliterals) -- table
if #pdfliterals > 0 then
pdfliterals = concat(pdfliterals,"\n")
if experiment then
- context(pdfliteral(pdfliterals))
+ context(mpsliteral(pdfliterals))
else
if savedliterals then
local last = #savedliterals + 1
@@ -320,15 +298,6 @@ local p_boolean = P("false") * Cc(false) + P("true") * Cc(true)
local p_set = Ct(number^1)
local p_path = Ct(Ct(number * number^-5)^1)
--- local variable =
--- P("1:") * key * p_number
--- + P("2:") * key * p_string
--- + P("3:") * key * p_boolean
--- + S("4568") * P(":") * key * p_set
--- + P("7:") * key * p_path
---
--- local pattern_key = Cf ( Carg(1) * (Cg(variable * newline^0)^0), rawset)
-
local variable =
P("1:") * p_number
+ P("2:") * p_string
@@ -374,7 +343,9 @@ function metapost.processspecial(str)
end
end
-local function setproperties(figure)
+local stack = { }
+
+local function pushproperties(figure)
local boundingbox = figure:boundingbox()
local properties = {
llx = boundingbox[1],
@@ -388,313 +359,321 @@ local function setproperties(figure)
italic = figure:italcorr(),
number = figure:charcode() or 0,
}
+ insert(stack,properties)
metapost.properties = properties
return properties
end
+local function popproperties()
+ metapost.properties = remove(stack)
+end
+
local function nocomment() end
metapost.comment = nocomment
-function metapost.flush(result,flusher,askedfig)
+function metapost.flush(specification,result)
if result then
- local figures = result.fig
+ local flusher = specification.flusher
+ local askedfig = specification.askedfig
+ local incontext = specification.incontext
+ local figures = result.fig
if figures then
flusher = flusher or pdfflusher
- local resetplugins = metapost.resetplugins or ignore -- before figure
- local processplugins = metapost.processplugins or ignore -- each object
+ local resetplugins = metapost.resetplugins or ignore -- before figure
+ local processplugins = metapost.processplugins or ignore -- each object
local synchronizeplugins = metapost.synchronizeplugins or ignore
- local pluginactions = metapost.pluginactions or ignore -- before / after
- local startfigure = flusher.startfigure
- local stopfigure = flusher.stopfigure
- local flushfigure = flusher.flushfigure
- local textfigure = flusher.textfigure
- local processspecial = flusher.processspecial or metapost.processspecial
- metapost.comment = flusher.comment or nocomment
+ local pluginactions = metapost.pluginactions or ignore -- before / after
+ local startfigure = flusher.startfigure
+ local stopfigure = flusher.stopfigure
+ local flushfigure = flusher.flushfigure
+ local textfigure = flusher.textfigure
+ local processspecial = flusher.processspecial or metapost.processspecial
+ metapost.comment = flusher.comment or nocomment
for index=1,#figures do
- local figure = figures[index]
- local properties = setproperties(figure)
+ local figure = figures[index]
+ local properties = pushproperties(figure)
if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then
- local objects = getobjects(result,figure,index)
- local result = { }
- local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
- local llx = properties.llx
- local lly = properties.lly
- local urx = properties.urx
- local ury = properties.ury
+ local objects = getobjects(result,figure,index)
+ local result = { }
+ local miterlimit = -1
+ local linecap = -1
+ local linejoin = -1
+ local dashed = false
+ local llx = properties.llx
+ local lly = properties.lly
+ local urx = properties.urx
+ local ury = properties.ury
if urx < llx then
-- invalid
startfigure(properties.number,0,0,0,0,"invalid",figure)
stopfigure()
else
- startfigure(properties.number,llx,lly,urx,ury,"begin",figure)
- result[#result+1] = "q"
- if objects then
- resetplugins(result) -- we should move the colorinitializer here
- local savedpath = nil
- local savedhtap = nil
- for o=1,#objects do
- local object = objects[o]
- local objecttype = object.type
- if objecttype == "text" then
- result[#result+1] = "q"
- local ot = object.transform -- 3,4,5,6,1,2
- result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot))
- flushfigure(result) -- flush accumulated literals
- result = { }
- textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
- result[#result+1] = "Q"
- elseif objecttype == "special" then
- if processspecial then
- processspecial(object.prescript)
- end
- elseif objecttype == "start_clip" then
- local evenodd = not object.istext and object.postscript == "evenodd"
- result[#result+1] = "q"
- flushnormalpath(object.path,result,false)
- result[#result+1] = evenodd and "W* n" or "W n"
- elseif objecttype == "stop_clip" then
- result[#result+1] = "Q"
- miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false
- elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then
- -- skip
- else
- -- we use an indirect table as we want to overload
- -- entries but this is not possible in userdata
- --
- -- can be optimized if no path
- --
- local original = object
- local object = { }
- setmetatable(object, {
- __index = original
- })
- -- first we analyze
- local before, after = processplugins(object)
- local evenodd, collect, both = false, false, false
- local postscript = object.postscript
- if not object.istext then
- if postscript == "evenodd" then
- evenodd = true
- elseif postscript == "collect" then
- collect = true
- elseif postscript == "both" then
- both = true
- elseif postscript == "eoboth" then
- evenodd = true
- both = true
- end
- end
- --
- if collect then
- if not savedpath then
- savedpath = { object.path or false }
- savedhtap = { object.htap or false }
- else
- savedpath[#savedpath+1] = object.path or false
- savedhtap[#savedhtap+1] = object.htap or false
+
+ -- we need to be indirect if we want the one-pass solution
+
+ local function processfigure()
+ result[#result+1] = "q"
+ if objects then
+ -- resetplugins(result) -- we should move the colorinitializer here
+ local savedpath = nil
+ local savedhtap = nil
+ for o=1,#objects do
+ local object = objects[o]
+ local objecttype = object.type
+ if objecttype == "text" then
+ result[#result+1] = "q"
+ local ot = object.transform -- 3,4,5,6,1,2
+ result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
+ flushfigure(result) -- flush accumulated literals
+ result = { }
+ textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
+ result[#result+1] = "Q"
+ elseif objecttype == "special" then
+ if processspecial then
+ processspecial(object.prescript)
end
+ elseif objecttype == "start_clip" then
+ local evenodd = not object.istext and object.postscript == "evenodd"
+ result[#result+1] = "q"
+ flushnormalpath(object.path,result,false)
+ result[#result+1] = evenodd and "W* n" or "W n"
+ elseif objecttype == "stop_clip" then
+ result[#result+1] = "Q"
+ miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false
+ elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then
+ -- skip
else
- local objecttype = object.type -- can have changed
- if before then
- result = pluginactions(before,result,flushfigure)
- end
- local ml = object.miterlimit
- if ml and ml ~= miterlimit then
- miterlimit = ml
- result[#result+1] = f_M(ml)
- end
- local lj = object.linejoin
- if lj and lj ~= linejoin then
- linejoin = lj
- result[#result+1] = f_j(lj)
- end
- local lc = object.linecap
- if lc and lc ~= linecap then
- linecap = lc
- result[#result+1] = f_J(lc)
+ -- we use an indirect table as we want to overload
+ -- entries but this is not possible in userdata
+ --
+ -- can be optimized if no path
+ --
+ local original = object
+ local object = { }
+ setmetatable(object, {
+ __index = original
+ })
+ local before,
+ after = processplugins(object)
+ local evenodd = false
+ local collect = false
+ local both = false
+ local postscript = object.postscript
+ if not object.istext then
+ if postscript == "evenodd" then
+ evenodd = true
+ elseif postscript == "collect" then
+ collect = true
+ elseif postscript == "both" then
+ both = true
+ elseif postscript == "eoboth" then
+ evenodd = true
+ both = true
+ end
end
- if both then
- if dashed ~= false then -- was just dashed test
- result[#result+1] = "[] 0 d"
- dashed = false
+ --
+ if collect then
+ if not savedpath then
+ savedpath = { object.path or false }
+ savedhtap = { object.htap or false }
+ else
+ savedpath[#savedpath+1] = object.path or false
+ savedhtap[#savedhtap+1] = object.htap or false
end
else
- local dl = object.dash
- if dl then
- local d = f_d(concat(dl.dashes or {}," "),dl.offset)
- if d ~= dashed then
- dashed = d
- result[#result+1] = d
- end
- elseif dashed ~= false then -- was just dashed test
- result[#result+1] = "[] 0 d"
- dashed = false
+ local objecttype = object.type -- can have changed
+ if before then
+ result = pluginactions(before,result,flushfigure)
end
- end
- local path = object.path -- newpath
- local transformed, penwidth = false, 1
- local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point"
- local pen = object.pen
- if pen then
- if pen.type == 'elliptical' then
- transformed, penwidth = pen_characteristics(original) -- boolean, value
- result[#result+1] = f_w(penwidth) -- todo: only if changed
- if objecttype == 'fill' then
- objecttype = 'both'
+ local ml = object.miterlimit
+ if ml and ml ~= miterlimit then
+ miterlimit = ml
+ result[#result+1] = f_M(ml)
+ end
+ local lj = object.linejoin
+ if lj and lj ~= linejoin then
+ linejoin = lj
+ result[#result+1] = f_j(lj)
+ end
+ local lc = object.linecap
+ if lc and lc ~= linecap then
+ linecap = lc
+ result[#result+1] = f_J(lc)
+ end
+ if both then
+ if dashed ~= false then -- was just dashed test
+ result[#result+1] = "[] 0 d"
+ dashed = false
end
- else -- calculated by mplib itself
- objecttype = 'fill'
- end
- end
- if transformed then
- result[#result+1] = "q"
- end
- if path then
- if savedpath then
- for i=1,#savedpath do
- local path = savedpath[i]
- if transformed then
- flushconcatpath(path,result,open)
- else
- flushnormalpath(path,result,open)
+ else
+ local dl = object.dash
+ if dl then
+ local d = f_d(concat(dl.dashes or {}," "),dl.offset)
+ if d ~= dashed then
+ dashed = d
+ result[#result+1] = d
end
+ elseif dashed ~= false then -- was just dashed test
+ result[#result+1] = "[] 0 d"
+ dashed = false
end
- savedpath = nil
end
- if transformed then
- flushconcatpath(path,result,open)
- else
- flushnormalpath(path,result,open)
- end
- if force_stroke then
- result[#result+1] = open and "S" or "h S"
- elseif objecttype == "fill" then
- result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo
- elseif objecttype == "outline" then
- if both then
- result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo
- else
- result[#result+1] = open and "S" or "h S"
- end
- elseif objecttype == "both" then
- result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
+ local path = object.path -- newpath
+ local transformed = false
+ local penwidth = 1
+ local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point"
+ local pen = object.pen
+ if pen then
+ if pen.type == "elliptical" then
+ transformed, penwidth = pen_characteristics(original) -- boolean, value
+ result[#result+1] = f_w(penwidth) -- todo: only if changed
+ if objecttype == "fill" then
+ objecttype = "both"
+ end
+ else -- calculated by mplib itself
+ objecttype = "fill"
+ end
end
- end
- if transformed then
- result[#result+1] = "Q"
- end
- local path = object.htap
- if path then
if transformed then
result[#result+1] = "q"
end
- if savedhtap then
- for i=1,#savedhtap do
- local path = savedhtap[i]
- if transformed then
- flushconcatpath(path,result,open)
+ if path then
+ if savedpath then
+ for i=1,#savedpath do
+ local path = savedpath[i]
+ if transformed then
+ flushconcatpath(path,result,open)
+ else
+ flushnormalpath(path,result,open)
+ end
+ end
+ savedpath = nil
+ end
+ if transformed then
+ flushconcatpath(path,result,open)
+ else
+ flushnormalpath(path,result,open)
+ end
+ if force_stroke then
+ result[#result+1] = open and "S" or "h S"
+ elseif objecttype == "fill" then
+ result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo
+ elseif objecttype == "outline" then
+ if both then
+ result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo
else
- flushnormalpath(path,result,open)
+ result[#result+1] = open and "S" or "h S"
end
+ elseif objecttype == "both" then
+ result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
end
- savedhtap = nil
- evenodd = true
end
if transformed then
- flushconcatpath(path,result,open)
- else
- flushnormalpath(path,result,open)
+ result[#result+1] = "Q"
end
- if force_stroke then
- result[#result+1] = open and "S" or "h S"
- elseif objecttype == "fill" then
- result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo
- elseif objecttype == "outline" then
- result[#result+1] = open and "S" or "h S"
- elseif objecttype == "both" then
- result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
+ local path = object.htap
+ if path then
+ if transformed then
+ result[#result+1] = "q"
+ end
+ if savedhtap then
+ for i=1,#savedhtap do
+ local path = savedhtap[i]
+ if transformed then
+ flushconcatpath(path,result,open)
+ else
+ flushnormalpath(path,result,open)
+ end
+ end
+ savedhtap = nil
+ evenodd = true
+ end
+ if transformed then
+ flushconcatpath(path,result,open)
+ else
+ flushnormalpath(path,result,open)
+ end
+ if force_stroke then
+ result[#result+1] = open and "S" or "h S"
+ elseif objecttype == "fill" then
+ result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo
+ elseif objecttype == "outline" then
+ result[#result+1] = open and "S" or "h S"
+ elseif objecttype == "both" then
+ result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
+ end
+ if transformed then
+ result[#result+1] = "Q"
+ end
end
- if transformed then
- result[#result+1] = "Q"
+ if after then
+ result = pluginactions(after,result,flushfigure)
end
end
- if after then
- result = pluginactions(after,result,flushfigure)
+ if object.grouped then
+ -- can be qQ'd so changes can end up in groups
+ miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false
end
end
- if object.grouped then
- -- can be qQ'd so changes can end up in groups
- miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false
- end
end
end
+ result[#result+1] = "Q"
+ flushfigure(result)
+ end
+ startfigure(properties.number,llx,lly,urx,ury,"begin",figure)
+ if incontext then
+ context(function() processfigure() end)
+ else
+ processfigure()
end
- result[#result+1] = "Q"
- flushfigure(result)
stopfigure("end")
+
end
if askedfig ~= "all" then
break
end
end
+ popproperties()
end
metapost.comment = nocomment
+ resetplugins(result) -- we should move the colorinitializer here
end
end
end
-function metapost.parse(result,askedfig)
- if result then
- local figures = result.fig
- if figures then
- local multipass = false
- local analyzeplugins = metapost.analyzeplugins -- each object
- for index=1,#figures do
- local figure = figures[index]
- local properties = setproperties(figure)
- if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then
- local objects = getobjects(result,figure,index)
- if objects then
- for o=1,#objects do
- if analyzeplugins(objects[o]) then
- multipass = true
- end
- end
- end
- if askedfig ~= "all" then
- break
- end
- end
+-- tracing:
+
+do
+
+ local result = { }
+
+ local flusher = {
+ startfigure = function()
+ result = { }
+ context.startnointerference()
+ end,
+ flushfigure = function(literals)
+ local n = #result
+ for i=1,#literals do
+ result[n+i] = literals[i]
end
- return multipass
+ end,
+ stopfigure = function()
+ context.stopnointerference()
end
- end
-end
+ }
--- tracing:
+ local specification = {
+ flusher = flusher,
+ -- incontext = true,
+ }
-local result = { }
-
-local flusher = {
- startfigure = function()
- result = { }
- context.startnointerference()
- end,
- flushfigure = function(literals)
- local n = #result
- for i=1,#literals do
- result[n+i] = literals[i]
- end
- end,
- stopfigure = function()
- context.stopnointerference()
+ function metapost.pdfliterals(result)
+ metapost.flush(specification,result)
+ return result
end
-}
-function metapost.pdfliterals(result)
- metapost.flush(result,flusher)
- return result
end
function metapost.totable(result,askedfig)
@@ -702,7 +681,6 @@ function metapost.totable(result,askedfig)
local figure = result and result.fig and result.fig[1]
if figure then
local results = { }
- -- local objects = figure:objects()
local objects = getobjects(result,figure,askedfig)
for o=1,#objects do
local object = objects[o]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.mkiv
index 147b67f743c..6dc73a15352 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-pdf.mkiv
@@ -47,6 +47,18 @@
\global\MPurx \zeropoint
\global\MPury \zeropoint}
+\let\popMPboundingbox\relax
+
+\unexpanded\def\pushMPboundingbox
+ {\edef\popMPboundingbox
+ {\global\MPwidth \the\MPwidth
+ \global\MPheight\the\MPheight
+ \global\MPllx \the\MPllx
+ \global\MPlly \the\MPlly
+ \global\MPurx \the\MPurx
+ \global\MPury \the\MPury
+ \relax}}
+
\unexpanded\def\repositionMPboxindeed
{\setbox\MPbox\hpack\bgroup
\kern-\MPllx
@@ -76,15 +88,15 @@
\wd\MPbox\MPwidth
\ht\MPbox\MPheight}
-\unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps)
- {\begingroup
- \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text
- \MPllx-#4\onebasepoint
- \MPlly-#5\onebasepoint
- \repositionMPbox
- \smashbox\MPbox
- \box\MPbox
- \endgroup}
+% \unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps)
+% {\begingroup
+% \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text
+% \MPllx-#4\onebasepoint
+% \MPlly-#5\onebasepoint
+% \repositionMPbox
+% \smashbox\MPbox
+% \box\MPbox
+% \endgroup}
% MPLIB specific:
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua
index bb5ce31e5e5..5708577fea6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.lua
@@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['mlib-pps'] = {
license = "see context related readme files",
}
-local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split
-local tonumber, type, unpack, next = tonumber, type, unpack, next
+local format, gmatch, match, split, gsub = string.format, string.gmatch, string.match, string.split, string.gsub
+local tonumber, type, unpack, next, select = tonumber, type, unpack, next, select
local round, sqrt, min, max = math.round, math.sqrt, math.min, math.max
local insert, remove, concat = table.insert, table.remove, table.concat
local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg
@@ -23,7 +23,6 @@ local context = context
local implement = interfaces.implement
local setmacro = interfaces.setmacro
------ texgetbox = tex.getbox
local texsetbox = tex.setbox
local textakebox = tex.takebox -- or: nodes.takebox
local copy_list = node.copy_list
@@ -37,6 +36,7 @@ local stoptiming = statistics.stoptiming
local trace_runs = false trackers.register("metapost.runs", function(v) trace_runs = v end)
local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end)
local trace_scripts = false trackers.register("metapost.scripts", function(v) trace_scripts = v end)
+local trace_btexetex = false trackers.register("metapost.btexetex", function(v) trace_btexetex = v end)
local report_metapost = logs.reporter("metapost")
local report_textexts = logs.reporter("metapost","textexts")
@@ -57,9 +57,6 @@ local cmyktorgb = colors.cmyktorgb -- or function() return 0,0,0 e
local rgbtogray = colors.rgbtogray -- or function() return 0 end
local cmyktogray = colors.cmyktogray -- or function() return 0 end
-metapost.makempy = metapost.makempy or { nofconverted = 0 }
-local makempy = metapost.makempy
-
local nooutercolor = "0 g 0 G"
local nooutertransparency = "/Tr0 gs" -- only when set
local outercolormode = 0
@@ -97,14 +94,25 @@ end
local f_f = formatters["%F"]
local f_f3 = formatters["%.3F"]
-
local f_gray = formatters["%.3F g %.3F G"]
local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"]
local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"]
-local f_cm = formatters["q %F %F %F %F %F %F cm"]
-local f_shade = formatters["MpSh%s"]
+local f_cm_b = formatters["q %.6F %.6F %.6F %.6F %.6F %.6F cm"]
+local f_scn = formatters["%.3F"]
+local f_shade = formatters["MpSh%s"]
local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"]
+local s_cm_e = "Q"
+
+directives.register("metapost.stripzeros",function()
+ f_f = formatters["%N"]
+ f_f3 = formatters["%.3N"]
+ f_gray = formatters["%.3N g %.3N G"]
+ f_rgb = formatters["%.3N %.3N %.3N rg %.3N %.3N %.3N RG"]
+ f_cmyk = formatters["%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K"]
+ f_cm_b = formatters["q %.6N %.6N %.6N %.6N %.6N %.6N cm"]
+ f_scn = formatters["%.3N"]
+end)
local function checked_color_pair(color,...)
if not color then
@@ -194,7 +202,8 @@ local function checkandconvert(ca,cb,model)
ca = { cmyktorgb(ca[1],ca[2],ca[3],ca[4]) }
cb = { cmyktorgb(cb[1],cb[2],cb[3],cb[4]) }
elseif #ca == 1 then
- local a, b = 1-ca[1], 1-cb[1]
+ local a = 1 - ca[1]
+ local b = 1 - cb[1]
ca = { a, a, a }
cb = { b, b, b }
end
@@ -244,16 +253,18 @@ local function preset(t,k)
return v
end
-local function startjob(plugmode)
+local function startjob(plugmode,kind)
+ insert(stack,top)
top = {
- textexts = { }, -- all boxes, optionally with a different color
- texlast = 0,
- texdata = setmetatableindex({},preset), -- references to textexts in order or usage
- plugmode = plugmode, -- some day we can then skip all pre/postscripts
+ textexts = { }, -- all boxes, optionally with a different color
+ texstrings = { },
+ texlast = 0,
+ texdata = setmetatableindex({},preset), -- references to textexts in order or usage
+ plugmode = plugmode, -- some day we can then skip all pre/postscripts
}
- insert(stack,top)
if trace_runs then
- report_metapost("starting run at level %i",#stack)
+ report_metapost("starting %s run at level %i in %s mode",
+ kind,#stack+1,plugmode and "plug" or "normal")
end
return top
end
@@ -261,16 +272,17 @@ end
local function stopjob()
if top then
for slot, content in next, top.textexts do
- flush_list(content)
- if trace_textexts then
- report_textexts("freeing text %s",slot)
+ if content then
+ flush_list(content)
+ if trace_textexts then
+ report_textexts("freeing text %s",slot)
+ end
end
end
if trace_runs then
- report_metapost("stopping run at level %i",#stack)
+ report_metapost("stopping run at level %i",#stack+1)
end
- remove(stack)
- top = stack[#stack]
+ top = remove(stack)
return top
end
end
@@ -281,7 +293,7 @@ end
-- end of new
-local function settext(box,slot)
+local settext = function(box,slot,str)
if top then
-- if trace_textexts then
-- report_textexts("getting text %s from box %s",slot,box)
@@ -290,10 +302,10 @@ local function settext(box,slot)
end
end
-local function gettext(box,slot)
+local gettext = function(box,slot)
if top then
- -- maybe check how often referenced
- texsetbox(box,copy_list(top.textexts[slot]))
+ texsetbox(box,top.textexts[slot])
+ top.textexts[slot] = false
-- if trace_textexts then
-- report_textexts("putting text %s in box %s",slot,box)
-- end
@@ -323,14 +335,19 @@ function models.all(cr)
local s = cr[1]
return checked_color_pair(f_gray,s,s)
elseif n == 3 then
- local r, g, b = cr[1], cr[2], cr[3]
+ local r = cr[1]
+ local g = cr[2]
+ local b = cr[3]
if r == g and g == b then
return checked_color_pair(f_gray,r,r)
else
return checked_color_pair(f_rgb,r,g,b,r,g,b)
end
else
- local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ local c = cr[1]
+ local m = cr[2]
+ local y = cr[3]
+ local k = cr[4]
if c == m and m == y and y == 0 then
k = 1 - k
return checked_color_pair(f_gray,k,k)
@@ -342,10 +359,15 @@ function models.all(cr)
local s = cr[1]
return checked_color_pair(f_gray,s,s)
elseif n == 3 then
- local r, g, b = cr[1], cr[2], cr[3]
+ local r = cr[1]
+ local g = cr[2]
+ local b = cr[3]
return checked_color_pair(f_rgb,r,g,b,r,g,b)
else
- local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ local c = cr[1]
+ local m = cr[2]
+ local y = cr[3]
+ local k = cr[4]
return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k)
end
end
@@ -359,14 +381,19 @@ function models.rgb(cr)
local s = cr[1]
checked_color_pair(f_gray,s,s)
elseif n == 3 then
- local r, g, b = cr[1], cr[2], cr[3]
+ local r = cr[1]
+ local g = cr[2]
+ local b = cr[3]
if r == g and g == b then
return checked_color_pair(f_gray,r,r)
else
return checked_color_pair(f_rgb,r,g,b,r,g,b)
end
else
- local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ local c = cr[1]
+ local m = cr[2]
+ local y = cr[3]
+ local k = cr[4]
if c == m and m == y and y == 0 then
k = 1 - k
return checked_color_pair(f_gray,k,k)
@@ -379,11 +406,12 @@ function models.rgb(cr)
local s = cr[1]
return checked_color_pair(f_gray,s,s)
else
+ local r = cr[1]
+ local g = cr[2]
+ local b = cr[3]
local r, g, b
if n == 3 then
- r, g, b = cmyktorgb(cr[1],cr[2],cr[3],cr[4])
- else
- r, g, b = cr[1], cr[2], cr[3]
+ r, g, b = cmyktorgb(r,g,b,cr[4])
end
return checked_color_pair(f_rgb,r,g,b,r,g,b)
end
@@ -398,7 +426,9 @@ function models.cmyk(cr)
local s = cr[1]
return checked_color_pair(f_gray,s,s)
elseif n == 3 then
- local r, g, b = cr[1], cr[2], cr[3]
+ local r = cr[1]
+ local g = cr[2]
+ local b = cr[3]
if r == g and g == b then
return checked_color_pair(f_gray,r,r)
else
@@ -406,7 +436,10 @@ function models.cmyk(cr)
return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k)
end
else
- local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ local c = cr[1]
+ local m = cr[2]
+ local y = cr[3]
+ local k = cr[4]
if c == m and m == y and y == 0 then
k = k - 1
return checked_color_pair(f_gray,k,k)
@@ -418,18 +451,20 @@ function models.cmyk(cr)
local s = cr[1]
return checked_color_pair(f_gray,s,s)
else
- local c, m, y, k
+ local c = cr[1]
+ local m = cr[2]
+ local y = cr[3]
+ local k = cr[4]
if n == 3 then
- c, m, y, k = rgbtocmyk(cr[1],cr[2],cr[3])
- else
- c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ c, m, y, k = rgbtocmyk(c,m,y)
end
return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k)
end
end
function models.gray(cr)
- local n, s = #cr, 0
+ local n = #cr
+ local s = 0
if n == 0 then
return checked_color_pair()
elseif n == 4 then
@@ -454,76 +489,9 @@ setmetatableindex(models, function(t,k)
end)
local function colorconverter(cs)
- -- return models[colors.currentmodel()](cs)
return models[outercolormodel](cs)
end
-local btex = P("btex")
-local etex = P(" etex")
-local vtex = P("verbatimtex")
-local ttex = P("textext")
-local gtex = P("graphictext")
-local multipass = P("forcemultipass")
-local spacing = S(" \n\r\t\v")^0
-local dquote = P('"')
-
-local found, forced = false, false
-
-local function convert(str)
- found = true
- return "rawtextext(\"" .. str .. "\")" -- centered
-end
-local function ditto(str)
- return "\" & ditto & \""
-end
-local function register()
- found = true
-end
-local function force()
- forced = true
-end
-
-local texmess = (dquote/ditto + (1 - etex))^0
-
-local function ignore(s)
- report_metapost("ignoring verbatim tex: %s",s)
- return ""
-end
-
--- local parser = P {
--- [1] = Cs((V(2)/register + V(4)/ignore + V(3)/convert + V(5)/force + 1)^0),
--- [2] = ttex + gtex,
--- [3] = btex * spacing * Cs(texmess) * etex,
--- [4] = vtex * spacing * Cs(texmess) * etex,
--- [5] = multipass, -- experimental, only for testing
--- }
-
--- currently a a one-liner produces less code
-
--- textext.*(".*") can have "'s but tricky parsing as we can have concatenated strings
--- so this is something for a boring plane or train trip and we might assume proper mp
--- input anyway
-
-local parser = Cs((
- (ttex + gtex)/register
- + (btex * spacing * Cs(texmess) * etex)/convert
- + (vtex * spacing * Cs(texmess) * etex)/ignore
- + 1
-)^0)
-
-local checking_enabled = false directives.register("metapost.checktexts",function(v) checking_enabled = v end)
-
-local function checktexts(str)
- if checking_enabled then
- found, forced = false, false
- return lpegmatch(parser,str), found, forced
- else
- return str
- end
-end
-
-metapost.checktexts = checktexts
-
local factor = 65536*(7227/7200)
implement {
@@ -541,42 +509,15 @@ local function sxsy(wd,ht,dp) -- helper for text
return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0
end
+metapost.sxsy = sxsy
+
-- for stock mp we need to declare the booleans first
-local no_first_run = "boolean mfun_first_run ; mfun_first_run := false ;"
-local do_first_run = "boolean mfun_first_run ; mfun_first_run := true ;"
-local no_trial_run = "boolean mfun_trial_run ; mfun_trial_run := false ;"
-local do_trial_run = "boolean mfun_trial_run ; mfun_trial_run := true ;"
local do_begin_fig = "; beginfig(1) ; "
local do_end_fig = "; endfig ;"
local do_safeguard = ";"
--- local f_text_data = formatters["mfun_tt_w[%i] := %f ; mfun_tt_h[%i] := %f ; mfun_tt_d[%i] := %f ;"]
---
--- function metapost.textextsdata()
--- local textexts = top.textexts
--- local collected = { }
--- local nofcollected = 0
--- for k, data in sortedhash(top.texdata) do -- sort is nicer in trace
--- local texorder = data.texorder
--- for n=1,#texorder do
--- local box = textexts[texorder[n]]
--- if box then
--- local wd, ht, dp = box.width/factor, box.height/factor, box.depth/factor
--- if trace_textexts then
--- report_textexts("passed data item %s:%s > (%p,%p,%p)",k,n,wd,ht,dp)
--- end
--- nofcollected = nofcollected + 1
--- collected[nofcollected] = f_text_data(n,wd,n,ht,n,dp)
--- else
--- break
--- end
--- end
--- end
--- return collected
--- end
-
-function metapost.textextsdata()
+function metapost.preparetextextsdata()
local textexts = top.textexts
local collected = { }
for k, data in sortedhash(top.texdata) do -- sort is nicer in trace
@@ -590,18 +531,10 @@ function metapost.textextsdata()
end
end
end
- mp.tt_initialize(collected)
+ mp.mf_tt_initialize(collected)
end
-
-metapost.intermediate = metapost.intermediate or { }
-metapost.intermediate.actions = metapost.intermediate.actions or { }
-
-metapost.method = 1 -- 1:dumb 2:clever
-
--- maybe we can latelua the texts some day
-
-local processmetapost = metapost.process
+local runmetapost = metapost.run
local function checkaskedfig(askedfig) -- return askedfig, wrappit
if not askedfig then
@@ -624,231 +557,98 @@ local function extrapass()
if trace_runs then
report_metapost("second run of job %s, asked figure %a",top.nofruns,top.askedfig)
end
- local textexts = metapost.textextsdata()
- processmetapost(top.mpx, {
- top.wrappit and do_begin_fig or "",
- no_trial_run,
- textexts and concat(textexts," ;\n") or "",
- top.initializations,
- do_safeguard,
- top.data,
- top.wrappit and do_end_fig or "",
- }, false, nil, false, true, top.askedfig)
+ metapost.preparetextextsdata()
+ runmetapost {
+ mpx = top.mpx,
+ askedfig = top.askedfig,
+ incontext = true,
+ data = {
+ top.wrappit and do_begin_fig or "",
+ no_trial_run,
+ top.initializations,
+ do_safeguard,
+ top.data,
+ top.wrappit and do_end_fig or "",
+ },
+ }
end
-function metapost.graphic_base_pass(specification) -- name will change (see mlib-ctx.lua)
- local top = startjob(true)
- --
+-- This one is called from the \TEX\ end so the specification is different
+-- from the specification to metapost,run cum suis! The definitions and
+-- extension used to be handled here but are now delegated to the format
+-- initializers because we need to accumulate them for nested instances (a
+-- side effect of going single pass).
+
+function metapost.graphic_base_pass(specification)
+ local top = startjob(true,"base")
local mpx = specification.mpx -- mandate
local data = specification.data or ""
- local definitions = specification.definitions or ""
- -- local extensions = metapost.getextensions(specification.instance,specification.useextensions)
- local extensions = specification.extensions or ""
local inclusions = specification.inclusions or ""
local initializations = specification.initializations or ""
- local askedfig = specification.figure -- no default else no wrapper
+ local askedfig,
+ wrappit = checkaskedfig(specification.figure)
+ nofruns = nofruns + 1
+ top.askedfig = askedfig
+ top.wrappit = wrappit
+ top.nofruns = nofruns
metapost.namespace = specification.namespace or ""
- --
- local askedfig, wrappit = checkaskedfig(askedfig)
- --
- nofruns = nofruns + 1
- --
- top.askedfig = askedfig
- top.wrappit = wrappit
- top.nofruns = nofruns
- --
- local done_1, done_2, done_3, forced_1, forced_2, forced_3
- if checking_enabled then
- data, done_1, forced_1 = checktexts(data)
- if extensions == "" then
- extensions, done_2, forced_2 = "", false, false
- else
- extensions, done_2, forced_2 = checktexts(extensions)
- end
- if inclusions == "" then
- inclusions, done_3, forced_3 = "", false, false
- else
- inclusions, done_3, forced_3 = checktexts(inclusions)
- end
- end
- top.intermediate = false
- top.multipass = false -- no needed here
- top.mpx = mpx
- top.data = data
- top.initializations = initializations
- local method = metapost.method
+ top.mpx = mpx
+ top.data = data
+ top.initializations = initializations
if trace_runs then
- if method == 1 then
- report_metapost("forcing two runs due to library configuration")
- elseif method ~= 2 then
- report_metapost("ignoring run due to library configuration")
- elseif not (done_1 or done_2 or done_3) then
- report_metapost("forcing one run only due to analysis")
- elseif done_1 then
- report_metapost("forcing at max two runs due to main code")
- elseif done_2 then
- report_metapost("forcing at max two runs due to extensions")
- else
- report_metapost("forcing at max two runs due to inclusions")
- end
+ report_metapost("running job %s, asked figure %a",nofruns,askedfig)
end
- if method == 1 or (method == 2 and (done_1 or done_2 or done_3)) then
- if trace_runs then
- report_metapost("first run of job %s, asked figure %a",nofruns,askedfig)
- end
- -- first true means: trialrun, second true means: avoid extra run if no multipass
- local flushed = processmetapost(mpx, {
- definitions,
- extensions,
- inclusions,
- wrappit and do_begin_fig or "",
- do_first_run,
- do_trial_run,
- initializations,
- do_safeguard,
- data,
- wrappit and do_end_fig or "",
- }, true, nil, not (forced_1 or forced_2 or forced_3), false, askedfig)
- if top.intermediate then
- for _, action in next, metapost.intermediate.actions do
- action()
- end
- end
- if not flushed or not metapost.optimize then
- -- tricky, we can only ask once for objects and therefore
- -- we really need a second run when not optimized
- -- context.MPLIBextrapass(askedfig)
- context(extrapass)
- end
- else
- if trace_runs then
- report_metapost("running job %s, asked figure %a",nofruns,askedfig)
- end
- processmetapost(mpx, {
- definitions,
- extensions,
+ runmetapost {
+ mpx = mpx,
+ askedfig = askedfig,
+ incontext = true,
+ data = {
inclusions,
wrappit and do_begin_fig or "",
- do_first_run,
- no_trial_run,
initializations,
do_safeguard,
data,
wrappit and do_end_fig or "",
- }, false, nil, false, false, askedfig)
- end
+ },
+ }
context(stopjob)
end
--- we overload metapost.process here
-
-function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, plugmode) -- overloads
- startjob(plugmode)
- processmetapost(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig)
- stopjob()
-end
-
-local start = [[\starttext]]
-local preamble = [[\def\MPLIBgraphictext#1{\startTEXpage[scale=10000]#1\stopTEXpage}]]
-local stop = [[\stoptext]]
-
-local mpyfilename = nil
-
-function makempy.registerfile(filename)
- mpyfilename = filename
+local function oldschool(mpx, data, trial_run, flusher, was_multi_pass, is_extra_pass, askedfig, incontext)
+ metapost.process {
+ mpx = mpx,
+ flusher = flusher,
+ askedfig = askedfig,
+ useplugins = incontext,
+ incontext = incontext,
+ data = data,
+ }
end
-implement {
- name = "registermpyfile",
- actions = makempy.registerfile,
- arguments = "string"
-}
-
-local pdftompy = sandbox.registerrunner {
- name = "mpy:pstoedit",
- program = "pstoedit",
- template = "-ssp -dt -f mpost %pdffile% %mpyfile%",
- checkers = {
- pdffile = "writable",
- mpyfile = "readable",
- },
- reporter = report_metapost,
-}
-
-local textopdf = sandbox.registerrunner {
- name = "mpy:context",
- program = "context",
- template = "--once %runmode% %texfile%",
- checkers = {
- runmode = "string",
- texfile = "readable",
- },
- reporter = report_metapost,
-}
-
-function makempy.processgraphics(graphics)
- if #graphics == 0 then
- return
- end
- if mpyfilename and exists(mpyfilename) then
- report_metapost("using file: %s",mpyfilename)
- return
- end
- makempy.nofconverted = makempy.nofconverted + 1
- starttiming(makempy)
- local mpofile = tex.jobname .. "-mpgraph"
- local mpyfile = file.replacesuffix(mpofile,"mpy")
- local pdffile = file.replacesuffix(mpofile,"pdf")
- local texfile = file.replacesuffix(mpofile,"tex")
- savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n")
- textopdf {
- runmode = tex.interactionmode == 0 and "--batchmode" or "",
- texfile = texfile,
- }
- if exists(pdffile) then
- pdftompy {
- pdffile = pdffile,
- mpyfile = mpyfile,
- }
- if exists(mpyfile) then
- local result, r = { }, 0
- local data = io.loaddata(mpyfile)
- if data and #data > 0 then
- for figure in gmatch(data,"beginfig(.-)endfig") do
- r = r + 1
- result[r] = formatters["begingraphictextfig%sendgraphictextfig ;\n"](figure)
- end
- savedata(mpyfile,concat(result,""))
- end
- end
+function metapost.process(specification,...)
+ if type(specification) ~= "table" then
+ oldschool(specification,...)
+ else
+ startjob(specification.incontext or specification.useplugins,"process")
+ runmetapost(specification)
+ stopjob()
end
- stoptiming(makempy)
end
-- -- the new plugin handler -- --
-local sequencers = utilities.sequencers
-local appendgroup = sequencers.appendgroup
-local appendaction = sequencers.appendaction
+local sequencers = utilities.sequencers
+local appendgroup = sequencers.appendgroup
+local appendaction = sequencers.appendaction
-local resetter = nil
-local analyzer = nil
-local processor = nil
-
-local resetteractions = sequencers.new { arguments = "t" }
-local analyzeractions = sequencers.new { arguments = "object,prescript" }
-local processoractions = sequencers.new { arguments = "object,prescript,before,after" }
+local resetteractions = sequencers.new { arguments = "t" }
+local processoractions = sequencers.new { arguments = "object,prescript,before,after" }
appendgroup(resetteractions, "system")
-appendgroup(analyzeractions, "system")
appendgroup(processoractions,"system")
-- later entries come first
---~ local scriptsplitter = Cf(Ct("") * (
---~ Cg(C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0)
---~ )^0, rawset)
-
local scriptsplitter = Ct ( Ct (
C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0
)^0 )
@@ -857,22 +657,24 @@ local function splitprescript(script)
local hash = lpegmatch(scriptsplitter,script)
for i=#hash,1,-1 do
local h = hash[i]
-if h == "reset" then
- for k, v in next, hash do
- if type(k) ~= "number" then
- hash[k] = nil
+ if h == "reset" then
+ for k, v in next, hash do
+ if type(k) ~= "number" then
+ hash[k] = nil
+ end
+ end
+ else
+ hash[h[1]] = h[2]
end
end
-else
- hash[h[1]] = h[2]
-end
- end
if trace_scripts then
report_scripts(table.serialize(hash,"prescript"))
end
return hash
end
+metapost.splitprescript = splitprescript
+
-- -- not used:
--
-- local function splitpostscript(script)
@@ -906,27 +708,9 @@ end
function metapost.resetplugins(t) -- intialize plugins, before figure
if top.plugmode then
-
outercolormodel = colors.currentmodel() -- currently overloads the one set at the tex end
-
- -- plugins can have been added
- resetter = resetteractions.runner
- analyzer = analyzeractions.runner
- processor = processoractions.runner
- -- let's apply one runner
- resetter(t)
- end
-end
-
-function metapost.analyzeplugins(object) -- each object (first pass)
- if top.plugmode then
- local prescript = object.prescript -- specifications
- if prescript and #prescript > 0 then
- analyzer(object,splitprescript(prescript) or {})
- return top.multipass
- end
+ resetteractions.runner(t)
end
- return false
end
function metapost.processplugins(object) -- each object (second pass)
@@ -935,7 +719,7 @@ function metapost.processplugins(object) -- each object (second pass)
if prescript and #prescript > 0 then
local before = { }
local after = { }
- processor(object,splitprescript(prescript) or {},before,after)
+ processoractions.runner(object,splitprescript(prescript) or {},before,after)
return #before > 0 and before, #after > 0 and after
else
local c = object.color
@@ -954,11 +738,16 @@ local basepoints = number.dimenfactors["bp"]
local function cm(object)
local op = object.path
if op then
- local first, second, fourth = op[1], op[2], op[4]
+ local first = op[1]
+ local second = op[2]
+ local fourth = op[4]
if fourth then
- local tx, ty = first.x_coord , first.y_coord
- local sx, sy = second.x_coord - tx, fourth.y_coord - ty
- local rx, ry = second.y_coord - ty, fourth.x_coord - tx
+ local tx = first.x_coord
+ local ty = first.y_coord
+ local sx = second.x_coord - tx
+ local sy = fourth.y_coord - ty
+ local rx = second.y_coord - ty
+ local ry = fourth.x_coord - tx
if sx == 0 then sx = 0.00001 end
if sy == 0 then sy = 0.00001 end
return sx, rx, ry, sy, tx, ty
@@ -967,6 +756,8 @@ local function cm(object)
return 1, 0, 0, 1, 0, 0 -- weird case
end
+metapost.cm = cm
+
-- color
local function cl_reset(t)
@@ -975,157 +766,195 @@ end
-- text
-local function tx_reset()
- if top then
- -- why ?
- top.texhash = { }
- top.texlast = 0
+local tx_reset, tx_process do
+
+ local eol = S("\n\r")^1
+ local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0)
+ local splitter = Ct(
+ ( (
+ P("s:") * C((1-eol)^1)
+ + P("n:") * ((1-eol)^1/tonumber)
+ + P("b:") * ((1-eol)^1/toboolean)
+ ) * eol^0 )^0)
+
+ local function applyformat(s)
+ local t = lpegmatch(splitter,s)
+ if #t == 1 then
+ return s
+ else
+ local f = lpegmatch(cleaner,t[1])
+ return formatters[f](unpack(t,2))
+ end
end
-end
-local fmt = formatters["%s %s %s % t"]
------ pat = tsplitat(":")
-local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work
-
-local f_gray_yes = formatters["s=%F,a=%F,t=%F"]
-local f_gray_nop = formatters["s=%F"]
-local f_rgb_yes = formatters["r=%F,g=%F,b=%F,a=%F,t=%F"]
-local f_rgb_nop = formatters["r=%F,g=%F,b=%F"]
-local f_cmyk_yes = formatters["c=%F,m=%F,y=%F,k=%F,a=%F,t=%F"]
-local f_cmyk_nop = formatters["c=%F,m=%F,y=%F,k=%F"]
-
-local ctx_MPLIBsetNtext = context.MPLIBsetNtext
-local ctx_MPLIBsetCtext = context.MPLIBsetCtext
-local ctx_MPLIBsettext = context.MPLIBsettext
-
--- we reuse content when possible
--- we always create at least one instance (for dimensions)
--- we make sure we don't do that when we use one (else counter issues with e.g. \definelabel)
-
-local eol = S("\n\r")^1
-local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0)
-local splitter = Ct(
- ( (
- P("s:") * C((1-eol)^1)
- + P("n:") * ((1-eol)^1/tonumber)
- + P("b:") * ((1-eol)^1/toboolean)
- ) * eol^0 )^0)
-
-local function applyformat(s)
- local t = lpegmatch(splitter,s)
- if #t == 1 then
- return s
- else
- local f = lpegmatch(cleaner,t[1])
- return formatters[f](unpack(t,2))
- end
-end
-
-local function tx_analyze(object,prescript)
- local data = top.texdata[metapost.properties.number]
- local tx_stage = prescript.tx_stage
- if tx_stage == "trial" then
- local tx_trial = data.textrial + 1
- data.textrial = tx_trial
- local tx_number = tonumber(prescript.tx_number)
- local s = object.postscript or ""
- local c = object.color -- only simple ones, no transparency
- if #c == 0 then
- local txc = prescript.tx_color
- if txc then
- c = lpegmatch(pat,txc)
+ local fmt = formatters["%s %s %s % t"]
+ ----- pat = tsplitat(":")
+ local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work
+
+ local f_gray_yes = formatters["s=%.3F,a=%i,t=%.3F"]
+ local f_gray_nop = formatters["s=%.3F"]
+ local f_rgb_yes = formatters["r=%.3F,g=%.3F,b=%.3F,a=%.3F,t=%.3F"]
+ local f_rgb_nop = formatters["r=%.3F,g=%.3F,b=%.3F"]
+ local f_cmyk_yes = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F,a=%.3F,t=%.3F"]
+ local f_cmyk_nop = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F"]
+
+ directives.register("metapost.stripzeros",function()
+ f_gray_yes = formatters["s=%.3N,a=%i,t=%.3N"]
+ f_gray_nop = formatters["s=%.3N"]
+ f_rgb_yes = formatters["r=%.3N,g=%.3N,b=%.3N,a=%.3N,t=%.3N"]
+ f_rgb_nop = formatters["r=%.3N,g=%.3N,b=%.3N"]
+ f_cmyk_yes = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N,a=%.3N,t=%.3N"]
+ f_cmyk_nop = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N"]
+ end)
+
+ local ctx_MPLIBsetNtext = context.MPLIBsetNtextX
+ local ctx_MPLIBsetCtext = context.MPLIBsetCtextX
+ local ctx_MPLIBsettext = context.MPLIBsettextX
+
+ local bp = number.dimenfactors.bp
+
+ local mp_index = 0
+ local mp_target = 0
+ local mp_c = nil
+ local mp_a = nil
+ local mp_t = nil
+
+ local function processtext()
+ local mp_text = top.texstrings[mp_index]
+ if not mp_text then
+ report_textexts("missing text for index %a",mp_index)
+ elseif not mp_c then
+ ctx_MPLIBsetNtext(mp_target,mp_text)
+ elseif #mp_c == 1 then
+ if mp_a and mp_t then
+ ctx_MPLIBsetCtext(mp_target,f_gray_yes(mp_c[1],mp_a,mp_t),mp_text)
+ else
+ ctx_MPLIBsetCtext(mp_target,f_gray_nop(mp_c[1]),mp_text)
end
- end
- if prescript.tx_type == "format" then
- s = applyformat(s)
- end
- local a = tonumber(prescript.tr_alternative)
- local t = tonumber(prescript.tr_transparency)
- local h = fmt(tx_number,a or "-",t or "-",c or "-")
- local n = data.texhash[h] -- todo: hashed variant with s (nicer for similar labels)
- if n then
- data.texslots[tx_trial] = n
- if trace_textexts then
- report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"old",n,h,s)
+ elseif #mp_c == 3 then
+ if mp_a and mp_t then
+ ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3],mp_a,mp_t),mp_text)
+ else
+ ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3]),mp_text)
end
- elseif prescript.tx_global == "yes" and data.texorder[tx_number] then
- -- we already have one flush and don't want it redone .. this needs checking
- if trace_textexts then
- report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"ignored",tx_last,h,s)
+ elseif #mp_c == 4 then
+ if mp_a and mp_t then
+ ctx_MPLIBsetCtext(mp_target,f_cmyk_yes(mp_c[1],mp_c[2],mp_c[3],mp_c[4],mp_a,mp_t),mp_text)
+ else
+ ctx_MPLIBsetCtext(mp_target,f_cmyk_nop(mp_c[1],mp_c[2],mp_c[3],mp_c[4]),mp_text)
end
else
- local tx_last = top.texlast + 1
- top.texlast = tx_last
- -- report_textexts("tex string: %s",s)
- if not c then
- ctx_MPLIBsetNtext(tx_last,s)
- elseif #c == 1 then
- if a and t then
- ctx_MPLIBsetCtext(tx_last,f_gray_yes(c[1],a,t),s)
- else
- ctx_MPLIBsetCtext(tx_last,f_gray_nop(c[1]),s)
- end
- elseif #c == 3 then
- if a and t then
- ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3],a,t),s)
- else
- ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3]),s)
- end
- elseif #c == 4 then
- if a and t then
- ctx_MPLIBsetCtext(tx_last,f_cmyk_yes(c[1],c[2],c[3],c[4],a,t),s)
- else
- ctx_MPLIBsetCtext(tx_last,f_cmyk_nop(c[1],c[2],c[3],c[4]),s)
- end
- else
- ctx_MPLIBsetNtext(tx_last,s)
+ -- can't happen
+ ctx_MPLIBsetNtext(mp_target,mp_text)
+ end
+ end
+
+ function mp.mf_some_text(index,str)
+ mp_target = index
+ mp_index = index
+ mp_c = nil
+ mp_a = nil
+ mp_t = nil
+ top.texstrings[mp_index] = str
+ tex.runtoks("mptexttoks")
+ local box = textakebox("mptextbox")
+ top.textexts[mp_target] = box
+ mp.triplet(bp*box.width,bp*box.height,bp*box.depth)
+ madetext = nil
+ end
+
+ local madetext = nil
+
+ function mp.mf_made_text(index)
+ mp.mf_some_text(index,madetext)
+ end
+
+ function metapost.maketext(s,mode)
+ if mode and mode == 1 then
+ if trace_btexetex then
+ report_metapost("ignoring verbatimtex: [[%s]]",s)
end
- top.multipass = true
- data.texhash [h] = tx_last
- -- data.texhash [tx_number] = tx_last
- data.texslots[tx_trial] = tx_last
- data.texorder[tx_number] = tx_last
- if trace_textexts then
- report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"new",tx_last,h,s)
+ else
+ if trace_btexetex then
+ report_metapost("handling btex ... etex: [[%s]]",s)
end
+ -- madetext = utilities.strings.collapse(s)
+ madetext = s
+ return "rawmadetext"
end
- elseif tx_stage == "extra" then
- local tx_trial = data.textrial + 1
- data.textrial = tx_trial
- local tx_number = tonumber(prescript.tx_number)
- if not data.texorder[tx_number] then
- local s = object.postscript or ""
- local tx_last = top.texlast + 1
- top.texlast = tx_last
- ctx_MPLIBsettext(tx_last,s)
- top.multipass = true
- data.texslots[tx_trial] = tx_last
- data.texorder[tx_number] = tx_last
- if trace_textexts then
- report_textexts("stage %a, usage %a, number %a, extra %a, text %a",tx_stage,tx_trial,tx_number,tx_last,s)
+ end
+
+ function mp.mf_formatted_text(index,fmt,...)
+ local t = { }
+ for i=1,select("#",...) do
+ local ti = select(i,...)
+ if type(ti) ~= "table" then
+ t[#t+1] = ti
end
end
+ local f = lpegmatch(cleaner,fmt)
+ local s = formatters[f](unpack(t)) or ""
+ mp.mf_some_text(index,s)
end
-end
-local function tx_process(object,prescript,before,after)
- local data = top.texdata[metapost.properties.number]
- local tx_number = tonumber(prescript.tx_number)
- if tx_number then
- local tx_stage = prescript.tx_stage
- if tx_stage == "final" then
- local tx_final = data.texfinal + 1
- data.texfinal = tx_final
- local n = data.texslots[tx_final]
+ interfaces.implement {
+ name = "mptexttoks",
+ actions = processtext,
+ }
+
+ tx_reset = function()
+ if top then
+ top.texhash = { }
+ top.texlast = 0
+ end
+ end
+
+ tx_process = function(object,prescript,before,after)
+ local data = top.texdata[metapost.properties.number]
+ local index = tonumber(prescript.tx_index)
+ if index then
if trace_textexts then
- report_textexts("stage %a, usage %a, number %a, use %a",tx_stage,tx_final,tx_number,n)
+ report_textexts("using index %a",index)
+ end
+ --
+ mp_c = object.color
+ if #mp_c == 0 then
+ local txc = prescript.tx_color
+ if txc then
+ mp_c = lpegmatch(pat,txc)
+ end
+ end
+ mp_a = tonumber(prescript.tr_alternative)
+ mp_t = tonumber(prescript.tr_transparency)
+ --
+ mp_index = index
+ mp_target = top.texlast - 1
+ top.texlast = mp_target
+ --
+ local mp_text = top.texstrings[mp_index]
+ local box
+ if prescript.tx_cache == "no" then
+ tex.runtoks("mptexttoks")
+ box = textakebox("mptextbox")
+ else
+ local hash = fmt(mp_text,mp_a or "-",mp_t or "-",mp_c or "-")
+ box = data.texhash[hash]
+ if box then
+ box = copy_list(box)
+ else
+ tex.runtoks("mptexttoks")
+ box = textakebox("mptextbox")
+ data.texhash[hash] = box
+ end
end
- local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function
- local box = top.textexts[n]
+ top.textexts[mp_target] = box
+ --
if box then
+ -- we need to freeze the variables outside the function
+ local sx, rx, ry, sy, tx, ty = cm(object)
+ local target = mp_target
before[#before+1] = function()
- -- flush always happens, we can have a special flush function injected before
- context.MPLIBgettextscaledcm(n,
+ context.MPLIBgettextscaledcm(target,
f_f(sx), -- bah ... %s no longer checks
f_f(rx), -- bah ... %s no longer checks
f_f(ry), -- bah ... %s no longer checks
@@ -1136,7 +965,7 @@ local function tx_process(object,prescript,before,after)
end
else
before[#before+1] = function()
- report_textexts("unknown %s",tx_number)
+ report_textexts("unknown %s",index)
end
end
if not trace_textexts then
@@ -1147,6 +976,7 @@ local function tx_process(object,prescript,before,after)
object.istext = true
end
end
+
end
-- we could probably redo normal textexts in the next way but as it's rather optimized
@@ -1182,30 +1012,31 @@ end
-- graphics (we use the given index because pictures can be reused)
-local graphics = { }
-function metapost.intermediate.actions.makempy()
- if #graphics > 0 then
- makempy.processgraphics(graphics)
- graphics = { } -- ? could be gt_reset
- end
-end
+local gt_reset, gt_process do
+
+ local graphics = { }
-local function gt_analyze(object,prescript)
- local gt_stage = prescript.gt_stage
- local gt_index = tonumber(prescript.gt_index)
- if gt_stage == "trial" and not graphics[gt_index] then
- graphics[gt_index] = formatters["\\MPLIBgraphictext{%s}"](object.postscript or "")
- top.intermediate = true
- top.multipass = true
+
+ local mp_index = 0
+ local mp_str = ""
+
+ function mp.mf_graphic_text(index,str)
+ if not graphics[index] then
+ mp_index = index
+ mp_str = str
+ tex.runtoks("mpgraphictexttoks")
+ end
end
-end
--- local function gt_process(object,prescript,before,after)
--- local gt_stage = prescript.gt_stage
--- if gt_stage == "final" then
--- end
--- end
+ interfaces.implement {
+ name = "mpgraphictexttoks",
+ actions = function()
+ context.MPLIBgraphictext(mp_index,mp_str)
+ end,
+ }
+
+end
-- shades
@@ -1342,7 +1173,7 @@ end
local function bm_process(object,prescript,before,after)
local bm_xresolution = prescript.bm_xresolution
if bm_xresolution then
- before[#before+1] = f_cm(cm(object))
+ before[#before+1] = f_cm_b(cm(object))
before[#before+1] = function()
figures.bitmapimage {
xresolution = tonumber(bm_xresolution),
@@ -1352,7 +1183,7 @@ local function bm_process(object,prescript,before,after)
data = object.postscript
}
end
- before[#before+1] = "Q"
+ before[#before+1] = s_cm_e
object.path = false
object.color = false
object.grouped = true
@@ -1364,10 +1195,13 @@ end
local function ps_process(object,prescript,before,after)
local ps_label = prescript.ps_label
if ps_label then
- local op = object.path
- local first, third = op[1], op[3]
- local x, y = first.x_coord, first.y_coord
- local w, h = third.x_coord - x, third.y_coord - y
+ local op = object.path
+ local first = op[1]
+ local third = op[3]
+ local x = first.x_coord
+ local y = first.y_coord
+ local w = third.x_coord - x
+ local h = third.y_coord - y
local properties = metapost.properties
x = x - properties.llx
y = properties.ury - y
@@ -1380,14 +1214,33 @@ end
-- figures
+-- local sx, rx, ry, sy, tx, ty = cm(object)
+-- sxsy(box.width,box.height,box.depth))
+
+function mp.mf_external_figure(filename)
+ local f = figures.getinfo(filename)
+ local w = 0
+ local h = 0
+ if f then
+ local u = f.used
+ if u and u.fullname then
+ w = u.width or 0
+ h = u.height or 0
+ end
+ else
+ report_metapost("external figure %a not found",filename)
+ end
+ mp.triplet(w/65536,h/65536,0)
+end
+
local function fg_process(object,prescript,before,after)
local fg_name = prescript.fg_name
if fg_name then
- before[#before+1] = f_cm(cm(object)) -- beware: does not use the cm stack
+ before[#before+1] = f_cm_b(cm(object)) -- beware: does not use the cm stack
before[#before+1] = function()
context.MPLIBfigure(fg_name,prescript.fg_mask or "")
end
- before[#before+1] = "Q"
+ before[#before+1] = s_cm_e
object.path = false
object.grouped = true
end
@@ -1411,14 +1264,27 @@ local remappers = {
[4] = formatters["c=%s,m=%s,y=%s,k=%s"],
}
+local processlast = 0
+local processhash = setmetatableindex(function(t,k)
+ processlast = processlast + 1
+ local v = formatters["mp_%s"](processlast)
+ defineprocesscolor(v,k,true,true)
+ t[k] = v
+ return v
+end)
+
+local function checked_transparency(alternative,transparency,before,after)
+ alternative = tonumber(alternative) or 1
+ transparency = tonumber(transparency) or 0
+ before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,alternative,transparency,true))
+ after [#after +1] = "/Tr0 gs" -- outertransparency
+end
+
local function tr_process(object,prescript,before,after)
-- before can be shortcut to t
local tr_alternative = prescript.tr_alternative
if tr_alternative then
- tr_alternative = tonumber(tr_alternative)
- local tr_transparency = tonumber(prescript.tr_transparency)
- before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,tr_alternative,tr_transparency,true))
- after[#after+1] = "/Tr0 gs" -- outertransparency
+ checked_transparency(tr_alternative,prescript.tr_transparency,before,after)
end
local cs = object.color
if cs and #cs > 0 then
@@ -1429,29 +1295,35 @@ local function tr_process(object,prescript,before,after)
else
local sp_name = prescript.sp_name or "black"
if sp_type == "spot" then
- local sp_value = prescript.sp_value or "s:1"
- local sp_temp = formatters["mp:%s"](sp_value)
- local s = split(sp_value,":")
- local r = remappers[#s]
- defineprocesscolor(sp_temp,r and r(unpack(s)) or "s=0",true,true)
- definespotcolor(sp_name,sp_temp,"p=1",true)
+ local sp_value = prescript.sp_value or "1"
+ local components = split(sp_value,":")
+ local specification = remappers[#components]
+ if specification then
+ specification = specification(unpack(components))
+ else
+ specification = "s=0"
+ end
+ local sp_spec = processhash[specification]
+ definespotcolor(sp_name,sp_spec,"p=1",true)
sp_type = "named"
elseif sp_type == "multitone" then -- (fractions of a multitone) don't work well in mupdf
- local sp_value = prescript.sp_value or "s:1"
- local sp_spec = { }
+ local sp_value = prescript.sp_value or "1"
+ local sp_specs = { }
local sp_list = split(sp_value," ")
for i=1,#sp_list do
- local v = sp_list[i]
- local t = formatters["mp:%s"](v)
- local s = split(v,":")
- local r = remappers[#s]
- defineprocesscolor(t,r and r(unpack(s)) or "s=0",true,true)
- local tt = formatters["ms:%s"](v)
- definespotcolor(tt,t,"p=1",true)
- sp_spec[#sp_spec+1] = formatters["%s=1"](t)
+ local sp_value = sp_list[i]
+ local components = split(sp_value,":")
+ local specification = remappers[#components]
+ if specification then
+ specification = specification(unpack(components))
+ else
+ specification = "s=0"
+ end
+ local sp_spec = processhash[specification]
+ sp_specs[i] = formatters["%s=1"](sp_spec)
end
- sp_spec = concat(sp_spec,",")
- definemultitonecolor(sp_name,sp_spec,"","",true)
+ sp_specs = concat(sp_specs,",")
+ definemultitonecolor(sp_name,sp_specs,"","")
sp_type = "named"
end
if sp_type == "named" then
@@ -1463,8 +1335,7 @@ local function tr_process(object,prescript,before,after)
local t = t_list[sp_name] -- string or attribute
local v = t and transparencyvalue(t)
if v then
- before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,v[1],v[2],true))
- after[#after+1] = "/Tr0 gs" -- outertransparency
+ checked_transparency(v[1],v[2],before,after)
end
end
local c = c_list[sp_name] -- string or attribute
@@ -1472,29 +1343,34 @@ local function tr_process(object,prescript,before,after)
if v then
-- all=1 gray=2 rgb=3 cmyk=4
local colorspace = v[1]
- local f = cs[1]
+ local factor = cs[1]
if colorspace == 2 then
- local s = f*v[2]
+ local s = factor * v[2]
c_b, c_a = checked_color_pair(f_gray,s,s)
elseif colorspace == 3 then
- local r, g, b = f*v[3], f*v[4], f*v[5]
+ local r = factor * v[3]
+ local g = factor * v[4]
+ local b = factor * v[5]
c_b, c_a = checked_color_pair(f_rgb,r,g,b,r,g,b)
elseif colorspace == 4 or colorspace == 1 then
- local c, m, y, k = f*v[6], f*v[7], f*v[8], f*v[9]
+ local c = factor * v[6]
+ local m = factor * v[7]
+ local y = factor * v[8]
+ local k = factor * v[9]
c_b, c_a = checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k)
elseif colorspace == 5 then
-- not all viewers show the fractions ok
local name = v[10]
local value = split(v[13],",")
- if f ~= 1 then
+ if factor ~= 1 then
for i=1,#value do
- value[i] = f * (tonumber(value[i]) or 1)
+ value[i] = f_scn(factor * (tonumber(value[i]) or 1))
end
end
value = concat(value," ")
c_b, c_a = checked_color_pair(f_spot,name,name,value,value)
else
- local s = f*v[2]
+ local s = factor *v[2]
c_b, c_a = checked_color_pair(f_gray,s,s)
end
end
@@ -1519,10 +1395,6 @@ end
-- groups
-local types = {
- isolated
-}
-
local function gr_process(object,prescript,before,after)
local gr_state = prescript.gr_state
if not gr_state then
@@ -1530,7 +1402,10 @@ local function gr_process(object,prescript,before,after)
elseif gr_state == "start" then
local gr_type = utilities.parsers.settings_to_set(prescript.gr_type)
local path = object.path
- local p1, p2, p3, p4 = path[1], path[2], path[3], path[4]
+ local p1 = path[1]
+ local p2 = path[2]
+ local p3 = path[3]
+ local p4 = path[4]
local llx = min(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord)
local lly = min(p1.y_coord,p2.y_coord,p3.y_coord,p4.y_coord)
local urx = max(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord)
@@ -1554,82 +1429,88 @@ end
-- outlines
-local outlinetexts = { }
+local ot_reset, ot_process do
-local function ot_reset()
- outlinetexts = { }
-end
+ local outlinetexts = { } -- also in top data
-local function ot_analyze(object,prescript)
- local ot_stage = prescript.ot_stage
- local ot_index = tonumber(prescript.ot_index)
- if ot_index and ot_stage == "trial" and not outlinetexts[ot_index] then
- local ot_kind = prescript.ot_kind or ""
- top.intermediate = true
- top.multipass = true
- context.MPLIBoutlinetext(ot_index,ot_kind,object.postscript)
+ ot_reset = function ()
+ outlinetexts = { }
end
-end
-local function ot_process(object,prescript,before,after)
-end
+ local mp_index = 0
+ local mp_kind = ""
+ local mp_str = ""
-implement {
- name = "MPLIBconvertoutlinetext",
- arguments = { "integer", "string", "integer" },
- actions = function(index,kind,box)
- local boxtomp = fonts.metapost.boxtomp
- if boxtomp then
- outlinetexts[index] = boxtomp(box,kind)
- else
- outlinetexts[index] = ""
+ function mp.mf_outline_text(index,str,kind)
+ if not outlinetexts[index] then
+ mp_index = index
+ mp_kind = kind
+ mp_str = str
+ tex.runtoks("mpoutlinetoks")
end
end
-}
-function mp.get_outline_text(index) -- maybe we need a more private namespace
- mp.print(outlinetexts[index] or "draw origin;")
-end
+ interfaces.implement {
+ name = "mpoutlinetoks",
+ actions = function()
+ context.MPLIBoutlinetext(mp_index,mp_kind,mp_str)
+ end,
+ }
+ implement {
+ name = "MPLIBconvertoutlinetext",
+ arguments = { "integer", "string", "integer" },
+ actions = function(index,kind,box)
+ local boxtomp = fonts.metapost.boxtomp
+ if boxtomp then
+ outlinetexts[index] = boxtomp(box,kind)
+ else
+ outlinetexts[index] = ""
+ end
+ end
+ }
--- definitions
+ function mp.mf_get_outline_text(index) -- maybe we need a more private namespace
+ mp.print(outlinetexts[index] or "draw origin;")
+ end
-appendaction(resetteractions, "system",ot_reset)
-appendaction(resetteractions, "system",cl_reset)
-appendaction(resetteractions, "system",tx_reset)
+end
-appendaction(processoractions,"system",ot_process)
-appendaction(processoractions,"system",gr_process)
+-- mf_object=
-appendaction(analyzeractions, "system",ot_analyze)
-appendaction(analyzeractions, "system",tx_analyze)
-appendaction(analyzeractions, "system",gt_analyze)
+local p1 = P("mf_object=")
+local p2 = lpeg.patterns.eol * p1
+local pattern = (1-p2)^0 * p2 + p1
-appendaction(processoractions,"system",sh_process)
--- (processoractions,"system",gt_process)
-appendaction(processoractions,"system",bm_process)
-appendaction(processoractions,"system",tx_process)
-appendaction(processoractions,"system",bx_process)
-appendaction(processoractions,"system",ps_process)
-appendaction(processoractions,"system",fg_process)
-appendaction(processoractions,"system",tr_process) -- last, as color can be reset
+function metapost.isobject(str)
+ return pattern and str ~= "" and lpegmatch(p,str) and true or false
+end
-appendaction(processoractions,"system",la_process)
+local function installplugin(specification)
+ local reset = specification.reset
+ local process = specification.process
+ local object = specification.object
+ if reset then
+ appendaction(resetteractions,"system",reset)
+ end
+ if process then
+ appendaction(processoractions,"system",process)
+ end
+end
--- function metapost.installplugin(reset,analyze,process)
--- if reset then
--- appendaction(resetteractions,"system",reset)
--- end
--- if analyze then
--- appendaction(analyzeractions,"system",analyze)
--- end
--- if process then
--- appendaction(processoractions,"system",process)
--- end
--- end
+metapost.installplugin = installplugin
--- we're nice and set them already
+-- definitions
-resetter = resetteractions .runner
-analyzer = analyzeractions .runner
-processor = processoractions.runner
+installplugin { name = "outline", reset = ot_reset, process = ot_process }
+installplugin { name = "color", reset = cl_reset, process = cl_process }
+installplugin { name = "text", reset = tx_reset, process = tx_process }
+installplugin { name = "group", reset = gr_reset, process = gr_process }
+installplugin { name = "graphictext", reset = gt_reset, process = gt_process }
+installplugin { name = "shade", reset = sh_reset, process = sh_process }
+installplugin { name = "bitmap", reset = bm_reset, process = bm_process }
+installplugin { name = "box", reset = bx_reset, process = bx_process }
+installplugin { name = "position", reset = ps_reset, process = ps_process }
+installplugin { name = "figure", reset = fg_reset, process = fg_process }
+installplugin { name = "layer", reset = la_reset, process = la_process }
+installplugin { name = "transparency", reset = tr_reset, process = tr_process }
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.mkiv
index c9d181bf976..05113058511 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-pps.mkiv
@@ -57,14 +57,36 @@
\let\MPLIBsettext\MPLIBsetNtext
+\unexpanded\def\MPLIBsetNtextX#1% #2% box text
+ {\MPLIBflushenvironment
+ \hbox\bgroup % text
+ \meta_set_current_color
+ \let\MPLIBflushenvironment\doMPLIBflushenvironment
+ \let\next}
+
+\unexpanded\def\MPLIBsetCtextX#1#2% #3% box colorspec text
+ {\MPLIBflushenvironment
+ \hbox\bgroup % text
+ \directcolored[#2]%
+ \meta_set_current_color % so, textcolor wins !
+ \let\MPLIBflushenvironment\doMPLIBflushenvironment
+ \let\next}
+
+\let\MPLIBsettextX\MPLIBsetNtextX
+
\unexpanded\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often
{\clf_mpgettext\MPtextbox #1%
\vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}}
+% \unexpanded\def\MPLIBfigure#1#2%
+% {\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}%
+% \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint
+% \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}}
+
\unexpanded\def\MPLIBfigure#1#2%
{\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}%
\clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint
- \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}}
+ \vpack to \zeropoint{\vss\hpack to \zeropoint{\fastsxsy{\sx}{\sy}{\box\scratchbox}\hss}}}
% horrible (we could inline scale and matrix code):
@@ -185,4 +207,15 @@
\setbox\scratchbox\hpack\bgroup
\unexpanded\def\MPLIBstopgroup{\doMPLIBstopgroup{#1}{#2}{#3}{#4}{#5}{#6}}}
+% For now here ... will be cleaned up:
+
+\newtoks\mptexttoks
+\newbox \mptextbox
+\newtoks\mpoutlinetoks
+\newtoks\mpgraphictexttoks
+
+\mptexttoks {\global\setbox\mptextbox\hbox{\clf_mptexttoks}}
+\mpoutlinetoks {\global\setbox\mptextbox\vbox{\clf_mpoutlinetoks}}
+\mpgraphictexttoks{\global\setbox\mptextbox\vbox{\clf_mpgraphictexttoks}}
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-run.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-run.lua
index 18bc7e4da11..670c0e16b35 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-run.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-run.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['mlib-run'] = {
license = "see context related readme files",
}
+-- todo mpx :execute -> mlib.execute(mpx,)
+
-- cmyk -> done, native
-- spot -> done, but needs reworking (simpler)
-- multitone ->
@@ -30,7 +32,6 @@ nears zero.
--ldx]]--
local type, tostring, tonumber, next = type, tostring, tonumber, next
-local gsub, match, find = string.gsub, string.match, string.find
local striplines = utilities.strings.striplines
local concat, insert, remove = table.concat, table.insert, table.remove
@@ -70,20 +71,6 @@ end
----- mpbasepath = lpeg.instringchecker(lpeg.append { "/metapost/context/", "/metapost/base/" })
local mpbasepath = lpeg.instringchecker(P("/metapost/") * (P("context") + P("base")) * P("/"))
--- local function i_finder(askedname,mode,ftype) -- fake message for mpost.map and metafun.mpvi
--- local foundname = file.is_qualified_path(askedname) and askedname or resolvers.findfile(askedname,ftype)
--- if not mpbasepath(foundname) then
--- -- we could use the via file but we don't have a complete io interface yet
--- local data, found, forced = metapost.checktexts(io.loaddata(foundname) or "")
--- if found then
--- local tempname = luatex.registertempfile(foundname,true)
--- io.savedata(tempname,data)
--- foundname = tempname
--- end
--- end
--- return foundname
--- end
-
-- mplib has no real io interface so we have a different mechanism than
-- tex (as soon as we have more control, we will use the normal code)
--
@@ -97,21 +84,6 @@ do
local new_instance = mplib.new
- local function preprocessed(name)
- if not mpbasepath(name) then
- -- we could use the via file but we don't have a complete io interface yet
- local data, found, forced = metapost.checktexts(io.loaddata(name) or "")
- if found then
- local temp = luatex.registertempfile(name,true)
- io.savedata(temp,data)
- return temp
- end
- end
- return name
- end
-
- mplib.preprocessed = preprocessed -- helper
-
local function validftype(ftype)
if ftype == "" then
-- whatever
@@ -123,14 +95,13 @@ do
end
finders.file = function(specification,name,mode,ftype)
- return preprocessed(resolvers.findfile(name,validftype(ftype)))
+ return resolvers.findfile(name,validftype(ftype))
end
local function i_finder(name,mode,ftype) -- fake message for mpost.map and metafun.mpvi
local specification = url.hashed(name)
local finder = finders[specification.scheme] or finders.file
local found = finder(specification,name,mode,validftype(ftype))
- -- print(found)
return found
end
@@ -160,7 +131,9 @@ function metapost.reporterror(result)
if not result then
report_metapost("error: no result object returned")
elseif result.status > 0 then
- local t, e, l = result.term, result.error, result.log
+ local t = result.term
+ local e = result.error
+ local l = result.log
local report = metapost.texerrors and texerrormessage or report_metapost
if t and t ~= "" then
report("mp error: %s",striplines(t))
@@ -193,7 +166,8 @@ local f_preamble = formatters [ [[
local methods = {
double = "double",
scaled = "scaled",
- binary = "binary",
+ -- binary = "binary",
+ binary = "double",
decimal = "decimal",
default = "scaled",
}
@@ -208,18 +182,6 @@ end
-- todo: random_seed
-local f_textext = formatters[ [[rawtextext("%s")]] ]
-
-function metapost.maketext(s,mode)
- if mode and mode == 1 then
- -- report_metapost("ignoring verbatimtex: %s",s)
- else
- -- report_metapost("handling btex ... etex: %s",s)
- s = gsub(s,'"','"&ditto&"')
- return f_textext(s)
- end
-end
-
local seed = nil
function metapost.load(name,method)
@@ -291,24 +253,103 @@ function metapost.unload(mpx)
stoptiming(mplib)
end
-local mpxformats = { }
+-- The flatten hack is needed because the library currently barks on \n\n and the
+-- collapse because mp cannot handle snippets due to grouping issues.
+
+local function flatten(source,target)
+ for i=1,#source do
+ local d = source[i]
+ if type(d) == "table" then
+ flatten(d,target)
+ elseif d and d ~= "" then
+ target[#target+1] = d
+ end
+ end
+ return target
+end
+
+local function prepareddata(data,collapse)
+ if data and data ~= "" then
+ if type(data) == "table" then
+ data = flatten(data,{ })
+ if collapse then
+ data = #data > 1 and concat(data,"\n") or data[1]
+ end
+ end
+ return data
+ end
+end
+
+metapost.defaultformat = "metafun"
+metapost.defaultinstance = "metafun"
+metapost.defaultmethod = "default"
-function metapost.format(instance,name,method)
+local mpxformats = { }
+local nofformats = 0
+local mpxpreambles = { }
+
+function metapost.pushformat(specification,f,m) -- was: instance, name, method
+ if type(specification) ~= "table" then
+ specification = {
+ instance = specification,
+ format = f,
+ method = m,
+ }
+ end
+ local instance = specification.instance
+ local format = specification.format
+ local method = specification.method
+ local definitions = specification.definitions
+ local extensions = specification.extensions
+ local preamble = nil
if not instance or instance == "" then
- instance = "metafun" -- brrr
+ instance = metapost.defaultinstance
+ specification.instance = instance
+ end
+ if not format or format == "" then
+ format = metapost.defaultformat
+ specification.format = format
+ end
+ if not method or method == "" then
+ method = metapost.defaultmethod
+ specification.method = method
+ end
+ if definitions and definitions ~= "" then
+ preamble = definitions
+ end
+ if extensions and extensions ~= "" then
+ if preamble then
+ preamble = preamble .. "\n" .. extensions
+ else
+ preamble = extensions
+ end
+ end
+ nofformats = nofformats + 1
+ local usedinstance = instance .. ":" .. nofformats
+ local mpx = mpxformats[usedinstance]
+ local mpp = mpxpreambles[instance] or ""
+ if preamble then
+ preamble = prepareddata(preamble,true)
+ mpp = mpp .. "\n" .. preamble
+ mpxpreambles[instance] = mpp
end
- name = name or instance
- local mpx = mpxformats[instance]
if not mpx then
- report_metapost("initializing instance %a using format %a",instance,name)
- mpx = metapost.checkformat(name,method)
- mpxformats[instance] = mpx
+ report_metapost("initializing instance %a using format %a and method %a",usedinstance,format,method)
+ mpx = metapost.checkformat(format,method)
+ mpxformats[usedinstance] = mpx
+ if mpp ~= "" then
+ preamble = mpp
+ end
+ end
+ if preamble then
+ mpx:execute(preamble)
end
+ specification.mpx = mpx
return mpx
end
-function metapost.instance(instance)
- return mpxformats[instance]
+function metapost.popformat()
+ nofformats = nofformats - 1
end
function metapost.reset(mpx)
@@ -335,10 +376,6 @@ local mp_tag = 0
-- key/values
-if not metapost.initializescriptrunner then
- function metapost.initializescriptrunner() end
-end
-
do
local stack, top = { }, nil
@@ -379,16 +416,47 @@ do
end
-function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig)
- local converted, result = false, { }
- if type(mpx) == "string" then
- mpx = metapost.format(mpx) -- goody
+
+if not metapost.process then
+
+ function metapost.process(specification)
+ metapost.run(specification)
+ end
+
+end
+
+-- run, process, convert and flush all work with a specification with the
+-- following (often optional) fields
+--
+-- mpx string or mp object
+-- data string or table of strings
+-- flusher table with flush methods
+-- askedfig string ("all" etc) or number
+-- incontext boolean
+-- plugmode boolean
+
+local function makebeginbanner(specification)
+ return formatters["%% begin graphic: n=%s\n\n"](metapost.n)
+end
+
+local function makeendbanner(specification)
+ return "\n% end graphic\n\n"
+end
+
+function metapost.run(specification)
+ local mpx = specification.mpx
+ local data = specification.data
+ local converted = false
+ local result = { }
+ local mpxdone = type(mpx) == "string"
+ if mpxdone then
+ mpx = metapost.pushformat { instance = mpx, format = mpx }
end
if mpx and data then
local tra = nil
starttiming(metapost)
- metapost.variables = { }
- metapost.initializescriptrunner(mpx,trialrun)
+ metapost.variables = { } -- todo also push / pop
+ metapost.pushscriptrunner(mpx)
if trace_graphics then
tra = mp_tra[mpx]
if not tra then
@@ -400,39 +468,12 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
}
mp_tra[mpx] = tra
end
- local banner = formatters["%% begin graphic: n=%s, trialrun=%s, multipass=%s, isextrapass=%s\n\n"](
- metapost.n, tostring(trialrun), tostring(multipass), tostring(isextrapass))
+ local banner = makebeginbanner(specification)
tra.inp:write(banner)
tra.log:write(banner)
end
- if type(data) == "table" then
- -- this hack is needed because the library currently barks on \n\n
- -- eventually we can text for "" in the next loop
- local n = 0
- local nofsnippets = #data
- for i=1,nofsnippets do
- local d = data[i]
- if d ~= "" then
- n = n + 1
- data[n] = d
- end
- end
- for i=nofsnippets,n+1,-1 do
- data[i] = nil
- end
- -- and this one because mp cannot handle snippets due to grouping issues
- if metapost.collapse then
- if #data > 1 then
- data = concat(data,"\n")
- else
- data = data[1]
- end
- end
- -- end of hacks
- end
-
+ local data = prepareddata(data,metapost.collapse)
local function process(d,i)
- -- d = string.gsub(d,"\r","")
if d then
if trace_graphics then
if i then
@@ -444,7 +485,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
end
end
starttiming(metapost.exectime)
- result = mpx:execute(d) -- some day we wil use a coroutine with textexts
+ result = mpx:execute(d)
stoptiming(metapost.exectime)
if trace_graphics and result then
local str = result.log or result.error
@@ -461,7 +502,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
end
end
if result.fig then
- converted = metapost.convert(result, trialrun, flusher, multipass, askedfig)
+ converted = metapost.convert(specification,result)
end
end
elseif i then
@@ -475,7 +516,6 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
if trace_tracingall then
mpx:execute("tracingall;")
end
- -- table.insert(data,2,"")
for i=1,#data do
process(data[i],i)
end
@@ -486,17 +526,25 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
process(data)
end
if trace_graphics then
- local banner = "\n% end graphic\n\n"
+ local banner = makeendbanner(specification)
tra.inp:write(banner)
tra.log:write(banner)
end
stoptiming(metapost)
+ metapost.popscriptrunner(mpx)
+ end
+ if mpxdone then
+ metapost.popformat()
end
return converted, result
end
-function metapost.convert()
- report_metapost('warning: no converter set')
+if not metapost.convert then
+
+ function metapost.convert()
+ report_metapost('warning: no converter set')
+ end
+
end
-- handy
@@ -564,7 +612,7 @@ end
-- goodie
-function metapost.quickanddirty(mpxformat,data,plugmode)
+function metapost.quickanddirty(mpxformat,data,incontext)
if not data then
mpxformat = "metafun"
data = mpxformat
@@ -584,7 +632,14 @@ function metapost.quickanddirty(mpxformat,data,plugmode)
end
}
local data = formatters["; beginfig(1) ;\n %s\n ; endfig ;"](data)
- metapost.process(mpxformat, { data }, false, flusher, false, false, "all", plugmode)
+ metapost.process {
+ mpx = mpxformat,
+ flusher = flusher,
+ askedfig = "all",
+ useplugins = incontext,
+ incontext = incontext,
+ data = { data },
+ }
if code then
return {
bbox = bbox or { 0, 0, 0, 0 },
@@ -619,7 +674,6 @@ do
local width = 0
local height = 0
local depth = 0
- local mpx = false
local flusher = {
startfigure = function(n,llx,lly,urx,ury)
@@ -637,13 +691,18 @@ do
end
}
- function metapost.simple(format,code) -- even less than metapost.quickcanddirty
- local mpx = metapost.format(format or "metafun","metafun")
+ function metapost.simple(format,code) -- even less than metapost.quickcanddirty
+ local mpx = metapost.pushformat { } -- takes defaults
-- metapost.setoutercolor(2)
- metapost.process(mpx,
- { "beginfig(1);", code, "endfig;" },
- false, flusher, false, false, 1, true -- last true is plugmode !
- )
+ metapost.process {
+ mpx = mpx,
+ flusher = flusher,
+ askedfig = 1,
+ useplugins = false,
+ incontext = false,
+ data = { "beginfig(1);", code, "endfig;" },
+ }
+ metapost.popformat()
if result then
local stream = concat(result," ")
result = nil -- cleanup
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-domotica.tex b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-domotica.tex
index 83562ee30cf..5a162893be3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-domotica.tex
+++ b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-domotica.tex
@@ -29,7 +29,9 @@
%
% example: context --extra=domotica --openzwave ./config/fibaro/fgms.xml ./open-zwave-master/config/aeotec/zw100.xml
% example: context --extra=domotica --openzwave --pattern="./open-zwave-master/config/**.xml"
-% example: context --extra=domotica --hue hue-pragma-tasks.lua
+% example: context --extra=domotica --hue hue-pragma-tasks.lua
+% example: context --extra=domotica --hue pragma-youless-gas.lua --year=2018 --month=8
+% example: context --extra=domotica --hue pragma-youless-electricity.lua
%
% end help
@@ -161,8 +163,11 @@
\stopmode
+
\startmode[hue]
+ \usemodule[youless]
+
\starttext
\setupheadertexts
@@ -171,10 +176,22 @@
local arguments = document.arguments
local files = document.files
- local pattern = arguments.pattern
local filename = files[1]
-
- if filename then
+ local pattern = arguments.pattern
+ local year = arguments.year
+ local month = arguments.month
+
+ local action = (arguments.tasks and "task")
+ or (arguments.graphics and "graphics")
+ or (string.find(filename,"tasks") and "tasks")
+ or (string.find(filename,"electricity") and "graphics")
+ or (string.find(filename,"pulse") and "graphics")
+ or (string.find(filename,"gas") and "graphics")
+
+ if not filename or filename == "" then
+ logs.report("youless","provide filename")
+ context("no files given")
+ elseif action == "tasks" then
context.starttitle { title = "Hue: " .. file.nameonly(filename) }
filename = file.addsuffix(filename,"lua")
if lfs.isfile(filename) then
@@ -183,9 +200,11 @@
context("unknown file %a",filename)
end
context.stoptitle()
+ elseif action == "graphics" then
+ moduledata.youless.graphics { year = year, month = month, filename = filename }
else
- context("no files given")
- context.stoptitle()
+ logs.report("youless","provide --status or --graphics")
+ context("no action given")
end
\stopluacode
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-fonts.tex b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-fonts.tex
new file mode 100644
index 00000000000..f1f74c9e9ae
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-fonts.tex
@@ -0,0 +1,98 @@
+%D \module
+%D [ file=mtx-context-fonts,
+%D version=2018.10.10,
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Show Font Info,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% begin help
+%
+% usage: context --extra=fonts [options] name
+%
+% --topspace=dimension : distance above first line
+% --backspace=dimension : distance before left margin
+% --paperformat=spec : paper*print or paperxprint
+% --compact : small margins, 8pt font
+% --verycompact : small margins, 7pt font
+%
+% example: context --extra=fonts --name=dejavu-serif
+% end help
+
+\input mtx-context-common.tex
+
+\usemodule[fonts-charts]
+\usemodule[fonts-tables]
+
+\input mtx-context-common.tex
+
+\doifdocumentargument {compact} {
+ \setdocumentargument{topspace} {5mm}
+ \setdocumentargument{backspace}{5mm}
+ \setdocumentargument{bodyfont} {8pt}
+}
+
+\doifdocumentargument {verycompact} {
+ \setdocumentargument{topspace} {5mm}
+ \setdocumentargument{backspace}{5mm}
+ \setdocumentargument{bodyfont} {7pt}
+}
+
+\setupbodyfont
+ [dejavu,9pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete
+
+\setuplayout
+ [header=0cm,
+ footer=1.5cm,
+ topspace=\getdocumentargumentdefault{topspace}{1.5cm},
+ backspace=\getdocumentargumentdefault{backspace}{1.5cm},
+ width=middle,
+ height=middle]
+
+\setuppapersize
+ [\getdocumentargument{paperformat_paper}]
+ [\getdocumentargument{paperformat_print}]
+
+\starttexdefinition unexpanded showfontdetails [#1]
+ \starttitle[title=#1]
+ \startsubject[title=Properties]
+ \showfontproperties[#1]
+ \stopsubject
+ \startsubject[title=Parameters]
+ \showfontparameters[#1]
+ \stopsubject
+ \startsubject[title=Positionings]
+ \showfontpositionings[#1]
+ \stopsubject
+ \startsubject[title=Substitutions]
+ \showfontsubstitutions[#1]
+ \stopsubject
+ \startsubject[title=Unicodevariants]
+ \showfontunicodevariants[#1]
+ \stopsubject
+ \startsubject[title=Ligatures]
+ \showfontligatures[#1]
+ \stopsubject
+ \showfontchart[#1,page=yes]
+ \stoptitle
+\stoptexdefinition
+
+\starttext
+
+ \startluacode
+ local files = document.files
+ if #files > 0 then
+ for i=1,#files do
+ context.showfontdetails { name = files[i] .. "*default" }
+ end
+ else
+ context("No font name(s) given.")
+ end
+ \stopluacode
+
+\stoptext
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-listing.tex b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-listing.tex
index f7c3d28680c..1053e80b9c3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-listing.tex
+++ b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-listing.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D This is a \TEXEXEC\ features that has been moved to \MKIV.
+%D This is a \TEXEXEC\ feature that has been moved to \MKIV.
% begin help
%
@@ -44,7 +44,7 @@
}
\setupbodyfont
- [dejavu,11pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete
+ [dejavu,9pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete
\setuptyping
[lines=yes]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-xml.tex b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-xml.tex
index f8bfeef3a6e..875f02da696 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mtx-context-xml.tex
+++ b/Master/texmf-dist/tex/context/base/mkiv/mtx-context-xml.tex
@@ -76,6 +76,11 @@
if template then
moduledata.xml.analyzers.allsetups(files,type(template) == "string" and template or nil)
end
+ context.page()
+ for i=1,#files do
+ context.type(files[i])
+ context.par()
+ end
else
context("no action given")
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv
index a1aecc35464..5e7de227096 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv
@@ -180,6 +180,10 @@
\def\mult_check_for_assignment_indeed#1=#2#3\_end_
{\if#2@\assignmentfalse\else\assignmenttrue\fi}
+\def\mult_check_for_assignment_indeed_begin_#1=#2#3\_end_
+ {\if#2@}
+
+
\def\mult_check_for_assignment#1%
{\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=@@\_end_}
@@ -223,7 +227,8 @@
{\ifx#2\relax\let#2\empty\fi % it is hardly faster but produces less expansion tracing
\def#3##1{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}%
\def#4##1##2{\ifcsname##1:##2\endcsname##1:##2\else\expandafter#5\csname##1:\s!parent\endcsname{##2}\fi}%
- \def#5##1##2{\ifx##1\relax\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ?
+ %\def#5##1##2{\ifx##1\relax\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ?
+ \def#5##1##2{\ifx##1\relax\??empty\else#4##1{##2}\fi}% is {} needed around ##1 ?
\def#6##1##2{\csname\ifcsname#1##1:##2\endcsname#1##1:##2\else\expandafter#5\csname#1##1:\s!parent\endcsname{##2}\fi\endcsname}%
\def#7##1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2:##1\endcsname}}% always root, no backtrack
\def#8##1{\begincsname#1#2:##1\endcsname}}
@@ -255,7 +260,8 @@
{\ifx#2\relax\let#2\empty\fi
\def#3##1{#1#4{#1#2}{##1}:}% leading #1 was missing .. is this one used?
\def#4##1##2{\ifcsname##1:##2\endcsname##1\else\expandafter#5\csname##1:\s!parent\endcsname{##2}\fi}%
- \def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}%
+ %\def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}%
+ \def#5##1##2{\ifx##1\relax\else#4##1{##2}\fi}%
\def#6{#1#2:}%
\def#7##1{#1##1:}%
\def#8{\ifx#2\empty\else\ifcsname#1#2:\s!parent\endcsname\else\expandafter\let\csname#1#2:\s!parent\endcsname#1\fi\fi}%
@@ -389,6 +395,43 @@
\the#7%
\let#4#9}}
+% \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones
+% {\ifx#4\relax\let#4\empty\fi % see \defineregister
+% \unexpanded\def#2{\dotripleempty#5}%
+% \newtoks#6%
+% \newtoks#7%
+% \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child]
+% {\let#9#4%
+% \edef#4{##1}%
+% \ifthirdargument
+% \the#6% predefine
+% \edef#8{##2}%
+% \mult_check_for_parent{#1}{#3}#4#8%
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
+% \mult_interfaces_get_parameters{#1#4:}[##3]%
+% \else\ifsecondargument
+% \the#6% predefine
+% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##2}=@@\_end_
+% \edef#8{##2}%
+% \mult_check_for_parent{#1}{#3}#4#8%
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
+% \else
+% \let#8\empty
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
+% \mult_interfaces_get_parameters{#1#4:}[##2]%
+% \fi
+% \else
+% \the#6% predefine
+% \let#8\empty
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
+% \fi\fi
+% \the#7%
+% \let#4#9}}
+
\unexpanded\def\installdefinehandler#1#2#3%
{\normalexpanded
{\mult_interfaces_install_define_handler
@@ -466,7 +509,7 @@
\let#3#7%
\else\iffirstargument
% \mult_check_for_assignment{##1}%
- \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_
+ \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_
\ifassignment
% \setuplayout[key=value]
\let#7#3%
@@ -496,6 +539,54 @@
#2\zerocount % mode is always zero at the end
\the#9}}
+% \unexpanded\def\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9%
+% {\newtoks#5%
+% \newconstant#2%
+% \newtoks#8%
+% \newtoks#9%
+% \ifx#6\relax\let#6\empty\fi
+% \unexpanded\def#4[##1][##2]% maybe helper
+% {\ifsecondargument % no commalist here
+% % \setuplayout[whatever][key=value]
+% \let#7#3%
+% \let#6#3%
+% \edef#3{##1}%
+% #2\doingrootsetupnamed
+% \mult_interfaces_get_parameters{#1#3:}[##2]%
+% \the#5%
+% \ifx#3#6\the#8\fi % only switchsetups if previous == current
+% \let#3#7%
+% \else\iffirstargument
+% % \mult_check_for_assignment{##1}%
+% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=@@\_end_
+% % \setuplayout[whatever]
+% \let#6#3% % previous becomes current
+% \edef#3{##1}% this will catch reset so one needs to test for it
+% #2\doingrootsetnamed
+% \the#5% % we can check for previous vs current
+% \the#8% switchsetups
+% \else
+% % \setuplayout[key=value]
+% \let#7#3%
+% \let#6#3%
+% \let#3\empty
+% #2\doingrootsetuproot
+% \mult_interfaces_get_parameters{#1:}[##1]%
+% \the#5%
+% \the#8% switchsetups
+% \let#3#7%
+% \fi
+% \else
+% % \setuplayout
+% \let#6#3% % previous becomes current
+% \let#3\empty % current becomes empty
+% #2\doingrootsetroot
+% \the#5%
+% \the#8% switchsetups
+% \fi\fi
+% #2\zerocount % mode is always zero at the end
+% \the#9}}
+
\unexpanded\def\installswitchsetuphandler#1#2%
{\normalexpanded
{\mult_interfaces_install_switch_setup_handler_a
@@ -966,176 +1057,176 @@
\def\s!double{double}
\def\s!triple{triple}
-\unexpanded\def\syst_helpers_double_empty#1#2#3%
- {\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_double_empty_one_yes_mult#2#3}%
- {\syst_helpers_double_empty_one_nop_mult#1}}
-
-\def\syst_helpers_double_empty_one_yes_mult#1#2[#3]%
- {\firstargumenttrue
- \doifelsenextoptional
- {\secondargumenttrue#2[{#3}]}%
- {\syst_helpers_double_empty_two_nop_mult#1{#3}}}
-
-\def\syst_helpers_double_empty_one_nop_mult% #1%
- {\firstargumentfalse
- \secondargumentfalse
- }% #1}
-
-\def\syst_helpers_double_empty_two_nop_mult
- {\secondargumentfalse
- \if_next_blank_space_token
- \expandafter\syst_helpers_double_empty_one_spaced_mult
- \else
- \expandafter\syst_helpers_double_empty_one_normal_mult
- \fi}
-
-\def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] }
-\def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]}
-
-\unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8%
- {\ifx#3\relax\let#3\empty\fi
- \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it
- \newtoks#4%
- \newtoks#7%
- \edef\m_mult_interface_setup{\csstring#2_}%
- \unexpanded\edef#2{\syst_helpers_double_empty
- \csname\m_mult_interface_setup\s!simple\endcsname
- \csname\m_mult_interface_setup\s!single\endcsname
- \csname\m_mult_interface_setup\s!double\endcsname}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
- {\let#6#3%
- \def#8####1% we will have a simple one as well
- {\edef#3{####1}%
- \mult_interfaces_get_parameters{#1#3:}[##2]%
- \the#4}%
- \processcommalist[##1]#8%
- \let#3#6%
- \the#7}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
- {\let#6#3%
- \let#3\empty
- \mult_interfaces_get_parameters{#1:}[##1]%
- \the#4%
- \let#3#6%
- \the#7}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
- {\let#6#3%
- \let#3\empty
- \the#4%
- \let#3#6%
- \the#7}}
-
-\unexpanded\def\installsetuphandler#1#2%
- {\normalexpanded
- {\mult_interfaces_install_setup_handler
- {\noexpand#1}% \??aa
- \expandafter\noexpand\csname setup#2\endcsname
- \expandafter\noexpand\csname current#2\endcsname
- \expandafter\noexpand\csname everysetup#2\endcsname
- \expandafter\noexpand\csname setupcurrent#2\endcsname
- \expandafter\noexpand\csname saved_setup_current#2\endcsname
- \expandafter\noexpand\csname everysetup#2root\endcsname
- \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
-
-\unexpanded\def\syst_helpers_triple_empty#1#2#3#4%
- {\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_triple_empty_one_yes_mult#2#3#4}%
- {\syst_helpers_triple_empty_one_nop_mult#1}}
-
-\def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]%
- {\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}%
- {\syst_helpers_triple_empty_two_nop_mult#1{#4}}}
-
-\def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]%
- {\secondargumenttrue
- \doifelsenextoptional
- {\thirdargumenttrue#2[{#3}][{#4}]}%
- {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}}
-
-\def\syst_helpers_triple_empty_one_nop_mult % #1%
- {\firstargumentfalse
- \secondargumentfalse
- \thirdargumentfalse
- } % #1
-
-\def\syst_helpers_triple_empty_two_nop_mult
- {\secondargumentfalse
- \thirdargumentfalse
- \if_next_blank_space_token
- \expandafter\syst_helpers_triple_empty_two_spaced_mult
- \else
- \expandafter\syst_helpers_triple_empty_two_normal_mult
- \fi}
-
-\def\syst_helpers_triple_empty_three_nop_mult
- {\thirdargumentfalse
- \if_next_blank_space_token
- \expandafter\syst_helpers_triple_empty_three_spaced_mult
- \else
- \expandafter\syst_helpers_triple_empty_three_normal_mult
- \fi}
-
-\def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] }
-\def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]}
-\def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] }
-\def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]}
-
-\unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8%
- {\ifx#3\relax\let#3\empty\fi
- \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}%
- \newtoks#4%
- \edef\m_mult_interface_setup{\csstring#2_}%
- \unexpanded\edef#2{\syst_helpers_triple_empty
- \csname\m_mult_interface_setup\s!simple\endcsname
- \csname\m_mult_interface_setup\s!single\endcsname
- \csname\m_mult_interface_setup\s!double\endcsname
- \csname\m_mult_interface_setup\s!triple\endcsname}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]%
- {\let#7#3%
- \def#8####1%
- {\edef#3{####1}%
- \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}%
- \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent
- \the#4}%
- \processcommalist[##1]#8%
- \let#3#7}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
- {\let#7#3%
- \def#8####1%
- {\edef#3{####1}%
- #6% checks parent and sets if needed
- \mult_interfaces_get_parameters{#1#3:}[##2]%
- \the#4}%
- \processcommalist[##1]#8%
- \let#3#7}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
- {\let#7#3%
- \let#3\empty
- \mult_interfaces_get_parameters{#1:}[##1]%
- \the#4%
- \let#3#7}%
- \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
- {\let#7#3%
- \let#3\empty
- \the#4%
- \let#3#7}}
-
-\unexpanded\def\installautosetuphandler#1#2%
- {\normalexpanded
- {\mult_interfaces_install_auto_setup_handler
- {\noexpand#1}% \??aa
- \expandafter\noexpand\csname setup#2\endcsname
- \expandafter\noexpand\csname current#2\endcsname
- \expandafter\noexpand\csname everysetup#2\endcsname
- \expandafter\noexpand\csname setupcurrent#2\endcsname
- \expandafter\noexpand\csname check#2parent\endcsname
- \expandafter\noexpand\csname saved_setup_current#2\endcsname
- \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
+% \unexpanded\def\syst_helpers_double_empty#1#2#3%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_double_empty_one_yes_mult#2#3}%
+% {\syst_helpers_double_empty_one_nop_mult#1}}
+%
+% \def\syst_helpers_double_empty_one_yes_mult#1#2[#3]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\secondargumenttrue#2[{#3}]}%
+% {\syst_helpers_double_empty_two_nop_mult#1{#3}}}
+%
+% \def\syst_helpers_double_empty_one_nop_mult% #1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% }% #1}
+%
+% \def\syst_helpers_double_empty_two_nop_mult
+% {\secondargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_double_empty_one_spaced_mult
+% \else
+% \expandafter\syst_helpers_double_empty_one_normal_mult
+% \fi}
+%
+% \def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] }
+% \def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]}
+%
+% \unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8%
+% {\ifx#3\relax\let#3\empty\fi
+% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it
+% \newtoks#4%
+% \newtoks#7%
+% \edef\m_mult_interface_setup{\csstring#2_}%
+% \unexpanded\edef#2{\syst_helpers_double_empty
+% \csname\m_mult_interface_setup\s!simple\endcsname
+% \csname\m_mult_interface_setup\s!single\endcsname
+% \csname\m_mult_interface_setup\s!double\endcsname}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
+% {\let#6#3%
+% \def#8####1% we will have a simple one as well
+% {\edef#3{####1}%
+% \mult_interfaces_get_parameters{#1#3:}[##2]%
+% \the#4}%
+% \processcommalist[##1]#8%
+% \let#3#6%
+% \the#7}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
+% {\let#6#3%
+% \let#3\empty
+% \mult_interfaces_get_parameters{#1:}[##1]%
+% \the#4%
+% \let#3#6%
+% \the#7}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
+% {\let#6#3%
+% \let#3\empty
+% \the#4%
+% \let#3#6%
+% \the#7}}
+
+% \unexpanded\def\installsetuphandler#1#2%
+% {\normalexpanded
+% {\mult_interfaces_install_setup_handler
+% {\noexpand#1}% \??aa
+% \expandafter\noexpand\csname setup#2\endcsname
+% \expandafter\noexpand\csname current#2\endcsname
+% \expandafter\noexpand\csname everysetup#2\endcsname
+% \expandafter\noexpand\csname setupcurrent#2\endcsname
+% \expandafter\noexpand\csname saved_setup_current#2\endcsname
+% \expandafter\noexpand\csname everysetup#2root\endcsname
+% \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
+%
+% \unexpanded\def\syst_helpers_triple_empty#1#2#3#4%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_triple_empty_one_yes_mult#2#3#4}%
+% {\syst_helpers_triple_empty_one_nop_mult#1}}
+%
+% \def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}%
+% {\syst_helpers_triple_empty_two_nop_mult#1{#4}}}
+%
+% \def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\thirdargumenttrue#2[{#3}][{#4}]}%
+% {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}}
+%
+% \def\syst_helpers_triple_empty_one_nop_mult % #1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% } % #1
+%
+% \def\syst_helpers_triple_empty_two_nop_mult
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_triple_empty_two_spaced_mult
+% \else
+% \expandafter\syst_helpers_triple_empty_two_normal_mult
+% \fi}
+%
+% \def\syst_helpers_triple_empty_three_nop_mult
+% {\thirdargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_triple_empty_three_spaced_mult
+% \else
+% \expandafter\syst_helpers_triple_empty_three_normal_mult
+% \fi}
+%
+% \def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] }
+% \def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]}
+% \def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] }
+% \def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]}
+%
+% \unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8%
+% {\ifx#3\relax\let#3\empty\fi
+% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}%
+% \newtoks#4%
+% \edef\m_mult_interface_setup{\csstring#2_}%
+% \unexpanded\edef#2{\syst_helpers_triple_empty
+% \csname\m_mult_interface_setup\s!simple\endcsname
+% \csname\m_mult_interface_setup\s!single\endcsname
+% \csname\m_mult_interface_setup\s!double\endcsname
+% \csname\m_mult_interface_setup\s!triple\endcsname}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]%
+% {\let#7#3%
+% \def#8####1%
+% {\edef#3{####1}%
+% \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}%
+% \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent
+% \the#4}%
+% \processcommalist[##1]#8%
+% \let#3#7}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
+% {\let#7#3%
+% \def#8####1%
+% {\edef#3{####1}%
+% #6% checks parent and sets if needed
+% \mult_interfaces_get_parameters{#1#3:}[##2]%
+% \the#4}%
+% \processcommalist[##1]#8%
+% \let#3#7}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
+% {\let#7#3%
+% \let#3\empty
+% \mult_interfaces_get_parameters{#1:}[##1]%
+% \the#4%
+% \let#3#7}%
+% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
+% {\let#7#3%
+% \let#3\empty
+% \the#4%
+% \let#3#7}}
+%
+% \unexpanded\def\installautosetuphandler#1#2%
+% {\normalexpanded
+% {\mult_interfaces_install_auto_setup_handler
+% {\noexpand#1}% \??aa
+% \expandafter\noexpand\csname setup#2\endcsname
+% \expandafter\noexpand\csname current#2\endcsname
+% \expandafter\noexpand\csname everysetup#2\endcsname
+% \expandafter\noexpand\csname setupcurrent#2\endcsname
+% \expandafter\noexpand\csname check#2parent\endcsname
+% \expandafter\noexpand\csname saved_setup_current#2\endcsname
+% \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
% okay, we can also get rid of the #9, but this code looks pretty bad, while the previous is
% still okay given that we can also use #6 as setup (so in fact we can save some cs again and
@@ -1197,9 +1288,11 @@
{\dodoubleempty#7}%
\unexpanded\def#7[##1][##2]%
{\ifsecondargument
- #3\c_mult_set\expandafter{\the\c_mult_set#9[##1][##2]}%
+ %#3\c_mult_set\expandafter{\the\c_mult_set#9[##1][##2]}%
+ #3\toksapp\c_mult_set{#9[##1][##2]}%
\else\iffirstargument
- #3\c_mult_set\expandafter{\the\c_mult_set#8[##1]}%
+ %#3\c_mult_set\expandafter{\the\c_mult_set#8[##1]}%
+ #3\toksapp\c_mult_set{#8[##1]}%
\fi\fi}}
\unexpanded\def\installdefinitionsetmember#1#2#3#4%
@@ -1230,9 +1323,30 @@
\expandafter\noexpand\csname current#2parent\endcsname
\expandafter\noexpand\csname inject#2parent\endcsname}}
+% Faster but not used that much to make a dent in performance. But, because it's
+% cleaner anyway and also gives less tracing, we apply it a few times.
+
+\unexpanded\def\syst_helpers_install_macro_stack#1#2#3%
+ {\xdef\m_syst_helpers_push_macro{\csstring#1}%
+ \expandafter\newcount\csname#3\m_syst_helpers_push_macro\endcsname
+ \expandafter\edef\csname push_macro_\m_syst_helpers_push_macro\endcsname
+ {\noexpand\expandafter\glet
+ \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname
+ \noexpand#1%
+ \global\advance\csname#3\m_syst_helpers_push_macro\endcsname\plusone}%
+ \expandafter\edef\csname pop_macro_\m_syst_helpers_push_macro\endcsname
+ {\global\advance\csname#3\m_syst_helpers_push_macro\endcsname\minusone
+ \noexpand\expandafter#2%
+ \noexpand\expandafter\noexpand#1%
+ \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname}}
+
+\unexpanded\def\installmacrostack #1{\syst_helpers_install_macro_stack#1\let \??localpushedmacro }
+\unexpanded\def\installglobalmacrostack#1{\syst_helpers_install_macro_stack#1\glet\??globalpushedmacro}
+
\protect
-%\unprotect
+% \unprotect
+%
% \installcorenamespace {test} \installcommandhandler \??test {test} \??test
% \unexpanded\def\TestMeA[#1]%
% {\edef\currenttest{#1}
@@ -1247,12 +1361,92 @@
% \unexpanded\def\TestMeD[#1]%
% {\edef\currenttest{#1}
% \doubleexpandafter\ifx\testparameter\c!before\empty \relax \else \relax \fi}
-% \protect
%
-% \starttext
-% \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed]
-% \resettimer \dorecurse{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502
-% \resettimer \dorecurse{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530
-% \resettimer \dorecurse{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487
-% \resettimer \dorecurse{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493
-% \stoptext
+% \protect
+%
+% \starttext
+% \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed]
+% \resettimer \dorecurse{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502
+% \resettimer \dorecurse{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530
+% \resettimer \dorecurse{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487
+% \resettimer \dorecurse{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493
+% \stoptext
+
+% There is no real demand for this ... even if this is twice as fast we only gain
+% a few milliseconds:
+%
+% \unexpanded\def\foo#1{[foo:#1]}
+%
+% \installcommalistprocessor {foo} \foo
+% \installcommalistprocessorcommand \processfoolist {foo} \foo
+%
+% \commalistprocessor{foo}[a,b,c,d]
+% \processfoolist [a, b, c, d]
+%
+% \testfeatureonce{30000}{} \elapsedtime\par % 0.01 -> 0.00
+% \testfeatureonce{30000}{\processfoolist [fixed,middle]} \elapsedtime\par % 0.07 -> 0.06
+% \testfeatureonce{30000}{\commalistprocessor{foo}[fixed,middle]} \elapsedtime\par % 0.09 -> 0.08
+% \testfeatureonce{30000}{\processcommalist [fixed,middle]\foo} \elapsedtime\par % 0.13 -> 0.12
+%
+% For instance the luatex manual only has some 3000 calls. But I keep this around as one
+% never knows when we might need it.
+%
+% \installcorenamespace{commalistprocessor}
+% \installcorenamespace{commalistprocessorcheck}
+% \installcorenamespace{commalistprocessorwrap}
+% \installcorenamespace{commalistprocessorfirst}
+% \installcorenamespace{commalistprocessorcheckspace}
+% \installcorenamespace{commalistprocessorcheckfinish}
+% \installcorenamespace{commalistprocessoraction}
+% \installcorenamespace{commalistprocessorgobblespace}
+%
+% \unexpanded\def\installcommalistprocessor#1#2% 7 macro names overhead
+% {\let\nexttoken\relax
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessor#1\endcsname[%
+% {\futurelet\nexttoken\csname\??commalistprocessorcheck#1\endcsname}%
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessorcheck#1\endcsname
+% {\noexpand\ifx\nexttoken]%
+% \noexpand\expandafter\noexpand\gobblethreearguments
+% \noexpand\else
+% \noexpand\expandafter\csname\??commalistprocessorwrap#1\endcsname
+% \noexpand\fi
+% \relax}% this one preserved the next {}
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessorwrap#1\endcsname##1]%
+% {\csname\??commalistprocessorfirst#1\endcsname##1,]\relax}%
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessorfirst#1\endcsname##1% picks up \relax
+% {\csname\??commalistprocessorcheckspace#1\endcsname}%
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckspace#1\endcsname
+% {\noexpand\ifx\nexttoken\noexpand\blankspace
+% \noexpand\expandafter\csname\??commalistprocessorgobblespace#1\endcsname
+% \noexpand\else
+% \noexpand\expandafter\csname\??commalistprocessorcheckfinish#1\endcsname
+% \noexpand\fi}%
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckfinish#1\endcsname
+% {\noexpand\ifx\nexttoken]%
+% \noexpand\expandafter\noexpand\gobbleoneargument
+% \noexpand\else
+% \noexpand\expandafter\csname\??commalistprocessoraction#1\endcsname
+% \noexpand\fi}%
+% %
+% \unexpanded\expandafter\edef\csname\??commalistprocessoraction#1\endcsname##1,%
+% {\noexpand#2{##1}%
+% \futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}%
+% %
+% \let\next\:%
+% \unexpanded\edef \:{\csname\??commalistprocessorgobblespace#1\endcsname}%
+% \unexpanded\expandafter\edef\: {\futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}%
+% \let\:\next
+% %
+% }
+%
+% \unexpanded\def\installcommalistprocessorcommand#1#2#3%
+% {\installcommalistprocessor{#2}{#3}%
+% \expandafter\let\expandafter#1\csname\??commalistprocessor#2\endcsname}
+%
+% \unexpanded\def\commalistprocessor#1{\csname\??commalistprocessor#1\endcsname}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-def.lua b/Master/texmf-dist/tex/context/base/mkiv/mult-def.lua
index 925c22cd223..e03a82a765f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-def.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-def.lua
@@ -7503,6 +7503,10 @@ return {
["pe"]="تاریخ",
["ro"]="data",
},
+ ["time"]={
+ ["en"]="time",
+ ["nl"]="tijd",
+ },
["deepnumbercommand"]={
["cs"]="deepnumbercommand",
["de"]="deepnumbercommand",
@@ -8278,7 +8282,7 @@ return {
["ro"]="inaltime",
},
["hfactor"]={
- ["cs"]="vfaktor",
+ ["cs"]="hfaktor",
["de"]="hfaktor",
["en"]="hfactor",
["fr"]="facteurhauteur",
@@ -8287,6 +8291,14 @@ return {
["pe"]="عاملارتفاع",
["ro"]="hfactor",
},
+ ["vfactor"]={
+ ["cs"]="vfaktor",
+ ["de"]="vfaktor",
+ ["en"]="vfactor",
+ ["it"]="vfactor",
+ ["nl"]="vfactor",
+ ["ro"]="vfactor",
+ },
["hfil"]={
["cs"]="hfil",
["de"]="hfil",
@@ -11544,6 +11556,12 @@ return {
["pe"]="گاموای",
["ro"]="ystep",
},
+ ["ownerpassword"]={
+ ["en"]="ownerpassword",
+ },
+ ["userpassword"]={
+ ["en"]="userpassword",
+ },
},
["elements"]={
["answerlines"]={
@@ -13020,6 +13038,10 @@ return {
["cite"]={
["en"]="cite",
},
+ ["closed"]={
+ ["en"]="closed",
+ ["nl"]="gesloten",
+ },
["color"]={
["cs"]="barevne",
["de"]="farbe",
@@ -15538,7 +15560,7 @@ return {
["ro"]="postscript",
},
["precedingpage"]={
- ["en"]="followingpage",
+ ["en"]="precedingpage",
["nl"]="voorafgaandepagina",
},
["preference"]={
@@ -17053,6 +17075,9 @@ return {
["unframed"]={
["en"]="unframed",
},
+ ["unicode"]={
+ ["en"]="unicode",
+ },
["unit"]={
["cs"]="jednotka",
["de"]="einheit",
@@ -17815,8 +17840,8 @@ return {
["cd:brackets-l"] = { en = "[...,...]", lua = "{..., ...}" },
["cd:parenthesis-s"] = { en = "(...)" },
["cd:parenthesis-l"] = { en = "(...,...)" },
- ["cd:index-s"] = { en = "[...]" },
- ["cd:index-l"] = { en = "[..+...+..]" },
+ ["cd:index-s"] = { en = "{...}" },
+ ["cd:index-l"] = { en = "{..+...+..}" },
["cd:math-s"] = { en = "$...$" },
["cd:math-l"] = { en = "$...$" },
["cd:inlinemath-s"] = { en = "$...$" },
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-fun.lua b/Master/texmf-dist/tex/context/base/mkiv/mult-fun.lua
index 9b7062605b7..0776f36b4b2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-fun.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-fun.lua
@@ -3,7 +3,7 @@ return {
--
"nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel",
"shadefactor",
- "textextoffset",
+ "textextoffset", "textextanchor",
"normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent",
"softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent",
"darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent",
@@ -53,17 +53,19 @@ return {
"shadedinto", "withshadecolors",
"withshadedomain", "withshademethod", "withshadefactor", "withshadevector",
"withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform",
- "withshadestep", "withshadefraction",
+ "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin",
"cmyk", "spotcolor", "multitonecolor", "namedcolor",
"drawfill", "undrawfill",
"inverted", "uncolored", "softened", "grayed", "greyed",
"onlayer",
"along",
- "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", -- "lua",
+ "graphictext", "loadfigure", "externalfigure", "figure", "register",
+ "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath",
"checkedbounds", "checkbounds", "strut", "rule",
"withmask", "bitmapimage",
"colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist",
"textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext",
+ "notcached",
"verbatim",
"thelabel", "label",
"autoalign",
@@ -144,5 +146,31 @@ return {
"sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist",
--
"circularpath", "squarepath", "linearpath",
+ --
+ "theoffset",
+ --
+ "texmode", "systemmode",
+ "texvar", "texstr",
+ "isarray", "prefix", "dimension",
+ "getmacro", "getdimen", "getcount", "gettoks",
+ "setmacro", "setdimen", "setcount", "settoks",
+ --
+ "positionpath", "positioncurve", "positionxy", "positionpxy",
+ "positionwhd", "positionpage", "positionregion", "positionbox",
+ "positionanchor", "positioninregion", "positionatanchor",
+ --
+ "wdpart", "htpart", "dppart",
+ --
+ "texvar", "texstr",
+ --
+ "inpath", "pointof", "leftof", "rightof",
+ --
+ "newhash", "disposehash", "inhash", "tohash",
+ --
+ "isarray", "prefix", "isobject",
+ --
+ "comment", "report", "lua", "mp", "MP", "luacall",
+ --
+ "mirrored", "mirroredabout",
},
}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/mult-ini.lua
index 3f320bf7fdf..0c8581281d1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-ini.lua
@@ -105,6 +105,22 @@ function interfaces.getnamespace(n)
return usednamespaces[n] .. ">"
end
+if documentdata then
+
+ local prefix, getmacro
+
+ function documentdata.variable(name)
+ if not prefix then
+ prefix = usednamespaces.variables .. ">document:"
+ end
+ if not getmacro then
+ getmacro = tokens.getters.macro
+ end
+ return getmacro(prefix..name)
+ end
+
+end
+
local function resolve(t,k)
local v = logs.reporter(k)
t[k] = v
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mult-ini.mkiv
index d66749d145e..634e2c1d827 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-ini.mkiv
@@ -111,6 +111,8 @@
\def\s!spread{spread} \let\!!spread\s!spread % obsolete
\def\s!plus {plus} \let\!!plus \s!plus % obsolete
\def\s!minus {minus} \let\!!minus \s!minus % obsolete
+\def\s!left {left}
+\def\s!right {right}
\def\s!fil {fil}
\def\s!fill {fill} \let\!!fill \s!fill % obsolete
\def\s!filll {filll}
@@ -122,11 +124,6 @@
\def\s!top {top}
\def\s!both {both}
-%D Kind of special:
-
-\edef\!!TLT{\detokenize{TLT}}
-\edef\!!TRT{\detokenize{TRT}}
-
%D \macros
%D {defineinterfaceconstant,
%D defineinterfacevariable,
@@ -341,17 +338,17 @@
%D These will become obsolete:
\unexpanded\def\startmessages #1 library: #2 %
- {\bgroup
+ {\begingroup
\ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi
- \catcode\endoflineasciicode\activecatcode
+ \catcode\endoflineasciicode\othercatcode
\doifelseinset{#1}{\currentresponses,all}\mult_messages_start_yes\mult_messages_start_nop{#2}}
\def\mult_messages_start_yes#1#2\stopmessages
{\clf_setinterfacemessages{#1}{#2}%
- \egroup}
+ \endgroup}
\def\mult_messages_start_nop#1#2\stopmessages
- {\egroup}
+ {\endgroup}
\let\stopmessages\relax
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-low.lua b/Master/texmf-dist/tex/context/base/mkiv/mult-low.lua
index 0acba3b87b1..75c048c92de 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-low.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-low.lua
@@ -12,7 +12,8 @@ return {
["constants"] = {
--
"zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive",
- "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred",
+ "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen",
+ "plusfifty", "plushundred", "plusonehundred", "plustwohundred", "plusfivehundred",
"plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone",
"zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint",
"points", "halfpoint",
@@ -20,7 +21,9 @@ return {
"zeromuskip", "onemuskip",
"pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi",
"normalpagebox",
- -- --
+ --
+ "directionlefttoright", "directionrighttoleft",
+ --
"endoflinetoken", "outputnewlinechar",
--
"emptytoks", "empty", "undefined",
@@ -31,9 +34,7 @@ return {
--
"fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality",
"luatexengine", "pdftexengine", "xetexengine", "unknownengine",
- -- "etexversion",
- -- "pdftexversion", "pdftexrevision",
- -- "xetexversion", "xetexrevision",
+ "contextformat", "contextversion", "contextkind", "contextlmtxmode", "contextmark", "mksuffix",
--
"activecatcode",
--
@@ -59,6 +60,7 @@ return {
"spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode",
"colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode",
"leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode",
+ "leftparentasciicode", "rightparentasciicode",
"lessthanasciicode", "morethanasciicode", "doublecommentsignal",
"atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode",
"doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode",
@@ -101,7 +103,9 @@ return {
"startcomponent", "stopcomponent", "component",
"startproduct", "stopproduct", "product",
"startproject", "stopproject", "project",
- "starttext", "stoptext", "startnotext", "stopnotext","startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument",
+ "starttext", "stoptext", "startnotext", "stopnotext",
+ "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument",
+ "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable",
"startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule","setupmodule","currentmoduleparameter","moduleparameter",
"everystarttext", "everystoptext",
--
@@ -153,10 +157,12 @@ return {
"texdefinition",
--
"doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup",
+ "copysetups", "resetsetups",
"doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler",
--
"newmode", "setmode", "resetmode",
"newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode",
+ "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode",
"booleanmodevalue",
--
"newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif",
@@ -165,14 +171,19 @@ return {
"then",
"begcsname",
--
+ "autorule",
+ --
"strippedcsname","checkedstrippedcsname",
--
"firstargumentfalse", "firstargumenttrue",
"secondargumentfalse", "secondargumenttrue",
"thirdargumentfalse", "thirdargumenttrue",
"fourthargumentfalse", "fourthargumenttrue",
- "fifthargumentfalse", "fifthsargumenttrue",
- "sixthargumentfalse", "sixtsargumenttrue",
+ "fifthargumentfalse", "fifthargumenttrue",
+ "sixthargumentfalse", "sixthargumenttrue",
+ "seventhargumentfalse", "seventhargumenttrue",
+ --
+ "vkern", "hkern",
--
"doglobal", "dodoglobal", "redoglobal", "resetglobal",
--
@@ -197,8 +208,8 @@ return {
--
"hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg",
--
- "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg",
- "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg",
+ "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg",
+ "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg",
"ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox",
"ruledhpack", "ruledvpack", "ruledtpack",
"ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern",
@@ -214,11 +225,20 @@ return {
"scratchtoks", "globalscratchtoks", "privatescratchtoks",
"scratchbox", "globalscratchbox", "privatescratchbox",
--
+ "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree",
+ --
+ "groupedcommand", "groupedcommandcs",
+ "triggergroupedcommand", "triggergroupedcommandcs",
+ "simplegroupedcommand", "pickupgroupedcommand",
+ --
"normalbaselineskip", "normallineskip", "normallineskiplimit",
--
"availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction",
--
+ "next", "nexttoken",
+ --
"nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox",
+ "boxisempty",
--
"scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance",
"scratchhsize", "scratchvsize",
@@ -239,6 +259,7 @@ return {
"scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip",
--
"doif", "doifnot", "doifelse",
+ "firstinset",
"doifinset", "doifnotinset",
"doifelseinset", "doifinsetelse",
"doifelsenextchar", "doifnextcharelse",
@@ -262,7 +283,7 @@ return {
"doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber",
"doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon",
"doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse",
- "doifelseassignment", "doifassignmentelse", "docheckassignment",
+ "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs",
"doiftext", "doifelsetext", "doiftextelse", "doifnottext",
--
"tracingall", "tracingnone", "loggingall",
@@ -278,7 +299,7 @@ return {
"singleexpandafter", "doubleexpandafter", "tripleexpandafter",
--
"dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces",
- "removepunctuation", "ignoreparskip", "forcestrutdepth",
+ "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace",
--
"wait", "writestatus", "define", "defineexpandable", "redefine",
--
@@ -329,7 +350,7 @@ return {
"dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty",
"permitspacesbetweengroups", "dontpermitspacesbetweengroups",
--
- "nopdfcompression", "maximumpdfcompression", "normalpdfcompression",
+ "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression",
--
"modulonumber", "dividenumber",
--
@@ -403,12 +424,8 @@ return {
"startluacode", "stopluacode", "startlua", "stoplua",
"startctxfunction","stopctxfunction","ctxfunction",
"startctxfunctiondefinition","stopctxfunctiondefinition",
- "installctxfunction", "installctxfunctioncall",
- "installprotectedctxfunction", "installprotectedctxfunctioncall",
- "installctxscanner", "installctxscannercall",
- "resetctxscanner",
- "installprotectedctxscanner", "installprotectedctxscannercall",
- "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand",
+ "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner",
+ "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand",
--
"carryoverpar",
"lastlinewidth",
@@ -433,7 +450,8 @@ return {
--
"nospace", "nospacing", "dospacing",
--
- "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack",
+ "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack",
+ "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack",
--
"frule",
--
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-prm.lua b/Master/texmf-dist/tex/context/base/mkiv/mult-prm.lua
index 1cd5f581007..579750bc97d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-prm.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-prm.lua
@@ -231,35 +231,44 @@ return {
"breakafterdirmode",
"catcodetable",
"clearmarks",
- "copyfont",
"compoundhyphenmode",
+ "copyfont",
"crampeddisplaystyle",
"crampedscriptscriptstyle",
"crampedscriptstyle",
"crampedtextstyle",
+ "csstring",
"draftmode",
"dviextension",
"dvifeedback",
"dvivariable",
"efcode",
+ "endlocalcontrol",
"etoksapp",
"etokspre",
+ "exceptionpenalty",
"expanded",
"expandglyphsinfont",
"explicitdiscretionary",
"explicithyphenpenalty",
+ "fixupboxesmode",
"fontid",
"formatname",
"gleaders",
+ "gtoksapp",
+ "gtokspre",
"hjcode",
"hyphenationbounds",
"hyphenationmin",
"hyphenpenaltymode",
"ifabsdim",
"ifabsnum",
+ "ifcondition",
"ifincsname",
"ifprimitive",
"ignoreligaturesinfont",
+ "immediateassigned",
+ "immediateassignment",
"initcatcodetable",
"insertht",
"lastnamedcs",
@@ -269,6 +278,7 @@ return {
"lastxpos",
"lastypos",
"latelua",
+ "lateluafunction",
"leftghost",
"leftmarginkern",
"letcharcode",
@@ -280,6 +290,10 @@ return {
"localleftbox",
"localrightbox",
"lpcode",
+ "luabytecode",
+ "luabytecodecall",
+ "luacopyinputnodes",
+ "luadef",
"luaescapestring",
"luafunction",
"luafunctioncall",
@@ -291,14 +305,17 @@ return {
"mathdirection",
"mathdisplayskipmode",
"matheqnogapstep",
+ "mathflattenmode",
"mathitalicsmode",
"mathnolimitsmode",
"mathoption",
"mathpenaltiesmode",
"mathrulesfam",
"mathrulesmode",
- "mathscriptsmode",
+ "mathrulethicknessmode",
"mathscriptboxmode",
+ "mathscriptcharmode",
+ "mathscriptsmode",
"mathstyle",
"mathsurroundmode",
"mathsurroundskip",
@@ -362,6 +379,8 @@ return {
"uniformdeviate",
"useboxresource",
"useimageresource",
+ "xtoksapp",
+ "xtokspre",
},
["omega"]={
"Omegaminorversion",
@@ -422,15 +441,17 @@ return {
"pdflastypos",
"pdflinkmargin",
"pdfliteral",
+ "pdfmajorversion",
"pdfmapfile",
"pdfmapline",
- "pdfmajorversion",
"pdfminorversion",
"pdfnames",
"pdfnoligatures",
"pdfnormaldeviate",
"pdfobj",
"pdfobjcompresslevel",
+ "pdfomitcharset",
+ "pdfomitcidset",
"pdfoutline",
"pdfoutput",
"pdfpageattr",
@@ -447,6 +468,7 @@ return {
"pdfprotrudechars",
"pdfpxdimen",
"pdfrandomseed",
+ "pdfrecompress",
"pdfrefobj",
"pdfrefxform",
"pdfrefximage",
@@ -522,7 +544,6 @@ return {
"cr",
"crcr",
"csname",
- "csstring",
"day",
"deadcycles",
"def",
@@ -580,6 +601,7 @@ return {
"fontname",
"futurelet",
"gdef",
+ "glet",
"global",
"globaldefs",
"halign",
@@ -823,4 +845,4 @@ return {
["xetex"]={
"XeTeXversion",
},
-}
+}
\ No newline at end of file
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-prm.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mult-prm.mkiv
index 1b9195f4101..5ffb84d389c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-prm.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-prm.mkiv
@@ -55,7 +55,7 @@
"pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages",
"pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral",
"pdfmapfile", "pdfmapline", "pdfmajorversion", "pdfminorversion", "pdfnames",
- "pdfnoligatures", "pdfnormaldeviate", "pdfobj",
+ "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfrecompress",
"pdfobjcompresslevel", "pdfoutline", "pdfoutput", "pdfpageattr",
"pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources",
"pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode",
@@ -68,6 +68,7 @@
"pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate",
"pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr",
"pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage",
+ "pdfomitcidset", "pdfomitcharset",
},
aleph = { -- we don't bother
"Alephminorversion", "Alephrevision", "Alephversion",
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-sys.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mult-sys.mkiv
index 7000eed7bb9..fdb2ea73214 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mult-sys.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/mult-sys.mkiv
@@ -55,6 +55,7 @@
\definesystemconstant {danish} \definesystemconstant {da}
\definesystemconstant {dutch} \definesystemconstant {nl}
\definesystemconstant {english} \definesystemconstant {en}
+\definesystemconstant {estonian} \definesystemconstant {et}
\definesystemconstant {farsi} \definesystemconstant {fa} % just persian
\definesystemconstant {finnish} \definesystemconstant {fi}
\definesystemconstant {french} \definesystemconstant {fr}
@@ -240,6 +241,7 @@
\definesystemconstant {next}
\definesystemconstant {pickup}
+\definesystemconstant {forget}
\definesystemconstant {ascii}
\definesystemconstant {default}
\definesystemconstant {unknown}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-acc.lua b/Master/texmf-dist/tex/context/base/mkiv/node-acc.lua
index 03f6d747634..e6c6176026e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-acc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-acc.lua
@@ -8,7 +8,6 @@ if not modules then modules = { } end modules ['node-acc'] = {
local nodes, node = nodes, node
-local nodecodes = nodes.nodecodes
local tasks = nodes.tasks
local nuts = nodes.nuts
@@ -16,6 +15,7 @@ local tonut = nodes.tonut
local tonode = nodes.tonode
local getid = nuts.getid
+local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
local getlist = nuts.getlist
local getchar = nuts.getchar
@@ -28,21 +28,28 @@ local setsubtype = nuts.setsubtype
local getwidth = nuts.getwidth
local setwidth = nuts.setwidth
------ traverse_nodes = nuts.traverse
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
+local nextnode = nuts.traversers.node
+
----- copy_node = nuts.copy
local insert_after = nuts.insert_after
local copy_no_components = nuts.copy_no_components
+local nodecodes = nodes.nodecodes
+local gluecodes = nodes.gluecodes
+
local glue_code = nodecodes.glue
----- kern_code = nodecodes.kern
local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local userskip_code = gluecodes.user
+local spaceskip_code = gluecodes.spaceskip
+local xspaceskip_code = gluecodes.xspaceskip
+
local a_characters = attributes.private("characters")
-local threshold = 65536 -- not used
local nofreplaced = 0
-- todo: nbsp etc
@@ -50,6 +57,9 @@ local nofreplaced = 0
-- todo: maybe cache as we now create many nodes
-- todo: check for subtype related to spacing (13/14 but most seems to be user anyway)
+local trace = false trackers.register("backend.spaces", function(v) trace = v end)
+local slot = nil
+
local function injectspaces(head)
local p, p_id
local n = head
@@ -57,32 +67,42 @@ local function injectspaces(head)
local id = getid(n)
if id == glue_code then
if p and getid(p) == glyph_code then
- -- unless we don't care about the little bit of overhead
- -- we can just: local g = copy_node(g)
- local g = copy_no_components(p)
- local a = getattr(n,a_characters)
- setchar(g,32)
- setlink(p,g,n)
- setwidth(n,getwidth(n) - getwidth(g))
- if a then
- setattr(g,a_characters,a)
+ local s = getsubtype(n)
+ if s == spaceskip_code or s == xspaceskip_code then
+ -- unless we don't care about the little bit of overhead
+ -- we can just: local g = copy_node(g)
+ local g = copy_no_components(p)
+ local a = getattr(n,a_characters)
+ setchar(g,slot)
+ setlink(p,g,n)
+ setwidth(n,getwidth(n) - getwidth(g))
+ -- setsubtype(n,userskip_code)
+ if a then
+ setattr(g,a_characters,a)
+ end
+ setattr(n,a_characters,0)
+ nofreplaced = nofreplaced + 1
end
- setattr(n,a_characters,0)
- nofreplaced = nofreplaced + 1
end
elseif id == hlist_code or id == vlist_code then
- injectspaces(getlist(n),attribute)
+ injectspaces(getlist(n),slot)
end
p_id = id
p = n
n = getnext(n)
end
- return head, true -- always done anyway
+ return head
end
nodes.handlers.accessibility = function(head)
- local head, done = injectspaces(tonut(head))
- return tonode(head), done
+ if trace then
+ if not slot then
+ slot = fonts.helpers.privateslot("visualspace")
+ end
+ else
+ slot = 32
+ end
+ return injectspaces(head,slot)
end
statistics.register("inserted spaces in output",function()
@@ -99,7 +119,7 @@ end)
--
-- local function compact(n)
-- local t = { }
--- for n in traverse_id(glyph_code,n) do
+-- for n in nextglyph, n do
-- t[#t+1] = utfchar(getchar(n)) -- check for unicode
-- end
-- return concat(t,"")
@@ -107,8 +127,7 @@ end)
--
-- local function injectspans(head)
-- local done = false
--- for n in traverse_nodes(tonuts(head)) do
--- local id = getid(n)
+-- for n, id in nextnode, tonuts(head) do
-- if id == disc then
-- local r = getfield(n,"replace")
-- local p = getfield(n,"pre")
@@ -134,18 +153,17 @@ end)
--
-- tasks.appendaction("processors", "words", "nodes.injectspans")
--
--- local pdfpageliteral = nuts.pool.pdfpageliteral
+-- local pageliteral = nuts.pool.pageliteral
--
-- local function injectspans(head)
-- local done = false
--- for n in traverse_nodes(tonut(head)) do
--- local id = getid(n)
+-- for n, id in nextnode, tonut(head) do
-- if id == disc then
-- local a = getattr(n,a_hyphenated)
-- if a then
-- local str = codes[a]
--- local b = pdfpageliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str)))
--- local e = pdfpageliteral("EMC")
+-- local b = pageliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str)))
+-- local e = pageliteral("EMC")
-- insert_before(head,n,b)
-- insert_after(head,n,e)
-- done = true
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua b/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua
index 84567068bba..d6a9950fe8c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua
@@ -32,8 +32,6 @@ local getnext = nuts.getnext
local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
-local getfont = nuts.getfont
-local getchar = nuts.getchar
local getattr = nuts.getattr
local getboth = nuts.getboth
local getcomponents = nuts.getcomponents
@@ -51,8 +49,10 @@ local setprev = nuts.setprev
local setcomponents = nuts.setcomponents
local setattrlist = nuts.setattrlist
-local traverse_nodes = nuts.traverse
-local traverse_id = nuts.traverse_id
+----- traverse_nodes = nuts.traverse
+----- traverse_id = nuts.traverse_id
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
local flush_node = nuts.flush
local flush_list = nuts.flush_list
local hpack_nodes = nuts.hpack
@@ -154,9 +154,8 @@ function nodes.repackhlist(list,...)
end
local function set_attributes(head,attr,value)
- for n in traverse_nodes(head) do
+ for n, id in nextnode, head do
setattr(n,attr,value)
- local id = getid(n)
if id == hlist_node or id == vlist_node then
set_attributes(getlist(n),attr,value)
end
@@ -164,11 +163,10 @@ local function set_attributes(head,attr,value)
end
local function set_unset_attributes(head,attr,value)
- for n in traverse_nodes(head) do
+ for n, id in nextnode, head do
if not getattr(n,attr) then
setattr(n,attr,value)
end
- local id = getid(n)
if id == hlist_code or id == vlist_code then
set_unset_attributes(getlist(n),attr,value)
end
@@ -176,9 +174,8 @@ local function set_unset_attributes(head,attr,value)
end
local function unset_attributes(head,attr)
- for n in traverse_nodes(head) do
+ for n, id in nextnode, head do
setattr(n,attr,unsetvalue)
- local id = getid(n)
if id == hlist_code or id == vlist_code then
unset_attributes(getlist(n),attr)
end
@@ -197,98 +194,11 @@ nuts.setattributes = set_attributes nodes.setattributes
nuts.setunsetattributes = set_unset_attributes nodes.setunsetattributes = vianuts(set_unset_attributes)
nuts.unsetattributes = unset_attributes nodes.unsetattributes = vianuts(unset_attributes)
--- history:
---
--- local function glyph_width(a)
--- local ch = chardata[getfont(a)][getchar(a)]
--- return (ch and ch.width) or 0
--- end
---
--- local function glyph_total(a)
--- local ch = chardata[getfont(a)][getchar(a)]
--- return (ch and (ch.height+ch.depth)) or 0
--- end
---
--- local function non_discardable(a) -- inline
--- return getid(id) < math_node -- brrrr
--- end
---
--- local function calculate_badness(t,s)
--- if t == 0 then
--- return 0
--- elseif s <= 0 then
--- return INF_BAD
--- else
--- local r
--- if t <= 7230584 then
--- r = t * 297 / s
--- elseif s >= 1663497 then
--- r = t / floor(s / 297)
--- else
--- r = t
--- end
--- r = floor(r)
--- if r > 1290 then
--- return INF_BAD
--- else
--- return floor((r * r * r + 0x20000) / 0x40000) -- 0400000 / 01000000
--- end
--- end
--- end
---
--- left-overs
---
--- local function round_xn_over_d(x, n, d)
--- local positive -- was x >= 0
--- if x >= 0 then
--- positive = true
--- else
--- x = -x
--- positive = false
--- end
--- local t = floor(x % 0x8000) * n -- 0100000
--- local f = floor(t / 0x8000) -- 0100000
--- local u = floor(x / 0x8000) * n + f -- 0100000
--- local v = floor(u % d) * 0x8000 + f -- 0100000
--- if floor(u / d) >= 0x8000 then -- 0100000
--- report_parbuilders('arith_error')
--- else
--- u = 0x8000 * floor(u / d) + floor(v / d) -- 0100000
--- end
--- v = floor(v % d)
--- if 2*v >= d then
--- u = u + 1
--- end
--- if positive then
--- return u
--- else
--- return -u
--- end
--- end
---
--- local function firstline(n)
--- while n do
--- local id = getid(n)
--- if id == hlist_code then
--- if getsubtype(n) == line_code then
--- return n
--- else
--- return firstline(getlist(n))
--- end
--- elseif id == vlist_code then
--- return firstline(getlist(n))
--- end
--- n = getnext(n)
--- end
--- end
---
--- nodes.firstline = firstline
-
function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255
if untagged then
return first_glyph(n)
else
- for g in traverse_id(glyph_code,n) do
+ for g in nextglyph ,n do
return g
end
end
@@ -297,8 +207,8 @@ end
local function firstcharinbox(n)
local l = getlist(getbox(n))
if l then
- for g in traverse_id(glyph_code,l) do
- return getchar(g)
+ for g, c in nextglyph, l do
+ return c
end
end
return 0
@@ -431,10 +341,9 @@ nodes.link = function(list,currentfont,currentattr,head,tail)
end
local function locate(start,wantedid,wantedsubtype)
- for n in traverse_nodes(start) do
- local id = getid(n)
+ for n, id, subtype in nextnode, start do
if id == wantedid then
- if not wantedsubtype or getsubtype(n) == wantedsubtype then
+ if not wantedsubtype or subtype == wantedsubtype then
return n
end
elseif id == hlist_code or id == vlist_code then
@@ -490,87 +399,6 @@ end
-- end
-- end
--- these component helpers might move to another module
-
--- nodemode helper: here we also flatten components, no check for disc here
-
-function nuts.set_components(target,start,stop)
- local head = getcomponents(target)
- if head then
- flush_list(head)
- head = nil
- end
- if start then
- setprev(start)
- else
- return nil
- end
- if stop then
- setnext(stop)
- end
- local tail = nil
- while start do
- local c = getcomponents(start)
- local n = getnext(start)
- if c then
- if head then
- setlink(tail,c)
- else
- head = c
- end
- tail = find_tail(c)
- setcomponents(start)
- flush_node(start)
- else
- if head then
- setlink(tail,start)
- else
- head = start
- end
- tail = start
- end
- start = n
- end
- setcomponents(target,head)
- -- maybe also upgrade the subtype but we don't use it anyway
- return head
-end
-
-function nuts.get_components(target)
- return getcomponents(target)
-end
-
-nuts.get_components = getcomponents
-
-function nuts.take_components(target)
- local c = getcomponents(target)
- setcomponents(target)
- -- maybe also upgrade the subtype but we don't use it anyway
- return c
-end
-
--- nodemode helper: we assume a glyph and a flat components list (basemode can
--- have nested components)
-
-function nuts.count_components(n,marks)
- local components = getcomponents(n)
- if components then
- if marks then
- local i = 0
- for g in traverse_id(glyph_code,components) do
- if not marks[getchar(g)] then
- i = i + 1
- end
- end
- return i
- else
- return count(glyph_code,components)
- end
- else
- return 0
- end
-end
-
-- nodemode helper: the next and prev pointers are untouched
function nuts.copy_no_components(g,copyinjection)
@@ -596,7 +424,7 @@ end
function nuts.copy_only_glyphs(current)
local head = nil
local previous = nil
- for n in traverse_id(glyph_code,current) do
+ for n in nextglyph, current do
n = copy_node(n)
if head then
setlink(previous,n)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua b/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
index 4ed5abe5e5e..a19e5e969a7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
@@ -9,178 +9,288 @@ if not modules then modules = { } end modules ['node-bck'] = {
-- beware, this one takes quite some runtime, so we need a status flag
-- maybe some page related state
+-- todo: done (or just get rid of done altogether) ... saves no purpose
+-- any longer
+
local attributes, nodes, node = attributes, nodes, node
-local enableaction = nodes.tasks.enableaction
+local enableaction = nodes.tasks.enableaction
-local nodecodes = nodes.nodecodes
-local listcodes = nodes.listcodes
+local nodecodes = nodes.nodecodes
+local listcodes = nodes.listcodes
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local cell_code = listcodes.cell
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
-local nuts = nodes.nuts
-local nodepool = nuts.pool
+local alignmentlist_code = listcodes.alignment
+local celllist_code = listcodes.cell
-local tonode = nuts.tonode
-local tonut = nuts.tonut
+local nuts = nodes.nuts
+local nodepool = nuts.pool
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getattr = nuts.getattr
-local getsubtype = nuts.getsubtype
-local getwhd = nuts.getwhd
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getattr = nuts.getattr
+local getsubtype = nuts.getsubtype
+local getwhd = nuts.getwhd
+local getwidth = nuts.getwidth
+local getprop = nuts.getprop
-local setattr = nuts.setattr
-local setlink = nuts.setlink
-local setlist = nuts.setlist
+local setattr = nuts.setattr
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setattributelist = nuts.setattributelist
+local setprop = nuts.setprop
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+local takebox = nuts.takebox
+local findtail = nuts.tail
-local new_rule = nodepool.rule
-local new_glue = nodepool.glue
+local nextnode = nuts.traversers.node
+local nexthlist = nuts.traversers.hlist
+local nextlist = nuts.traversers.list
-local a_color = attributes.private('color')
-local a_transparency = attributes.private('transparency')
-local a_colormodel = attributes.private('colormodel')
-local a_background = attributes.private('background')
-local a_alignbackground = attributes.private('alignbackground')
+local flush_node_list = nuts.flush_list
-local function add_backgrounds(head) -- rather old code .. to be redone
- local current = head
- while current do
- local id = getid(current)
- if id == hlist_code or id == vlist_code then
- local list = getlist(current)
- if list then
- local head = add_backgrounds(list)
- if head then
- setlist(current,head)
- list = head
- end
+local new_rule = nodepool.rule
+local new_kern = nodepool.kern
+local new_hlist = nodepool.hlist
+
+local privateattributes = attributes.private
+local unsetvalue = attributes.unsetvalue
+
+local linefillers = nodes.linefillers
+
+local a_color = privateattributes("color")
+local a_transparency = privateattributes("transparency")
+local a_colormodel = privateattributes("colormodel")
+local a_background = privateattributes("background")
+local a_alignbackground = privateattributes("alignbackground")
+local a_linefiller = privateattributes("linefiller")
+local a_ruled = privateattributes("ruled")
+
+local trace_alignment = false
+local report_alignment = logs.reporter("backgrounds","alignment")
+
+trackers.register("backgrounds.alignments",function(v) trace_alignment = v end)
+
+-- We can't use listbuilders with where=alignment because at that stage we have
+-- unset boxes. Also, post_linebreak is unsuitable for nested processing as we
+-- get the same stuff many times (wrapped again and again).
+--
+-- After many experiments with different callbacks the shipout is still the best
+-- place but then we need to store some settings longer or save them with the node.
+-- For color only we can get away with it with an extra attribute flagging a row
+-- but for more complex stuff we can better do as we do here now.
+
+local overshoot = math.floor(65781/5) -- could be an option per table (just also store it)
+
+local function colored_a(current,list,template,id)
+ local width, height, depth = getwhd(current)
+ local total = height + depth
+ if width > 0 and total > 0 then
+ local rule = nil
+ --
+ local a = getattr(template,a_linefiller)
+ if a then
+ local d = linefillers.data[a%1000]
+ if d then
+ rule = linefillers.filler(template,d,width,height,depth)
+ end
+ end
+ --
+ if not rule then
+ rule = new_rule(width,height,depth)
+ end
+ setattributelist(rule,template)
+ local back = new_kern(-((id == vlist_code and total) or width))
+ return setlink(rule,back,list)
+ end
+end
+
+local function colored_b(current,list,template,id,indent)
+ local width, height, depth = getwhd(current)
+ local total = height + depth
+ if width > 0 and total > 0 then
+ local fore = (indent ~= 0) and new_kern(indent)
+ local rule = nil
+ --
+ local a = getattr(template,a_linefiller)
+ if a then
+ local d = linefillers.data[a%1000]
+ if d then
+ rule = linefillers.filler(template,d,width-indent,height,depth)
end
- local width, height, depth = getwhd(current)
- if width > 0 then
- local background = getattr(current,a_background)
+ end
+ --
+ if not rule then
+ rule = new_rule(width-indent,height+overshoot,depth+overshoot)
+ setattributelist(rule,template)
+ end
+ if overshoot == 0 then
+ local back = new_kern(-((id == vlist_code and total) or width))
+ return setlink(fore,rule,back,list)
+ else
+ rule = new_hlist(rule)
+ return setlink(fore,rule,list)
+ end
+ end
+end
+
+local templates = { }
+local currentrow = 0
+local enabled = false
+local alignments = false
+
+local function add_alignbackgrounds(head,list)
+ for current, id, subtype, list in nextlist, list do
+ if list and id == hlist_code and subtype == celllist_code then
+ for template in nexthlist, list do
+ local background = getattr(template,a_alignbackground)
if background then
- -- direct to hbox
- -- colorspace is already set so we can omit that and stick to color
- local mode = getattr(current,a_colormodel)
- if mode then
- local skip = id == hlist_code and width or (height + depth)
- local glue = new_glue(-skip)
- local rule = new_rule(width,height,depth)
- local color = getattr(current,a_color)
- local transparency = getattr(current,a_transparency)
- setattr(rule,a_colormodel,mode)
- if color then
- setattr(rule,a_color,color)
- end
- if transparency then
- setattr(rule,a_transparency,transparency)
- end
--- setlink(rule,glue)
--- if list then
--- setlink(glue,list)
--- end
--- setlist(current,rule)
- setlist(current,rule,glue,list)
+ local list = colored_a(current,list,template)
+ if list then
+ setlist(current,list)
end
+ setattr(template,a_alignbackground,unsetvalue) -- or property
end
+ break
end
end
- current = getnext(current)
end
- return head, true
+ local template = getprop(head,"alignmentchecked")
+ if template then
+ list = colored_b(head,list,template[1],hlist_code,template[2])
+ flush_node_list(template)
+ templates[currentrow] = false
+ return list
+ end
end
-local function add_alignbackgrounds(head)
- local current = head
- while current do
- local id = getid(current)
- if id == hlist_code then
- local list = getlist(current)
- if not list then
- -- no need to look
- elseif getsubtype(current) == cell_code then
- local background = nil
- local found = nil
- -- for l in traverse(list) do
- -- background = getattr(l,a_alignbackground)
- -- if background then
- -- found = l
- -- break
- -- end
- -- end
- -- we know that it's a fake hlist (could be user node)
- -- but we cannot store tables in user nodes yet
- for l in traverse_id(hpack_code,list) do
- background = getattr(l,a_alignbackground)
- if background then
- found = l
+local function add_backgrounds(head,id,list)
+ if list then
+ for current, id, subtype, list in nextlist, list do
+ if list then
+ if alignments and subtype == alignmentlist_code then
+ local l = add_alignbackgrounds(current,list)
+ if l then
+ list = l
+ setlist(current,list)
end
- break
end
- --
- if background then
- -- current has subtype 5 (cell)
- local width, height, depth = getwhd(current)
- if width > 0 then
- local mode = getattr(found,a_colormodel)
- if mode then
- local glue = new_glue(-width)
- local rule = new_rule(width,height,depth)
- local color = getattr(found,a_color)
- local transparency = getattr(found,a_transparency)
- setattr(rule,a_colormodel,mode)
- if color then
- setattr(rule,a_color,color)
- end
- if transparency then
- setattr(rule,a_transparency,transparency)
- end
- setlink(rule,glue)
- if list then
- setlink(glue,list)
- end
- setlist(current,rule)
- end
- end
+ local l = add_backgrounds(current,id,list)
+ if l then
+ list = l
+ setlist(current,l)
end
- else
- add_alignbackgrounds(list)
end
- elseif id == vlist_code then
- local list = getlist(current)
- if list then
- add_alignbackgrounds(list)
+ end
+ end
+ if id == hlist_code or id == vlist_code then
+ local background = getattr(head,a_background)
+ if background then
+ list = colored_a(head,list,head,id)
+ -- not needed
+ setattr(head,a_background,unsetvalue) -- or property
+ return list
+ end
+ end
+end
+
+function nodes.handlers.backgrounds(head)
+ add_backgrounds(head,getid(head),getlist(head))
+ return head
+end
+
+function nodes.handlers.backgroundspage(head,where)
+ if head and where == "alignment" then
+ for n in nexthlist, head do
+ local p = getprop(n,"alignmentchecked")
+ if not p and getsubtype(n) == alignmentlist_code then
+ currentrow = currentrow + 1
+ local template = templates[currentrow]
+ if trace_alignment then
+ report_alignment("%03i %s %s",currentrow,"page",template and "+" or "-")
+ end
+ setprop(n,"alignmentchecked",template)
end
end
- current = getnext(current)
end
- return head, true
+ return head
end
--- nodes.handlers.backgrounds = add_backgrounds
--- nodes.handlers.alignbackgrounds = add_alignbackgrounds
+function nodes.handlers.backgroundsvbox(head,where)
+ if head and where == "vbox" then
+ local list = getlist(head)
+ if list then
+ for n in nexthlist, list do
+ local p = getprop(n,"alignmentchecked")
+ if not p and getsubtype(n) == alignmentlist_code then
+ currentrow = currentrow + 1
+ local template = templates[currentrow]
+ if trace_alignment then
+ report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-")
+ end
+ setprop(n,"alignmentchecked",template)
+ end
+ end
+ end
+ end
+ return head
+end
-nodes.handlers.backgrounds = function(head) local head, done = add_backgrounds (tonut(head)) return tonode(head), done end
-nodes.handlers.alignbackgrounds = function(head) local head, done = add_alignbackgrounds(tonut(head)) return tonode(head), done end
+-- interfaces.implement {
+-- name = "enablebackgroundboxes",
+-- onlyonce = true,
+-- actions = enableaction,
+-- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
+-- }
+--
+-- doing it in the shipout works as well but this is nicer
+
+local function enable(alignmentstoo)
+ if not enabled then
+ enabled = true
+ enableaction("shipouts","nodes.handlers.backgrounds")
+ end
+ if not alignments and alignmentstoo then
+ alignments = true
+ enableaction("vboxbuilders","nodes.handlers.backgroundsvbox")
+ enableaction("mvlbuilders", "nodes.handlers.backgroundspage")
+ end
+end
interfaces.implement {
name = "enablebackgroundboxes",
onlyonce = true,
- actions = enableaction,
- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
+ actions = enable,
}
interfaces.implement {
name = "enablebackgroundalign",
onlyonce = true,
- actions = enableaction,
- arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" }
+ actions = function()
+ enable(true)
+ end,
+}
+
+interfaces.implement {
+ name = "setbackgroundrowdata",
+ arguments = { "integer", "integer", "dimension" },
+ actions = function(row,box,indent)
+ row = row -1 -- better here than in tex
+ if box == 0 then
+ templates[row] = false
+ else
+ templates[row] = { takebox(box), indent }
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "resetbackgroundrowdata",
+ actions = function()
+ currentrow = 0
+ end,
}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-bck.mkiv b/Master/texmf-dist/tex/context/base/mkiv/node-bck.mkiv
index 6bfc43d6a41..b093274430c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-bck.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-bck.mkiv
@@ -16,12 +16,10 @@
%D This is first attempt to replacing backgrounds in a few tables
%D mechanisms. When used more frequently, we can store the color
%D spec in the attribute.
-%D
-%D Maybe move some to the bar handler.
\unprotect
-\registerctxluafile{node-bck}{}
+\registerctxluafile{node-bck}{optimize}
% \backgroundvbox[green] {\input tufte } \par
% \backgroundvbox[blue] {\input ward } \par
@@ -74,6 +72,9 @@
\unexpanded\def\backgroundvbox{\node_backgrounds_boxes_add\vbox}
\unexpanded\def\backgroundvtop{\node_backgrounds_boxes_add\vtop}
+\unexpanded\def\backgroundline{\dontleavehmode
+ \node_backgrounds_boxes_add\hbox}
+
% \def\node_backgrounds_boxes_add#1[#2]%
% {\begingroup
% \clf_enablebackgroundboxes
@@ -90,18 +91,4 @@
{\clf_enablebackgroundboxes
#1\backgroundcolorattr{#2}}
-% less argument carry over:
-%
-% \def\node_backgrounds_boxes_add#1[#2]%
-% {\clf_enablebackgroundboxes#1%
-% \ifcsname\??colorattribute\currentcolorprefix#2\endcsname
-% \thebackgroundcolorattr{\currentcolorprefix#2}%
-% \else\ifcsname\??colorattribute#2\endcsname
-% \thebackgroundcolorattr{#2}%
-% \fi\fi}
-
-% \def\backgroundvbox[#1]{\vbox \backgroundcolorattr{#1}}
-% \def\backgroundvtop[#1]{\vtop \backgroundcolorattr{#1}}
-% \def\backgroundhbox[#1]{\hbox \backgroundcolorattr{#1}}
-
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-dir.lua b/Master/texmf-dist/tex/context/base/mkiv/node-dir.lua
index 59564ac93bd..3f0cba67e91 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-dir.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-dir.lua
@@ -6,304 +6,61 @@ if not modules then modules = { } end modules ['node-dir'] = {
license = "see context related readme files"
}
---[[
-In the process of cleaning up the lua variant of the parbuilder
-we ran into a couple of functions (translated c macros) that were
-somewhat inefficient. More convenient is to use hashes although at
-the c-end still macros are used. In the process directions.h was
-adapted and now has the mappings as comments. This lua file is
-based on that file.
-]]--
-
-local allocate = utilities.storage.allocate
-
-local nodes = nodes
-
-nodes.is_mirrored = allocate {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
-}
-
-nodes.is_rotated = allocate { -- used
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
-}
-
-nodes.textdir_is_parallel = allocate { -- used
- TLT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- TRT= {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- }
-}
-
-nodes.pardir_is_parallel = allocate {
- TLT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- TRT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
-}
-
-nodes.pardir_is_opposite = allocate {
- TLT = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- TRT = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- -- RTT = false,
- },
-}
-
-nodes.textdir_is_opposite = allocate { -- used
- TLT = {
- -- TLT = false,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- TRT= {
- TLT = true, ["+TLT"] = true,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
-}
-
-nodes.glyphdir_is_opposite = allocate {
- TLT = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- TRT= {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
-}
-
-nodes.pardir_is_equal = allocate { -- used
- TLT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- TRT= {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- LTL= {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- -- RTT = false,
- },
- RTT= {
- -- TLT = false,
- -- TRT = false,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
- },
-}
-
-nodes.textdir_is_equal = allocate { -- used
- TLT = {
- TLT = true, ["+TLT"] = true,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- TRT= {
- -- TLT = false,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
- RTT = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
-}
-
-nodes.glyphdir_is_equal = allocate { -- used
- TLT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
- },
- TRT= {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
- },
- LTL = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- -- RTT = false,
- },
- RTT = {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- RTT = true, ["+RTT"] = true,
- },
-}
-
-nodes.partextdir_is_equal = allocate {
- TLT = {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
- TRT= {
- -- TLT = false,
- -- TRT = false,
- LTL = true, ["+LTL"] = true,
- RTT = true, ["+RTT"] = true,
- },
- LTL = {
- TLT = true, ["+TLT"] = true,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
- },
- RTT = {
- -- TLT = false,
- TRT = true, ["+TRT"] = true,
- -- LTL = false,
- -- RTT = false,
- },
-}
-
-nodes.textdir_is_is = allocate {
- TLT = true, ["+TLT"] = true,
- -- TRT = false,
- -- LTL = false,
- -- RTT = false,
-}
-
-nodes.glyphdir_is_orthogonal = allocate {
- TLT = true, ["+TLT"] = true,
- TRT = true, ["+TRT"] = true,
- LTL = true, ["+LTL"] = true,
- -- RTT = false
-}
-
-nodes.dir_is_pop = allocate { -- used
- ["-TRT"] = true,
- ["-TLT"] = true,
- ["-LTL"] = true,
- ["-RTT"] = true,
-}
-
-nodes.dir_negation = allocate { -- used
- ["-TRT"] = "+TRT",
- ["-TLT"] = "+TLT",
- ["-LTL"] = "+LTL",
- ["-RTT"] = "+RTT",
- ["+TRT"] = "-TRT",
- ["+TLT"] = "-TLT",
- ["+LTL"] = "-LTL",
- ["+RTT"] = "-RTT",
-}
+-- This is experimental code, so when I change it I need to check other modules
+-- too.
+--
+-- Local par nodes are somewhat special. They start a paragraph and then register
+-- the par direction. But they can also show op mid paragraph in which case they
+-- register boxes and penalties. In that case the direction should not be affected.
+--
+-- We can assume that when hpack and prelinebreak filters are called, a local par
+-- still sits at the head, but after a linebreak pass this node can be after the
+-- leftskip (when present).
+
+local nodes = nodes
+local nuts = nodes.nuts
+
+local nodecodes = nodes.nodecodes
+local localpar_code = nodecodes.localpar
+
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getdirection = nuts.getdirection
+
+local dirvalues = nodes.dirvalues
+local lefttoright = dirvalues.lefttoright
+local righttoleft = dirvalues.righttoleft
+
+local localparnewgraf_code = 0
+
+local function newstack(head,direction)
+ local stack = { }
+ local top = 0
+ if head and getid(head) == localpar_code and getsubtype(head) == localparnewgraf_code then
+ direction = getdirection(head)
+ end
+ if not direction then
+ direction = lefttoright
+ elseif direction == "TLT" then
+ direction = lefttoright
+ elseif direction == "TRT" then
+ direction = righttoleft
+ end
+ local function update(node)
+ local dir, pop = getdirection(node)
+ if not pop then
+ top = top + 1
+ stack[top] = dir
+ return dir
+ elseif top == 0 then
+ return direction
+ elseif top == 1 then
+ top = 0
+ return direction
+ else
+ top = top - 1
+ return stack[top]
+ end
+ end
+ return direction, update
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua b/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
index 975eb0becc0..dc681d16556 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
@@ -16,16 +16,15 @@ local next, type, format = next, type, string.format
local attributes, nodes, node = attributes, nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
-local getprev = nuts.getprev
local getid = nuts.getid
local getlist = nuts.getlist
local getleader = nuts.getleader
local getattr = nuts.getattr
local getwidth = nuts.getwidth
+local getwhd = nuts.getwhd
+local getorientation = nuts.getorientation
local setlist = nuts.setlist
local setleader = nuts.setleader
@@ -34,10 +33,22 @@ local copy_node = nuts.copy
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
+local nextnode = nuts.traversers.node
+
local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
local rulecodes = nodes.rulecodes
+----- normalrule_code = rulecodes.normal
+local boxrule_code = rulecodes.box
+local imagerule_code = rulecodes.image
+local emptyrule_code = rulecodes.empty
+----- userrule_code = rulecodes.user
+----- overrule_code = rulecodes.over
+----- underrule_code = rulecodes.under
+----- fractionrule_code = rulecodes.fraction
+----- radicalrule_code = rulecodes.radical
+----- outlinerule_code = rulecodes.outline
+
local glyph_code = nodecodes.glyph
local disc_code = nodecodes.disc
local glue_code = nodecodes.glue
@@ -82,37 +93,34 @@ local finalizer = plugin.finalizer
local flusher = plugin.flusher
if not processor then
return function(head)
- return head, false
+ return head
end
elseif initializer or finalizer or resolver then
return function(head)
starttiming(attributes)
- local done, used, ok, inheritance = false, nil, false, nil
+ local used, inheritance
if resolver then
inheritance = resolver()
end
if initializer then
initializer(namespace,attribute,head)
end
- head, ok = processor(namespace,attribute,head,inheritance)
- if ok then
- if finalizer then
- head, ok, used = finalizer(namespace,attribute,head)
- if used and flusher then
- head = flusher(namespace,attribute,head,used)
- end
+ head = processor(namespace,attribute,head,inheritance)
+ if finalizer then
+ head, used = finalizer(namespace,attribute,head)
+ if used and flusher then
+ head = flusher(namespace,attribute,head,used)
end
- done = true
end
stoptiming(attributes)
- return head, done
+ return head
end
else
return function(head)
starttiming(attributes)
- local head, done = processor(namespace,attribute,head)
+ head = processor(namespace,attribute,head)
stoptiming(attributes)
- return head, done
+ return head
end
end
nodes.plugindata = nil
@@ -126,7 +134,7 @@ end
-- the injectors
local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger
-local current, current_selector, done = 0, 0, false -- nb, stack has a local current !
+local current, current_selector = 0, 0 -- nb, stack has a local current !
local nsbegin, nsend, nsreset
function states.initialize(namespace,attribute,head)
@@ -138,7 +146,6 @@ function states.initialize(namespace,attribute,head)
nstrigger = triggering and namespace.triggering and a_trigger
current = 0
current_selector = 0
- done = false -- todo: done cleanup
nsstep = namespace.resolve_step
if nsstep then
nsreset = namespace.resolve_reset
@@ -151,7 +158,6 @@ end
function states.finalize(namespace,attribute,head) -- is this one ok?
if current > 0 and nsnone then
- head = tonut(head)
local id = getid(head)
if id == hlist_code or id == vlist_code then
local content = getlist(head)
@@ -164,20 +170,17 @@ function states.finalize(namespace,attribute,head) -- is this one ok?
else
head = insert_node_before(head,head,copy_node(nsnone))
end
- return tonode(head), true, true
+ return head, true
end
- return head, false, false
+ return head, false
end
-- we need to deal with literals too (reset as well as oval)
local function process(attribute,head,inheritance,default) -- one attribute
- local stack = head
- local done = false
local check = false
local leader = nil
- while stack do
- local id = getid(stack)
+ for stack, id in nextnode, head do
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -188,39 +191,52 @@ local function process(attribute,head,inheritance,default) -- one attribute
elseif id == hlist_code or id == vlist_code then
local content = getlist(stack)
if content then
+ -- tricky checking
+ local outer
+ if getorientation(stack) then
+ outer = getattr(stack,attribute)
+ if outer then
+ if default and outer == inheritance then
+ if current ~= default then
+ head = insert_node_before(head,stack,copy_node(nsdata[default]))
+ current = default
+ end
+ elseif current ~= outer then
+ head = insert_node_before(head,stack,copy_node(nsdata[c]))
+ current = outer
+ end
+ elseif default and inheritance then
+ if current ~= default then
+ head = insert_node_before(head,stack,copy_node(nsdata[default]))
+ current = default
+ end
+ elseif current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ current = 0
+ end
+ end
-- begin nested --
+ local list
if nstrigger and getattr(stack,nstrigger) then
- local outer = getattr(stack,attribute)
+ if not outer then
+ outer = getattr(stack,attribute)
+ end
if outer ~= inheritance then
- local list, ok = process(attribute,content,inheritance,outer)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,outer)
else
- local list, ok = process(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,default)
end
else
- local list, ok = process(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,default)
+ end
+ if content ~= list then
+ setlist(stack,list)
end
-- end nested --
end
elseif id == rule_code then
- check = getwidth(stack) ~= 0
+ local wd, ht, dp = getwhd(stack)
+ check = wd ~= 0 or (ht+dp) ~= 0
end
-- much faster this way than using a check() and nested() function
if check then
@@ -230,12 +246,10 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
- done = true
end
elseif current ~= c then
head = insert_node_before(head,stack,copy_node(nsdata[c]))
current = c
- done = true
end
if leader then
local savedcurrent = current
@@ -247,33 +261,19 @@ local function process(attribute,head,inheritance,default) -- one attribute
current = 0
end
-- begin nested --
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = process(attribute,leader,inheritance,outer)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,outer)
else
- local list, ok = process(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,default)
end
else
- local list, ok = process(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,default)
+ end
+ if leader ~= list then
+ setleader(stack,list)
end
-- end nested --
current = savedcurrent
@@ -283,23 +283,19 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
- done = true
end
elseif current > 0 then
head = insert_node_before(head,stack,copy_node(nsnone))
current = 0
- done = true
end
check = false
end
- stack = getnext(stack)
end
- return head, done
+ return head
end
states.process = function(namespace,attribute,head,default)
- local head, done = process(attribute,tonut(head),default)
- return tonode(head), done
+ return process(attribute,head,default)
end
-- we can force a selector, e.g. document wide color spaces, saves a little
@@ -309,13 +305,9 @@ end
-- each other with the same color but different color spaces e.g. \showcolor)
local function selective(attribute,head,inheritance,default) -- two attributes
- -- local head = head
- local stack = head
- local done = false
local check = false
local leader = nil
- while stack do
- local id = getid(stack)
+ for stack, id, subtype in nextnode, head do
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -326,41 +318,66 @@ local function selective(attribute,head,inheritance,default) -- two attributes
elseif id == hlist_code or id == vlist_code then
local content = getlist(stack)
if content then
+ -- tricky checking
+ local outer
+ if getorientation(stack) then
+ outer = getattr(stack,attribute)
+ if outer then
+ if default and outer == inheritance then
+ if current ~= default then
+ local data = nsdata[default]
+ head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
+ current = default
+ end
+ else
+ local s = getattr(stack,nsselector)
+ -- local s = nsforced or getattr(stack,nsselector)
+ if current ~= outer or current_selector ~= s then
+ local data = nsdata[outer]
+ head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
+ current = outer
+ current_selector = s
+ end
+ end
+ elseif default and inheritance then
+ if current ~= default then
+ local data = nsdata[default]
+ head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
+ current = default
+ end
+ elseif current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ current, current_selector = 0, 0
+ end
+ end
-- begin nested
+ local list
if nstrigger and getattr(stack,nstrigger) then
- local outer = getattr(stack,attribute)
+ if not outer then
+ outer = getattr(stack,attribute)
+ end
if outer ~= inheritance then
- local list, ok = selective(attribute,content,inheritance,outer)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,outer)
else
- local list, ok = selective(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,default)
end
else
- local list, ok = selective(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,default)
+ end
+ if content ~= list then
+ setlist(stack,list)
end
-- end nested
end
elseif id == rule_code then
- check = getwidth(stack) ~= 0
+ if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then
+ -- so no redundant color stuff (only here, layers for instance should obey)
+ check = false
+ else
+ local wd, ht, dp = getwhd(stack)
+ check = wd ~= 0 or (ht+dp) ~= 0
+ end
end
-
if check then
local c = getattr(stack,attribute)
if c then
@@ -369,9 +386,6 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
- if ok then
- done = true
- end
end
else
local s = getattr(stack,nsselector)
@@ -379,43 +393,25 @@ local function selective(attribute,head,inheritance,default) -- two attributes
if current ~= c or current_selector ~= s then
local data = nsdata[c]
head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
- -- head = insert_node_before(head,stack,copy_node(data[s or nsselector]))
current = c
current_selector = s
- if ok then
- done = true
- end
end
end
if leader then
-- begin nested
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = selective(attribute,leader,inheritance,outer)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,outer)
else
- local list, ok = selective(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,default)
end
else
- local list, ok = selective(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,default)
+ end
+ if leader ~= list then
+ setleader(stack,list)
end
-- end nested
leader = false
@@ -425,22 +421,19 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
- done = true
end
elseif current > 0 then
head = insert_node_before(head,stack,copy_node(nsnone))
- current, current_selector, done = 0, 0, true
+ current, current_selector = 0, 0
end
check = false
end
- stack = getnext(stack)
end
- return head, done
+ return head
end
states.selective = function(namespace,attribute,head,default)
- local head = selective(attribute,tonut(head),default)
- return tonode(head), true
+ return selective(attribute,head,default)
end
-- Ideally the next one should be merged with the previous but keeping it separate is
@@ -454,7 +447,6 @@ end
local function stacked(attribute,head,default) -- no triggering, no inheritance, but list-wise
local stack = head
- local done = false
local current = default or 0
local depth = 0
local check = false
@@ -472,42 +464,30 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
local content = getlist(stack)
if content then
-- the problem is that broken lines gets the attribute which can be a later one
+ local list
if nslistwise then
local a = getattr(stack,attribute)
if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below
local p = current
current = a
head = insert_node_before(head,stack,copy_node(nsdata[a]))
- local list = stacked(attribute,content,current) -- two return values
- if content ~= list then
- setlist(stack,list)
- end
+ list = stacked(attribute,content,current) -- two return values
head, stack = insert_node_after(head,stack,copy_node(nsnone))
current = p
- done = true
else
- local list, ok = stacked(attribute,content,current)
- if content ~= list then
- setlist(stack,list) -- only if ok
- end
- if ok then
- done = true
- end
+ list = stacked(attribute,content,current)
end
else
- local list, ok = stacked(attribute,content,current)
- if content ~= list then
- setlist(stack,list) -- only if ok
- end
- if ok then
- done = true
- end
+ list = stacked(attribute,content,current)
+ end
+ if content ~= list then
+ setlist(stack,list) -- only if ok
end
end
elseif id == rule_code then
- check = getwidth(stack) ~= 0
+ local wd, ht, dp = getwhd(stack)
+ check = wd ~= 0 or (ht+dp) ~= 0
end
-
if check then
local a = getattr(stack,attribute)
if a then
@@ -515,15 +495,14 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsdata[a]))
depth = depth + 1
current = a
- done = true
end
if leader then
- local list, ok = stacked(attribute,content,current)
- if leader ~= list then
- setleader(stack,list) -- only if ok
- end
- if ok then
- done = true
+ local content = getlist(leader)
+ if content then
+ local list = stacked(attribute,content,current)
+ if leader ~= list then
+ setleader(stack,list) -- only if ok
+ end
end
leader = false
end
@@ -533,7 +512,6 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsnone))
depth = depth - 1
current = 0
- done = true
end
check = false
end
@@ -543,24 +521,22 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_after(head,stack,copy_node(nsnone))
depth = depth - 1
end
- return head, done
+ return head
end
states.stacked = function(namespace,attribute,head,default)
- local head, done = stacked(attribute,tonut(head),default)
- return tonode(head), done
+ return stacked(attribute,head,default)
end
-- experimental
local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
--- nsbegin()
+ -- nsbegin()
local stacked = false
local current = head
local previous = head
- local done = false
local attrib = default or unsetvalue
local check = false
local leader = false
@@ -576,38 +552,27 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
elseif id == hlist_code or id == vlist_code then
local content = getlist(current)
- if not content then
- -- skip
- elseif nslistwise then
- local a = getattr(current,attribute)
- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
- head = insert_node_before(head,current,copy_node(nsdata[a]))
- local list = stacker(attribute,content,a)
- if list ~= content then
- setlist(current,list)
+ if content then
+ local list
+ if nslistwise then
+ local a = getattr(current,attribute)
+ if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+ head = insert_node_before(head,current,copy_node(nsdata[a]))
+ list = stacker(attribute,content,a)
+ head, current = insert_node_after(head,current,copy_node(nsnone))
+ else
+ list = stacker(attribute,content,attrib)
end
- done = true
- head, current = insert_node_after(head,current,copy_node(nsnone))
else
- local list, ok = stacker(attribute,content,attrib)
- if content ~= list then
- setlist(current,list)
- end
- if ok then
- done = true
- end
+ list = stacker(attribute,content,default)
end
- else
- local list, ok = stacker(attribute,content,default)
if list ~= content then
setlist(current,list)
end
- if ok then
- done = true
- end
end
elseif id == rule_code then
- check = getwidth(current) ~= 0
+ local wd, ht, dp = getwhd(current)
+ check = wd ~= 0 or (ht+dp) ~= 0
end
if check then
@@ -619,16 +584,22 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
local n = nsstep(a)
if n then
- head = insert_node_before(head,current,tonut(n)) -- a
+ head = insert_node_before(head,current,n) -- a
end
attrib = a
- done = true
if leader then
-- tricky as a leader has to be a list so we cannot inject before
- local list, ok = stacker(attribute,leader,attrib)
- if ok then
- done = true
+ -- local list = stacker(attribute,leader,attrib)
+ -- leader = false
+
+ local content = getlist(leader)
+ if content then
+ local list = stacker(attribute,leader,attrib)
+ if leader ~= list then
+ setleader(current,list)
+ end
end
+
leader = false
end
end
@@ -642,18 +613,101 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
if stacked then
local n = nsend()
while n do
- head = insert_node_after(head,previous,tonut(n))
+ head = insert_node_after(head,previous,n)
n = nsend()
end
end
- return head, done
+ return head
end
+-- local nextid = nodes.nuts.traversers.id
+--
+-- local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
+--
+-- -- nsbegin()
+-- local stacked = false
+--
+-- local current = head
+-- local previous = head
+-- local attrib = default or unsetvalue
+-- local check = false
+-- local leader = false
+--
+-- local id = getid(current)
+-- while current do
+-- if id == glyph_code then
+-- check = true
+-- elseif id == glue_code then
+-- leader = getleader(current)
+-- if leader then
+-- check = true
+-- end
+-- elseif id == hlist_code or id == vlist_code then
+-- local content = getlist(current)
+-- if content then
+-- local list
+-- if nslistwise then
+-- local a = getattr(current,attribute)
+-- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+-- head = insert_node_before(head,current,copy_node(nsdata[a]))
+-- list = stacker(attribute,content,a)
+-- head, current = insert_node_after(head,current,copy_node(nsnone))
+-- else
+-- list = stacker(attribute,content,attrib)
+-- end
+-- else
+-- list = stacker(attribute,content,default)
+-- end
+-- if list ~= content then
+-- setlist(current,list)
+-- end
+-- end
+-- elseif id == rule_code then
+-- check = getwidth(current) ~= 0
+-- end
+--
+-- if check then
+-- local a = getattr(current,attribute) or unsetvalue
+-- if a ~= attrib then
+-- if not stacked then
+-- stacked = true
+-- nsbegin()
+-- end
+-- local n = nsstep(a)
+-- if n then
+-- head = insert_node_before(head,current,n) -- a
+-- end
+-- attrib = a
+-- if leader then
+-- -- tricky as a leader has to be a list so we cannot inject before
+-- local list = stacker(attribute,leader,attrib)
+-- leader = false
+-- end
+-- end
+-- check = false
+-- end
+--
+-- previous = current
+--
+-- current, id = nextid(current,current)
+-- end
+--
+-- if stacked then
+-- local n = nsend()
+-- while n do
+-- head = insert_node_after(head,previous,n)
+-- n = nsend()
+-- end
+-- end
+--
+-- return head
+-- end
+
states.stacker = function(namespace,attribute,head,default)
- local head, done = stacker(attribute,tonut(head),default)
+ local head = stacker(attribute,head,default)
nsreset()
- return tonode(head), done
+ return head
end
-- -- --
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-fin.mkiv b/Master/texmf-dist/tex/context/base/mkiv/node-fin.mkiv
index 4f1ff2aba41..086b19ae5dc 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-fin.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-fin.mkiv
@@ -18,8 +18,8 @@
\unprotect
-\registerctxluafile{node-shp}{}
-\registerctxluafile{node-fin}{} % we might generalize this one
+\registerctxluafile{node-shp}{optimize}
+\registerctxluafile{node-fin}{optimize} % we might generalize this one
% we might have two variants at some point (efficiency)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-fnt.lua b/Master/texmf-dist/tex/context/base/mkiv/node-fnt.lua
index f846f996d52..154853121d0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-fnt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-fnt.lua
@@ -37,22 +37,20 @@ local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
local nodecodes = nodes.nodecodes
+local boundarycodes = nodes.boundarycodes
+
local handlers = nodes.handlers
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getattr = nuts.getattr
local getid = nuts.getid
-local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
local getdisc = nuts.getdisc
local getnext = nuts.getnext
local getprev = nuts.getprev
local getboth = nuts.getboth
-local getfield = nuts.getfield
+local getdata = nuts.getdata
----- getdisc = nuts.getdisc
local setchar = nuts.setchar
local setlink = nuts.setlink
@@ -62,14 +60,18 @@ local setprev = nuts.setprev
local isglyph = nuts.isglyph -- unchecked
local ischar = nuts.ischar -- checked
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
-local protect_glyph = nuts.protect_glyph
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextboundary = nuts.traversers.boundary
+local nextdisc = nuts.traversers.disc
+local nextchar = nuts.traversers.char
+
local flush_node = nuts.flush
local disc_code = nodecodes.disc
local boundary_code = nodecodes.boundary
-local word_boundary = nodes.boundarycodes.word
+
+local wordboundary_code = boundarycodes.word
local protect_glyphs = nuts.protect_glyphs
local unprotect_glyphs = nuts.unprotect_glyphs
@@ -144,10 +146,10 @@ local kerning = nuts.kerning
-- -- -- this will go away
--
--- local disccodes = nodes.disccodes
--- local explicit_code = disccodes.explicit
--- local automatic_code = disccodes.automatic
--- local expanders = nil
+-- local disccodes = nodes.disccodes
+-- local explicitdisc_code = disccodes.explicit
+-- local automaticdisc_code = disccodes.automatic
+-- local expanders = nil
--
-- function fonts.setdiscexpansion(v)
-- if v == nil or v == true then
@@ -172,17 +174,17 @@ local function start_trace(head)
report_fonts()
report_fonts("checking node list, run %s",run)
report_fonts()
- local n = tonut(head)
+ local n = head
while n do
local char, id = isglyph(n)
if char then
- local font = getfont(n)
+ local font = id
local attr = getattr(n,0) or 0
report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char)
elseif id == disc_code then
report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n))
elseif id == boundary_code then
- report_fonts("[boundary] %i:%i",getsubtype(n),getfield(n,"value"))
+ report_fonts("[boundary] %i:%i",getsubtype(n),getdata(n))
else
report_fonts("[%s]",nodecodes[id])
end
@@ -202,32 +204,23 @@ local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expa
report_fonts()
end
-function handlers.characters(head,groupcode,size,packtype,direction)
- -- either next or not, but definitely no already processed list
- starttiming(nodes)
-
- local usedfonts = { }
- local attrfonts = { }
- local basefonts = { }
- local basefont = nil
- local prevfont = nil
- local prevattr = 0
- local done = false
- local variants = nil
- local redundant = nil
- local nuthead = tonut(head)
- local lastfont = nil
- local lastproc = nil
- local lastnone = nil
-
- local a, u, b, r, e = 0, 0, 0, 0, 0
-
- if trace_fontrun then
- start_trace(head)
- end
- -- There is no gain in checking for a single glyph and then having a fast path. On the
- -- metafun manual (with some 2500 single char lists) the difference is just noise.
+do
+
+ local usedfonts
+ local attrfonts
+ local basefonts
+ local basefont
+ local prevfont
+ local prevattr
+ local variants
+ local redundant
+ local firstnone
+ local lastfont
+ local lastproc
+ local lastnone
+
+ local a, u, b, r, e
local function protectnone()
protect_glyphs(firstnone,lastnone)
@@ -296,288 +289,290 @@ function handlers.characters(head,groupcode,size,packtype,direction)
end
end
- for n in traverse_char(nuthead) do
- local font = getfont(n)
- -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
- local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
- if font ~= prevfont or attr ~= prevattr then
- prevfont = font
- prevattr = attr
- variants = fontvariants[font]
- local fontmode = fontmodes[font]
- if fontmode == "none" then
- setnone(n)
- elseif fontmode == "base" then
- setbase(n)
- else
- setnode(n,font,attr)
- end
- elseif firstnone then
- lastnone = n
+ function handlers.characters(head,groupcode,size,packtype,direction)
+ -- either next or not, but definitely no already processed list
+ starttiming(nodes)
+
+ usedfonts = { }
+ attrfonts = { }
+ basefonts = { }
+ basefont = nil
+ prevfont = nil
+ prevattr = 0
+ variants = nil
+ redundant = nil
+ firstnone = nil
+ lastfont = nil
+ lastproc = nil
+ lastnone = nil
+
+ a, u, b, r, e = 0, 0, 0, 0, 0
+
+ if trace_fontrun then
+ start_trace(head)
end
- if variants then
- local char = getchar(n)
- if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then
- local hash = variants[char]
- if hash then
- local p = getprev(n)
- if p then
- local char = ischar(p) -- checked
- local variant = hash[char]
- if variant then
- if trace_variants then
- report_fonts("replacing %C by %C",char,variant)
- end
- setchar(p,variant)
- if redundant then
- r = r + 1
- redundant[r] = n
- else
- r = 1
- redundant = { n }
+
+ -- There is no gain in checking for a single glyph and then having a fast path. On the
+ -- metafun manual (with some 2500 single char lists) the difference is just noise.
+
+ for n, char, font in nextchar, head do
+ -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context
+ if font ~= prevfont or attr ~= prevattr then
+ prevfont = font
+ prevattr = attr
+ variants = fontvariants[font]
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
+ else
+ setnode(n,font,attr)
+ end
+ elseif firstnone then
+ lastnone = n
+ end
+ if variants then
+ if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then
+ local hash = variants[char]
+ if hash then
+ local p = getprev(n)
+ if p then
+ local char = ischar(p) -- checked
+ local variant = hash[char]
+ if variant then
+ if trace_variants then
+ report_fonts("replacing %C by %C",char,variant)
+ end
+ setchar(p,variant)
+ if redundant then
+ r = r + 1
+ redundant[r] = n
+ else
+ r = 1
+ redundant = { n }
+ end
end
end
+ elseif keep_redundant then
+ -- go on, can be used for tracing
+ elseif redundant then
+ r = r + 1
+ redundant[r] = n
+ else
+ r = 1
+ redundant = { n }
end
- elseif keep_redundant then
- -- go on, can be used for tracing
- elseif redundant then
- r = r + 1
- redundant[r] = n
- else
- r = 1
- redundant = { n }
end
end
end
- end
- if firstnone then
- protectnone()
- end
+ if firstnone then
+ protectnone()
+ end
- if force_boundaryrun then
+ if force_boundaryrun then
- -- we can inject wordboundaries and then let the hyphenator do its work
- -- but we need to get rid of those nodes in order to build ligatures
- -- and kern (a rather context thing)
+ -- we can inject wordboundaries and then let the hyphenator do its work
+ -- but we need to get rid of those nodes in order to build ligatures
+ -- and kern (a rather context thing)
- for b in traverse_id(boundary_code,nuthead) do
- if getsubtype(b) == word_boundary then
- if redundant then
- r = r + 1
- redundant[r] = b
- else
- r = 1
- redundant = { b }
+ for b, subtype in nextboundary, head do
+ if subtype == wordboundary_code then
+ if redundant then
+ r = r + 1
+ redundant[r] = b
+ else
+ r = 1
+ redundant = { b }
+ end
end
end
- end
- end
+ end
- if redundant then
- for i=1,r do
- local r = redundant[i]
- local p, n = getboth(r)
- if r == nuthead then
- nuthead = n
- setprev(n)
- else
- setlink(p,n)
- end
- if b > 0 then
- for i=1,b do
- local bi = basefonts[i]
- local b1 = bi[1]
- local b2 = bi[2]
- if b1 == b2 then
- if b1 == r then
- bi[1] = false
- bi[2] = false
+ if redundant then
+ for i=1,r do
+ local r = redundant[i]
+ local p, n = getboth(r)
+ if r == head then
+ head = n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if b > 0 then
+ for i=1,b do
+ local bi = basefonts[i]
+ local b1 = bi[1]
+ local b2 = bi[2]
+ if b1 == b2 then
+ if b1 == r then
+ bi[1] = false
+ bi[2] = false
+ end
+ elseif b1 == r then
+ bi[1] = n
+ elseif b2 == r then
+ bi[2] = p
end
- elseif b1 == r then
- bi[1] = n
- elseif b2 == r then
- bi[2] = p
end
end
+ flush_node(r)
end
- flush_node(r)
end
- end
- if force_discrun then
-
- -- basefont is not supported in disc only runs ... it would mean a lot of
- -- ranges .. we could try to run basemode as a separate processor run but
- -- not for now (we can consider it when the new node code is tested
- for d in traverse_id(disc_code,nuthead) do
- -- we could use first_glyph, only doing replace is good enough because
- -- pre and post are normally used for hyphens and these come from fonts
- -- that part of the hyphenated word
- local _, _, r = getdisc(d)
- if r then
- local prevfont = nil
- local prevattr = nil
- local none = false
- for n in traverse_char(r) do
- local font = getfont(n)
- local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
- if font ~= prevfont or attr ~= prevattr then
- prevfont = font
- prevattr = attr
- local fontmode = fontmodes[font]
- if fontmode == "none" then
- setnone(n)
- elseif fontmode == "base" then
- setbase(n)
- else
- setnode(n,font,attr)
+ if force_discrun then
+
+ -- basefont is not supported in disc only runs ... it would mean a lot of
+ -- ranges .. we could try to run basemode as a separate processor run but
+ -- not for now (we can consider it when the new node code is tested
+ for d in nextdisc, head do
+ -- we could use first_glyph, only doing replace is good enough because
+ -- pre and post are normally used for hyphens and these come from fonts
+ -- that part of the hyphenated word
+ local _, _, r = getdisc(d)
+ if r then
+ local prevfont = nil
+ local prevattr = nil
+ local none = false
+ for n, char, font in nextchar, r do
+ local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context
+ if font ~= prevfont or attr ~= prevattr then
+ prevfont = font
+ prevattr = attr
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
+ else
+ setnode(n,font,attr)
+ end
+ elseif firstnone then
+ -- lastnone = n
+ lastnone = nil
end
- elseif firstnone then
- -- lastnone = n
- lastnone = nil
+ -- we assume one font for now (and if there are more and we get into issues then
+ -- we can always remove the break)
+ break
end
- -- we assume one font for now (and if there are more and we get into issues then
- -- we can always remove the break)
- break
- end
- if firstnone then
- protectnone()
+ if firstnone then
+ protectnone()
+ end
+ -- elseif expanders then
+ -- local subtype = getsubtype(d)
+ -- if subtype == automaticdisc_code or subtype == explicitdisc_code then
+ -- expanders[subtype](d)
+ -- e = e + 1
+ -- end
end
- -- elseif expanders then
- -- local subtype = getsubtype(d)
- -- if subtype == automatic_code or subtype == explicit_code then
- -- expanders[subtype](d)
- -- e = e + 1
- -- end
end
- end
-
- end
- if trace_fontrun then
- stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders)
- end
+ end
- -- in context we always have at least 2 processors
- if u == 0 then
- -- skip
- elseif u == 1 then
- local attr = a > 0 and 0 or false -- 0 is the savest way
- for i=1,#lastproc do
- local h, d = lastproc[i](head,lastfont,attr,direction)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ if trace_fontrun then
+ stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders)
end
- else
- -- local attr = a == 0 and false or 0 -- 0 is the savest way
- local attr = a > 0 and 0 or false -- 0 is the savest way
- for font, processors in next, usedfonts do -- unordered
- for i=1,#processors do
- local h, d = processors[i](head,font,attr,direction,u)
- if d then
- if h then
- head = h
- end
- done = true
- end
+
+ -- in context we always have at least 2 processors
+ if u == 0 then
+ -- skip
+ elseif u == 1 then
+ local attr = a > 0 and 0 or false -- 0 is the savest way
+ for i=1,#lastproc do
+ head = lastproc[i](head,lastfont,attr,direction)
end
- end
- end
- if a == 0 then
- -- skip
- elseif a == 1 then
- local font, dynamics = next(attrfonts)
- for attribute, processors in next, dynamics do -- unordered, attr can switch in between
- for i=1,#processors do
- local h, d = processors[i](head,font,attribute,direction)
- if d then
- if h then
- head = h
- end
- done = true
+ else
+ -- local attr = a == 0 and false or 0 -- 0 is the savest way
+ local attr = a > 0 and 0 or false -- 0 is the savest way
+ for font, processors in next, usedfonts do -- unordered
+ for i=1,#processors do
+ head = processors[i](head,font,attr,direction,u)
end
end
end
- else
- for font, dynamics in next, attrfonts do
+ if a == 0 then
+ -- skip
+ elseif a == 1 then
+ local font, dynamics = next(attrfonts)
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute,direction,a)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ head = processors[i](head,font,attribute,direction)
end
end
- end
- end
- if b == 0 then
- -- skip
- elseif b == 1 then
- -- only one font
- local range = basefonts[1]
- local start = range[1]
- local stop = range[2]
- if (start or stop) and (start ~= stop) then
- local front = nuthead == start
- if stop then
- start = ligaturing(start,stop)
- start = kerning(start,stop)
- elseif start then -- safeguard
- start = ligaturing(start)
- start = kerning(start)
- end
- if front and nuthead ~= start then
- -- nuthead = start
- head = tonode(start)
+ else
+ for font, dynamics in next, attrfonts do
+ for attribute, processors in next, dynamics do -- unordered, attr can switch in between
+ for i=1,#processors do
+ head = processors[i](head,font,attribute,direction,a)
+ end
+ end
end
end
- else
- -- multiple fonts
- for i=1,b do
- local range = basefonts[i]
+ if b == 0 then
+ -- skip
+ elseif b == 1 then
+ -- only one font
+ local range = basefonts[1]
local start = range[1]
local stop = range[2]
- if start then -- and start ~= stop but that seldom happens
- local front = nuthead == start
- local prev = getprev(start)
- local next = getnext(stop)
+ if (start or stop) and (start ~= stop) then
+ local front = head == start
if stop then
- start, stop = ligaturing(start,stop)
- start, stop = kerning(start,stop)
- else
+ start = ligaturing(start,stop)
+ start = kerning(start,stop)
+ elseif start then -- safeguard
start = ligaturing(start)
start = kerning(start)
end
- -- is done automatically
- if prev then
- setlink(prev,start)
- end
- if next then
- setlink(stop,next)
+ if front and head ~= start then
+ head = start
end
- -- till here
- if front and nuthead ~= start then
- nuthead = start
- head = tonode(start)
+ end
+ else
+ -- multiple fonts
+ for i=1,b do
+ local range = basefonts[i]
+ local start = range[1]
+ local stop = range[2]
+ if start then -- and start ~= stop but that seldom happens
+ local front = head == start
+ local prev = getprev(start)
+ local next = getnext(stop)
+ if stop then
+ start, stop = ligaturing(start,stop)
+ start, stop = kerning(start,stop)
+ else
+ start = ligaturing(start)
+ start = kerning(start)
+ end
+ -- is done automatically
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ -- till here
+ if front and head ~= start then
+ head = start
+ end
end
end
end
+
+ stoptiming(nodes)
+
+ if trace_characters then
+ nodes.report(head)
+ end
+
+ return head
end
- stoptiming(nodes)
- if trace_characters then
- nodes.report(head,done)
- end
- return head, true
+
end
-handlers.protectglyphs = function(n) protect_glyphs (tonut(n)) return n, true end
-handlers.unprotectglyphs = function(n) unprotect_glyphs(tonut(n)) return n, true end
+handlers.protectglyphs = protect_glyphs
+handlers.unprotectglyphs = unprotect_glyphs
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua
index 50da140ce98..f910c7e012f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua
@@ -70,6 +70,12 @@ local formatcolumns = utilities.formatters.formatcolumns
local getsubtypes = node.subtypes
local getvalues = node.values
+tex.magicconstants = { -- we use tex.constants for something else
+ running = -1073741824,
+ maxdimen = 1073741823, -- 0x3FFFFFFF or 2^30-1
+ trueinch = 4736286,
+}
+
-- local listcodes = allocate {
-- [0] = "unknown",
-- [1] = "line",
@@ -108,12 +114,11 @@ dircodes = allocate {
}
-- local glyphcodes = allocate {
--- [0] = "character",
--- [1] = "glyph",
--- [2] = "ligature",
--- [3] = "ghost",
--- [4] = "left",
--- [5] = "right",
+-- [ 1] = "character",
+-- [ 2] = "ligature",
+-- [ 4] = "ghost",
+-- [ 8] = "left",
+-- [16] = "right",
-- }
local glyphcodes = mark(getsubtypes("glyph"))
@@ -281,11 +286,12 @@ local function simplified(t)
end
local nodecodes = simplified(node.types())
-local whatcodes = simplified(node.whatsits())
+local whatcodes = simplified(node.whatsits and node.whatsits() or { })
local usercodes = allocate {
[ 97] = "attribute", -- a
[100] = "number", -- d
+ [102] = "float", -- f
[108] = "lua", -- l
[110] = "node", -- n
[115] = "string", -- s
@@ -306,7 +312,7 @@ local noadoptions = allocate {
-- local directionvalues = mark(getvalues("dir"))
-- local gluevalues = mark(getvalues("glue"))
--- local pdfliteralvalues = mark(getvalues("pdf_literal"))
+-- local literalvalues = mark(getvalues("literal"))
local dirvalues = allocate {
[0] = "TLT",
@@ -323,7 +329,7 @@ local gluevalues = allocate {
[4] = "filll",
}
-local pdfliteralvalues = allocate {
+local literalvalues = allocate {
[0] = "origin",
[1] = "page",
[2] = "always",
@@ -356,41 +362,90 @@ usercodes = allocate(swapped(usercodes,usercodes))
noadoptions = allocate(swapped(noadoptions,noadoptions))
dirvalues = allocate(swapped(dirvalues,dirvalues))
gluevalues = allocate(swapped(gluevalues,gluevalues))
-pdfliteralvalues = allocate(swapped(pdfliteralvalues,pdfliteralvalues))
-
-nodes.gluecodes = gluecodes
-nodes.dircodes = dircodes
-nodes.boundarycodes = boundarycodes
-nodes.noadcodes = noadcodes
-nodes.nodecodes = nodecodes
-nodes.whatcodes = whatcodes
-nodes.listcodes = listcodes
-nodes.glyphcodes = glyphcodes
-nodes.kerncodes = kerncodes
-nodes.penaltycodes = penaltycodes
-nodes.mathcodes = mathcodes
-nodes.fillcodes = fillcodes
-nodes.margincodes = margincodes
-nodes.disccodes = disccodes
-nodes.accentcodes = accentcodes
-nodes.radicalcodes = radicalcodes
-nodes.fencecodes = fencecodes
-nodes.rulecodes = rulecodes
-nodes.leadercodes = leadercodes
-nodes.usercodes = usercodes
-nodes.noadoptions = noadoptions
-nodes.dirvalues = dirvalues
-nodes.gluevalues = gluevalues
-nodes.pdfliteralvalues = pdfliteralvalues
-
-nodes.skipcodes = gluecodes -- more friendly
-nodes.directioncodes = dircodes -- more friendly
-nodes.whatsitcodes = whatcodes -- more official
-nodes.marginkerncodes = margincodes
-nodes.discretionarycodes = disccodes
-nodes.directionvalues = dirvalues -- more friendly
-nodes.skipvalues = gluevalues -- more friendly
-nodes.literalvalues = pdfliteralvalues -- more friendly
+literalvalues = allocate(swapped(literalvalues,literalvalues))
+
+if CONTEXTLMTXMODE > 1 then
+ whatcodes.literal = 0x1 whatcodes[0x1] = "literal"
+ whatcodes.latelua = 0x2 whatcodes[0x2] = "latelua"
+ whatcodes.userdefined = 0x3 whatcodes[0x3] = "userdefined"
+ whatcodes.savepos = 0x4 whatcodes[0x4] = "savepos"
+ whatcodes.save = 0x5 whatcodes[0x5] = "save"
+ whatcodes.restore = 0x6 whatcodes[0x6] = "restore"
+ whatcodes.setmatrix = 0x7 whatcodes[0x7] = "setmatrix"
+ whatcodes.open = 0x8 whatcodes[0x8] = "open"
+ whatcodes.close = 0x9 whatcodes[0x9] = "close"
+ whatcodes.write = 0xA whatcodes[0xA] = "write"
+elseif not whatcodes.literal then
+ whatcodes.literal = whatcodes.pdfliteral
+ whatcodes.save = whatcodes.pdfsave
+ whatcodes.restore = whatcodes.pdfrestore
+ whatcodes.setmatrix = whatcodes.pdfsetmatrix
+end
+
+nodes.gluecodes = gluecodes
+nodes.dircodes = dircodes
+nodes.boundarycodes = boundarycodes
+nodes.noadcodes = noadcodes
+nodes.nodecodes = nodecodes
+nodes.whatcodes = whatcodes
+nodes.listcodes = listcodes
+nodes.glyphcodes = glyphcodes
+nodes.kerncodes = kerncodes
+nodes.penaltycodes = penaltycodes
+nodes.mathcodes = mathcodes
+nodes.fillcodes = fillcodes
+nodes.margincodes = margincodes
+nodes.disccodes = disccodes
+nodes.accentcodes = accentcodes
+nodes.radicalcodes = radicalcodes
+nodes.fencecodes = fencecodes
+nodes.rulecodes = rulecodes
+nodes.leadercodes = leadercodes
+nodes.usercodes = usercodes
+nodes.noadoptions = noadoptions
+nodes.dirvalues = dirvalues
+nodes.gluevalues = gluevalues
+nodes.literalvalues = literalvalues
+
+dirvalues.lefttoright = 0
+dirvalues.righttoleft = 1
+
+nodes.subtypes = allocate {
+ [nodecodes.accent] = accentcodes,
+ [nodecodes.boundary] = boundarycodes,
+ [nodecodes.dir] = dircodes,
+ [nodecodes.disc] = disccodes,
+ [nodecodes.fence] = fencecodes,
+ [nodecodes.glue] = gluecodes,
+ [nodecodes.glyph] = glyphcodes,
+ [nodecodes.hlist] = listcodes,
+ [nodecodes.kern] = kerncodes,
+ [nodecodes.marginkern] = margincodes,
+ [nodecodes.math] = mathcodes,
+ [nodecodes.noad] = noadcodes,
+ [nodecodes.penalty] = penaltycodes,
+ [nodecodes.radical] = radicalcodes,
+ [nodecodes.rule] = rulecodes,
+ [nodecodes.vlist] = listcodes,
+ [nodecodes.whatsit] = whatcodes,
+}
+
+table.setmetatableindex(nodes.subtypes,function(t,k)
+ local v = { }
+ t[k] = v
+ return v
+end)
+
+nodes.skipcodes = gluecodes -- more friendly
+nodes.directioncodes = dircodes -- more friendly
+nodes.whatsitcodes = whatcodes -- more official
+nodes.marginkerncodes = margincodes
+nodes.discretionarycodes = disccodes
+nodes.directionvalues = dirvalues -- more friendly
+nodes.skipvalues = gluevalues -- more friendly
+nodes.literalvalues = literalvalues -- more friendly
+
+glyphcodes.glyph = glyphcodes.character
listcodes.row = listcodes.alignment
listcodes.column = listcodes.alignment
@@ -399,7 +454,7 @@ kerncodes.kerning = kerncodes.fontkern
kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new
-pdfliteralvalues.direct = pdfliteralvalues.always
+literalvalues.direct = literalvalues.always
nodes.codes = allocate { -- mostly for listing
glue = skipcodes,
@@ -468,4 +523,3 @@ end
if node.fix_node_lists then
node.fix_node_lists(false)
end
-
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/node-ini.mkiv
index 8f10791633e..35013c4b801 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ini.mkiv
@@ -21,7 +21,7 @@
\registerctxluafile{node-met}{}
\registerctxluafile{node-nut}{}
\registerctxluafile{node-res}{}
-\registerctxluafile{node-ppt}{} % experimental
+%registerctxluafile{node-ppt}{} % experimental, not used so probably useless
\registerctxluafile{node-dir}{}
\registerctxluafile{node-aux}{}
\registerctxluafile{node-tst}{}
@@ -34,9 +34,9 @@
\registerctxluafile{node-ext}{}
\registerctxluafile{node-acc}{} % experimental
%registerctxluafile{node-prp}{} % makes no sense (yet)
-\registerctxluafile{node-ppt}{}
\registerctxluafile{node-scn}{}
\registerctxluafile{node-syn}{}
+\registerctxluafile{node-par}{}
\newcount\c_node_tracers_show_box % box number
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
index 865f69c2c7f..0d501890b92 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
@@ -134,6 +134,53 @@ if not modules then modules = { } end modules ['node-par'] = {
]]--
+--[[--
+
+#define dir_TLT 0
+#define dir_TRT 1
+#define dir_LTL 2
+#define dir_RTT 3
+
+#define dir_TLT_or_TRT(A) (A < 2)
+#define dir_LTL_or_RTT(A) (A > 1)
+
+#define textdir_parallel(A,B) (\
+(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
+(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\
+)
+
+#define pardir_parallel(A,B) (\
+(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
+(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\
+)
+
+#define pardir_opposite(A,B) (\
+(A == dir_LTL and B == dir_RTT) or \
+(A == dir_RTT and B == dir_LTL)\
+)
+
+#define textdir_opposite(A,B) (\
+(A == dir_TLT and B == dir_TRT) or \
+(A == dir_TRT and B == dir_TLT)\
+)
+
+#define glyphdir_opposite(A,B) 0
+
+#define pardir_equal(A,B) (\
+(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
+(A == dir_LTL and B == dir_LTL) or \
+(A == dir_RTT and B == dir_RTT)\
+)
+
+#define textdir_equal(A,B) (\
+(A == dir_TLT and B == dir_TLT) or \
+(A == dir_TRT and B == dir_TRT) or \
+(A == dir_LTL and dir_LTL_or_RTT(B)) or \
+(A == dir_RTT and dir_LTL_or_RTT(B))\
+)
+
+--]]--
+
local tonumber = tonumber
local utfchar = utf.char
local write, write_nl = texio.write, texio.write_nl
@@ -191,7 +238,6 @@ local parameters = fonthashes.parameters
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getfield = nuts.getfield
local getid = nuts.getid
@@ -200,21 +246,20 @@ local getnext = nuts.getnext
local getprev = nuts.getprev
local getboth = nuts.getboth
local getlist = nuts.getlist
-local getfont = nuts.getfont
-local getchar = nuts.getchar
local getdisc = nuts.getdisc
local getattr = nuts.getattr
local getdisc = nuts.getdisc
local getglue = nuts.getglue
local getwhd = nuts.getwhd
-local getcomponents = nuts.getcomponents
local getkern = nuts.getkern
local getpenalty = nuts.getpenalty
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local getshift = nuts.getshift
local getwidth = nuts.getwidth
local getheight = nuts.getheight
local getdepth = nuts.getdepth
+local getdata = nuts.getdata
+local getwhd = nuts.getwhd
local isglyph = nuts.isglyph
@@ -229,11 +274,10 @@ local setsubtype = nuts.setsubtype
local setglue = nuts.setglue
local setwhd = nuts.setwhd
local setkern = nuts.setkern
-local setdir = nuts.setdir
+local setdirection = nuts.setdirection
local setshift = nuts.setshift
local setwidth = nuts.setwidth
------ setheight = nuts.setheight
------ setdepth = nuts.setdepth
+local setexpansion = nuts.setexpansion
local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2
local find_tail = nuts.tail
@@ -246,13 +290,14 @@ local replace_node = nuts.replace
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local is_zero_glue = nuts.is_zero_glue
+local is_skipable = nuts.protrusion_skippable
local nodepool = nuts.pool
local nodecodes = nodes.nodecodes
local kerncodes = nodes.kerncodes
local glyphcodes = nodes.glyphcodes
-local gluecodes = nodes.gluecodes
+local leadercodes = nodes.leadercodes
local margincodes = nodes.margincodes
local disccodes = nodes.disccodes
local mathcodes = nodes.mathcodes
@@ -276,9 +321,9 @@ local marginkern_code = nodecodes.marginkern
local dir_code = nodecodes.dir
local boundary_code = nodecodes.boundary
-local protrusion_code = boundarycodes.protrusion
+local protrusionboundary_code = boundarycodes.protrusion
-local leaders_code = gluecodes.leaders
+local leaders_code = leadercodes.leaders
local localpar_code = nodecodes.localpar
@@ -287,17 +332,17 @@ local italickern_code = kerncodes.italiccorrection
local fontkern_code = kerncodes.fontkern
local accentkern_code = kerncodes.accentkern
-local ligature_code = glyphcodes.ligature
+local ligatureglyph_code = glyphcodes.ligature
-local stretch_orders = nodes.fillcodes
+local fillcodes = nodes.fillcodes
local leftmargin_code = margincodes.left
----- rightmargin_code = margincodes.right
-local automatic_disc_code = disccodes.automatic
-local regular_disc_code = disccodes.regular
-local first_disc_code = disccodes.first
-local second_disc_code = disccodes.second
+local automaticdisc_code = disccodes.automatic
+local regulardisc_code = disccodes.regular
+local firstdisc_code = disccodes.first
+local seconddisc_code = disccodes.second
local endmath_code = mathcodes.endmath
@@ -323,7 +368,7 @@ local fit_decent_class = 2 -- fitness for all other lines
local fit_tight_class = 3 -- fitness for lines shrinking 0.5 to 1.0 of their shrinkability
local new_penalty = nodepool.penalty
-local new_dir = nodepool.textdir
+local new_direction = nodepool.direction
local new_leftmarginkern = nodepool.leftmarginkern
local new_rightmarginkern = nodepool.rightmarginkern
local new_leftskip = nodepool.leftskip
@@ -334,17 +379,6 @@ local new_temp = nodepool.temp
local new_rule = nodepool.rule
local new_hlist = nodepool.hlist
-local is_rotated = nodes.is_rotated
-local is_parallel = nodes.textdir_is_parallel
-local is_opposite = nodes.textdir_is_opposite
-local textdir_is_equal = nodes.textdir_is_equal
-local pardir_is_equal = nodes.pardir_is_equal
-local glyphdir_is_equal = nodes.glyphdir_is_equal
-
-local dir_pops = nodes.dir_is_pop
-local dir_negations = nodes.dir_negation
-local is_skipable = nuts.protrusion_skippable
-
-- helpers --
-- It makes more sense to move the somewhat messy dir state tracking
@@ -359,22 +393,24 @@ end
-- in the parbuilder.
local function checked_line_dir(stack,current)
- if not dir_pops[current] then
+ local direction, pop = getdirection(current)
+ if not pop then
local n = stack.n + 1
stack.n = n
stack[n] = current
- return getdir(current)
+ return direction
elseif n > 0 then
local n = stack.n
local dirnode = stack[n]
dirstack.n = n - 1
- return getdir(dirnode)
+ direction = getdirection(dirnode) -- we could save it
+ return direction
else
report_parbuilders("warning: missing pop node (%a)",1) -- in line ...
end
end
--- The next function checks a dir nodes in a list and appends the negations
+-- The next function checks dir nodes in a list and appends the negations
-- that are currently needed (some day LuaTeX will be more tolerant). We use
-- the negations for the next line.
@@ -382,10 +418,12 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop)
local e = start
local n = stack.n
local h = nil
+ -- todo: traverse
while start and start ~= stop do
local id = getid(start)
if id == dir_code then
- if not dir_pops[getdir(start)] then -- weird, what is this #
+ local direction, pop = getdirection(start)
+ if not pop then
n = n + 1
stack[n] = start
elseif n > 0 then
@@ -397,7 +435,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop)
start = getnext(start)
end
for i=n,1,-1 do
- h, current = insert_node_after(current,current,new_dir(dir_negations[getdir(stack[i])]))
+ h, current = insert_node_after(current,current,new_direction(getdirection(stack[i]),true))
end
stack.n = n
return current
@@ -406,7 +444,7 @@ end
local function inject_dirs_at_begin_of_line(stack,current)
local h = nil
for i=stack.n,1,-1 do
- h, current = insert_node_after(current,current,new_dir(stack[i]))
+ h, current = insert_node_after(current,current,new_direction(stack[i]))
end
stack.n = 0
return current
@@ -507,9 +545,9 @@ end)
local function kern_stretch_shrink(p,d)
local left = getprev(p)
if left then
- local char = isglyph(left)
+ local char, font = isglyph(left)
if char then
- local data = expansions[getfont(left)][char]
+ local data = expansions[font][char]
if data then
local stretch = data.stretch
local shrink = data.shrink
@@ -630,8 +668,8 @@ local function find(head) -- do we really want to recurse into an hlist?
head = getnext(head)
end
elseif id == boundary_code then
- if getsubtype(head) == protrusion_code then
- local v = getfield(head,"value")
+ if getsubtype(head) == protrusionboundary_code then
+ local v = getdata(head)
if v == 1 or v == 3 then
head = getnext(head)
if head then
@@ -654,19 +692,19 @@ end
local function find_protchar_left(l) -- weird function
local ln = getnext(l)
- if ln and getid(ln) == hlist_code and not getlist(ln) and getfield(ln,"width") == 0 and getfield(ln,"height") == 0 and getfield(ln,"depth") == 0 then
- l = getnext(l)
- else -- if d then -- was always true
- local id = getid(l)
- while ln and not (id == glyph_code or id < math_code) do -- is there always a glyph?
- l = ln
- ln = getnext(l)
- id = getid(ln)
- end
+ if ln and getid(ln) == hlist_code and not getlist(ln) then
+ local w, h, d = getwhd(ln)
+ if w == 0 and h == 0 and d == 0 then
+ l = getnext(l)
+ return find(l) or l
+ end
+ end -- if d then -- was always true
+ local id = getid(l)
+ while ln and not (id == glyph_code or id < math_code) do -- is there always a glyph?
+ l = ln
+ ln = getnext(l)
+ id = getid(ln)
end
- -- if getid(l) == glyph_code then
- -- return l
- -- end
return find(l) or l
end
@@ -684,8 +722,8 @@ local function find(head,tail)
tail = getprev(tail)
end
elseif id == boundary_code then
- if getsubtype(head) == protrusion_code then
- local v = getfield(tail,"value")
+ if getsubtype(head) == protrusionboundary_code then
+ local v = getdata(tail)
if v == 2 or v == 3 then
tail = getprev(tail)
if tail then
@@ -711,8 +749,8 @@ local function find_protchar_right(l,r)
end
local function left_pw(p)
- local font = getfont(p)
- local prot = chardata[font][getchar(p)].left_protruding
+ local char, font = isglyph(p)
+ local prot = chardata[font][char].left_protruding
if not prot or prot == 0 then
return 0
end
@@ -720,8 +758,8 @@ local function left_pw(p)
end
local function right_pw(p)
- local font = getfont(p)
- local prot = chardata[font][getchar(p)].right_protruding
+ local char, font = isglyph(p)
+ local prot = chardata[font][char].right_protruding
if not prot or prot == 0 then
return 0
end
@@ -748,13 +786,13 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw
local char, id = isglyph(s)
if char then
local wd, ht, dp = getwhd(s)
- if is_rotated[line_break_dir] then -- can be shared
+ if is_rotated(line_break_dir) then
size = size + ht + dp
else
size = size + wd
end
if checked_expansion then
- local data = checked_expansion[getfont(s)]
+ local data = checked_expansion[id] -- id == font
if data then
data = data[char]
if data then
@@ -765,7 +803,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw
end
elseif id == hlist_code or id == vlist_code then
local wd, ht, dp = getwhd(s)
- if is_parallel[getdir(s)][line_break_dir] then
+ if textdir_parallel(getdirection(s),line_break_dir) then
size = size + wd
else
size = size + ht + dp
@@ -796,1709 +834,1712 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw
return size, adjust_stretch, adjust_shrink
end
-local function compute_break_width(par,break_type,p) -- split in two
- local break_width = par.break_width
- if break_type > unhyphenated_code then
- local disc_width = par.disc_width
- local checked_expansion = par.checked_expansion
- local line_break_dir = par.line_break_dir
- local break_size = break_width.size + disc_width.size
- local break_adjust_stretch = break_width.adjust_stretch + disc_width.adjust_stretch
- local break_adjust_shrink = break_width.adjust_shrink + disc_width.adjust_shrink
- local pre, post, replace = getdisc(p)
- if replace then
- local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace)
- break_size = break_size - size
- break_adjust_stretch = break_adjust_stretch - adjust_stretch
- break_adjust_shrink = break_adjust_shrink - adjust_shrink
- end
- if post then
- local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,post)
- break_size = break_size + size
- break_adjust_stretch = break_adjust_stretch + adjust_stretch
- break_adjust_shrink = break_adjust_shrink + adjust_shrink
- end
- break_width.size = break_size
- break_width.adjust_stretch = break_adjust_stretch
- break_width.adjust_shrink = break_adjust_shrink
- if not post then
- p = getnext(p)
- else
- return
- end
- end
- while p do -- skip spacing etc
- local id = getid(p)
- if id == glyph_code then
- return -- happens often
- elseif id == glue_code then
- local wd, stretch, shrink, stretch_order = getglue(p)
- local order = stretch_orders[stretch_order]
- break_width.size = break_width.size - wd
- break_width[order] = break_width[order] - stretch
- break_width.shrink = break_width.shrink - shrink
- elseif id == penalty_code then
- -- do nothing
- elseif id == kern_code then
- local s = getsubtype(p)
- if s == userkern_code or s == italickern_code then
- break_width.size = break_width.size - getkern(p)
+-- We can actually make par local to this module as we never break inside a break call and that way the
+-- array is reused. At some point the information will be part of the paragraph spec as passed.
+
+local hztolerance = 2500
+local hzwarned = false
+
+do
+
+ local function compute_break_width(par,break_type,p) -- split in two
+ local break_width = par.break_width
+ if break_type > unhyphenated_code then
+ local disc_width = par.disc_width
+ local checked_expansion = par.checked_expansion
+ local line_break_dir = par.line_break_dir
+ local break_size = break_width.size + disc_width.size
+ local break_adjust_stretch = break_width.adjust_stretch + disc_width.adjust_stretch
+ local break_adjust_shrink = break_width.adjust_shrink + disc_width.adjust_shrink
+ local pre, post, replace = getdisc(p)
+ if replace then
+ local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace)
+ break_size = break_size - size
+ break_adjust_stretch = break_adjust_stretch - adjust_stretch
+ break_adjust_shrink = break_adjust_shrink - adjust_shrink
+ end
+ if post then
+ local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,post)
+ break_size = break_size + size
+ break_adjust_stretch = break_adjust_stretch + adjust_stretch
+ break_adjust_shrink = break_adjust_shrink + adjust_shrink
+ end
+ break_width.size = break_size
+ break_width.adjust_stretch = break_adjust_stretch
+ break_width.adjust_shrink = break_adjust_shrink
+ if not post then
+ p = getnext(p)
else
return
end
- elseif id == math_code then
- break_width.size = break_width.size - getkern(p) -- surround
- -- new in luatex
- local wd, stretch, shrink, stretch_order = getglue(p)
- local order = stretch_orders[stretch_order]
- break_width.size = break_width.size - wd
- break_width[order] = break_width[order] - stretch
- break_width.shrink = break_width.shrink - shrink
- else
- return
end
- p = getnext(p)
- end
-end
-
-local function append_to_vlist(par, b)
- local prev_depth = par.prev_depth
- local head_field = par.head_field
- local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail
- local is_hlist = getid(b) == hlist_code
- -- if prev_depth > par.ignored_dimen then
- if prev_depth > ignore_depth then
- if is_hlist then
- local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip)
- local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines
- local skip = nil
- if delta < par.line_skip_limit then
- width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip)
- skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order)
- else
- skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order)
- end
- if head_field then
- setlink(tail_field,skip)
+ while p do -- skip spacing etc
+ local id = getid(p)
+ if id == glyph_code then
+ return -- happens often
+ elseif id == glue_code then
+ local wd, stretch, shrink, stretch_order = getglue(p)
+ local order = fillcodes[stretch_order]
+ break_width.size = break_width.size - wd
+ break_width[order] = break_width[order] - stretch
+ break_width.shrink = break_width.shrink - shrink
+ elseif id == penalty_code then
+ -- do nothing
+ elseif id == kern_code then
+ local s = getsubtype(p)
+ if s == userkern_code or s == italickern_code then
+ break_width.size = break_width.size - getkern(p)
+ else
+ return
+ end
+ elseif id == math_code then
+ break_width.size = break_width.size - getkern(p) -- surround
+ -- new in luatex
+ local wd, stretch, shrink, stretch_order = getglue(p)
+ local order = fillcodes[stretch_order]
+ break_width.size = break_width.size - wd
+ break_width[order] = break_width[order] - stretch
+ break_width.shrink = break_width.shrink - shrink
else
- par.head_field = skip
- head_field = skip
+ return
end
- tail_field = skip
+ p = getnext(p)
end
end
- if head_field then
- setlink(tail_field,b)
- else
- par.head_field = b
- end
- if is_hlist then
- local pd = getdepth(b)
- par.prev_depth = pd
- texnest[texnest.ptr].prevdepth = pd
- end
-end
-local function append_list(par, b)
- local head_field = par.head_field
- if head_field then
- local n = slide_node_list(head_field) -- todo: find_tail
- setlink(n,b)
- else
- par.head_field = b
+ local function append_to_vlist(par, b)
+ local prev_depth = par.prev_depth
+ local head_field = par.head_field
+ local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail
+ local is_hlist = getid(b) == hlist_code
+ -- if prev_depth > par.ignored_dimen then
+ if prev_depth > ignore_depth then
+ if is_hlist then
+ local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip)
+ local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines
+ local skip = nil
+ if delta < par.line_skip_limit then
+ width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip)
+ skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order)
+ else
+ skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order)
+ end
+ if head_field then
+ setlink(tail_field,skip)
+ else
+ par.head_field = skip
+ head_field = skip
+ end
+ tail_field = skip
+ end
+ end
+ if head_field then
+ setlink(tail_field,b)
+ else
+ par.head_field = b
+ end
+ if is_hlist then
+ local pd = getdepth(b)
+ par.prev_depth = pd
+ texnest[texnest.ptr].prevdepth = pd
+ end
end
-end
-
--- We can actually make par local to this module as we never break inside a break call and that way the
--- array is reused. At some point the information will be part of the paragraph spec as passed.
-
-local hztolerance = 2500
-local hzwarned = false
-
-local function used_skip(s)
- return s and not is_zero_glue(s) and s
-end
-local function initialize_line_break(head,display)
-
- local hang_indent = tex.hangindent or 0
- local hsize = tex.hsize or 0
- local hang_after = tex.hangafter or 0
- local par_shape_ptr = tex.parshape
- local left_skip = tonut(tex.leftskip) -- nodes
- local right_skip = tonut(tex.rightskip) -- nodes
- local pretolerance = tex.pretolerance
- local tolerance = tex.tolerance
- local adjust_spacing = tex.adjustspacing
- local protrude_chars = tex.protrudechars
- local last_line_fit = tex.lastlinefit
-
- local newhead = new_temp()
- setnext(newhead,head)
-
- local adjust_spacing_status = adjust_spacing > 1 and -1 or 0
-
- -- metatables
-
- local par = {
- head = newhead,
- head_field = nil,
- display = display,
- font_in_short_display = 0,
- no_shrink_error_yet = true, -- have we complained about infinite shrinkage?
- second_pass = false, -- is this our second attempt to break this paragraph?
- final_pass = false, -- is this our final attempt to break this paragraph?
- threshold = 0, -- maximum badness on feasible lines
-
- passive = nil, -- most recent node on passive list
- printed_node = head, -- most recent node that has been printed
- pass_number = 0, -- the number of passive nodes allocated on this pass
- auto_breaking = 0, -- make auto_breaking accessible out of line_break
-
- active_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
- break_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
- disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 },
- fill_width = { stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
- background = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
-
- hang_indent = hang_indent,
- hsize = hsize,
- hang_after = hang_after,
- par_shape_ptr = par_shape_ptr,
- left_skip = left_skip,
- right_skip = right_skip,
- pretolerance = pretolerance,
- tolerance = tolerance,
-
- protrude_chars = protrude_chars,
- adjust_spacing = adjust_spacing,
- max_stretch_ratio = adjust_spacing_status,
- max_shrink_ratio = adjust_spacing_status,
- cur_font_step = adjust_spacing_status,
- checked_expansion = false,
- tracing_paragraphs = tex.tracingparagraphs > 0,
-
- emergency_stretch = tex.emergencystretch or 0,
- looseness = tex.looseness or 0,
- line_penalty = tex.linepenalty or 0,
- hyphen_penalty = tex.hyphenpenalty or 0,
- broken_penalty = tex.brokenpenalty or 0,
- inter_line_penalty = tex.interlinepenalty or 0,
- club_penalty = tex.clubpenalty or 0,
- widow_penalty = tex.widowpenalty or 0,
- display_widow_penalty = tex.displaywidowpenalty or 0,
- ex_hyphen_penalty = tex.exhyphenpenalty or 0,
-
- adj_demerits = tex.adjdemerits or 0,
- double_hyphen_demerits = tex.doublehyphendemerits or 0,
- final_hyphen_demerits = tex.finalhyphendemerits or 0,
-
- first_line = 0, -- tex.nest[tex.nest.ptr].modeline, -- 0, -- cur_list.pg_field
-
- -- each_line_height = tex.pdfeachlineheight or 0, -- this will go away
- -- each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away
- -- first_line_height = tex.pdffirstlineheight or 0, -- this will go away
- -- last_line_depth = tex.pdflastlinedepth or 0, -- this will go away
-
- -- ignored_dimen = tex.pdfignoreddimen or 0,
-
- baseline_skip = tonut(tex.baselineskip),
- lineskip = tonut(tex.lineskip),
- line_skip_limit = tex.lineskiplimit,
-
- prev_depth = texnest[texnest.ptr].prevdepth,
-
- final_par_glue = slide_node_list(head), -- todo: we know tail already, slow
-
- par_break_dir = tex.pardir,
- line_break_dir = tex.pardir,
-
- internal_pen_inter = 0, -- running localinterlinepenalty
- internal_pen_broken = 0, -- running localbrokenpenalty
- internal_left_box = nil, -- running localleftbox
- internal_left_box_width = 0, -- running localleftbox width
- init_internal_left_box = nil, -- running localleftbox
- init_internal_left_box_width = 0, -- running localleftbox width
- internal_right_box = nil, -- running localrightbox
- internal_right_box_width = 0, -- running localrightbox width
-
- best_place = { }, -- how to achieve minimal_demerits
- best_pl_line = { }, -- corresponding line number
- easy_line = 0, -- line numbers easy_line are equivalent in break nodes
- last_special_line = 0, -- line numbers last_special_line all have the same width
- first_width = 0, -- the width of all lines last_special_line, if no parshape has been specified
- second_width = 0, -- the width of all lines last_special_line
- first_indent = 0, -- left margin to go with first_width
- second_indent = 0, -- left margin to go with second_width
-
- best_bet = nil, -- use this passive node and its predecessors
- fewest_demerits = 0, -- the demerits associated with best_bet
- best_line = 0, -- line number following the last line of the new paragraph
- line_diff = 0, -- the difference between the current line number and the optimum best_line
-
- -- not yet used
-
- best_pl_short = { }, -- shortfall corresponding to minimal_demerits
- best_pl_glue = { }, -- corresponding glue stretch or shrink
- do_last_line_fit = false,
- last_line_fit = last_line_fit,
-
- minimum_demerits = awful_badness,
-
- minimal_demerits = {
-
- [fit_very_loose_class] = awful_badness,
- [fit_loose_class] = awful_badness,
- [fit_decent_class] = awful_badness,
- [fit_tight_class] = awful_badness,
-
- },
-
- prev_char_p = nil,
-
- statistics = {
-
- noflines = 0,
- nofprotrudedlines = 0,
- nofadjustedlines = 0,
-
- },
-
- -- -- just a thought ... parshape functions ... it would be nice to
- -- -- also store the height so far (probably not too hard) although
- -- -- in most cases we work on grids in such cases
- --
- -- adapt_width = function(par,line)
- -- -- carry attribute, so that we can accumulate
- -- local left = 655360 * (line - 1)
- -- local right = 655360 * (line - 1)
- -- return left, right
- -- end
+ local function append_list(par, b)
+ local head_field = par.head_field
+ if head_field then
+ local n = slide_node_list(head_field) -- todo: find_tail
+ setlink(n,b)
+ else
+ par.head_field = b
+ end
+ end
+
+ local function used_skip(s)
+ return s and not is_zero_glue(s) and s
+ end
+
+ local function initialize_line_break(head,display)
+
+ local hang_indent = tex.hangindent or 0
+ local hsize = tex.hsize or 0
+ local hang_after = tex.hangafter or 0
+ local par_shape_ptr = tex.parshape
+ local left_skip = tonut(tex.leftskip) -- nodes
+ local right_skip = tonut(tex.rightskip) -- nodes
+ local pretolerance = tex.pretolerance
+ local tolerance = tex.tolerance
+ local adjust_spacing = tex.adjustspacing
+ local protrude_chars = tex.protrudechars
+ local last_line_fit = tex.lastlinefit
+ local par_dir = tex.pardirection
+
+ local newhead = new_temp()
+ setnext(newhead,head)
+
+ local adjust_spacing_status = adjust_spacing > 1 and -1 or 0
+
+ -- metatables
+
+ local par = {
+ head = newhead,
+ head_field = nil,
+ display = display,
+ font_in_short_display = 0,
+ no_shrink_error_yet = true, -- have we complained about infinite shrinkage?
+ second_pass = false, -- is this our second attempt to break this paragraph?
+ final_pass = false, -- is this our final attempt to break this paragraph?
+ threshold = 0, -- maximum badness on feasible lines
+
+ passive = nil, -- most recent node on passive list
+ printed_node = head, -- most recent node that has been printed
+ pass_number = 0, -- the number of passive nodes allocated on this pass
+ auto_breaking = 0, -- make auto_breaking accessible out of line_break
+
+ active_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ break_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ fill_width = { stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
+ background = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
+
+ hang_indent = hang_indent,
+ hsize = hsize,
+ hang_after = hang_after,
+ par_shape_ptr = par_shape_ptr,
+ left_skip = left_skip,
+ right_skip = right_skip,
+ pretolerance = pretolerance,
+ tolerance = tolerance,
+
+ protrude_chars = protrude_chars,
+ adjust_spacing = adjust_spacing,
+ max_stretch_ratio = adjust_spacing_status,
+ max_shrink_ratio = adjust_spacing_status,
+ cur_font_step = adjust_spacing_status,
+ checked_expansion = false,
+ tracing_paragraphs = tex.tracingparagraphs > 0,
+
+ emergency_stretch = tex.emergencystretch or 0,
+ looseness = tex.looseness or 0,
+ line_penalty = tex.linepenalty or 0,
+ hyphen_penalty = tex.hyphenpenalty or 0,
+ broken_penalty = tex.brokenpenalty or 0,
+ inter_line_penalty = tex.interlinepenalty or 0,
+ club_penalty = tex.clubpenalty or 0,
+ widow_penalty = tex.widowpenalty or 0,
+ display_widow_penalty = tex.displaywidowpenalty or 0,
+ ex_hyphen_penalty = tex.exhyphenpenalty or 0,
+
+ adj_demerits = tex.adjdemerits or 0,
+ double_hyphen_demerits = tex.doublehyphendemerits or 0,
+ final_hyphen_demerits = tex.finalhyphendemerits or 0,
+
+ first_line = 0, -- texnest[texnest.ptr].modeline, -- 0, -- cur_list.pg_field
+
+ -- each_line_height = tex.pdfeachlineheight or 0, -- this will go away
+ -- each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away
+ -- first_line_height = tex.pdffirstlineheight or 0, -- this will go away
+ -- last_line_depth = tex.pdflastlinedepth or 0, -- this will go away
+
+ -- ignored_dimen = tex.pdfignoreddimen or 0,
+
+ baseline_skip = tonut(tex.baselineskip),
+ lineskip = tonut(tex.lineskip),
+ line_skip_limit = tex.lineskiplimit,
+
+ prev_depth = texnest[texnest.ptr].prevdepth,
+
+ final_par_glue = slide_node_list(head), -- todo: we know tail already, slow
+
+ par_break_dir = par_dir,
+ line_break_dir = par_dir,
+
+ internal_pen_inter = 0, -- running localinterlinepenalty
+ internal_pen_broken = 0, -- running localbrokenpenalty
+ internal_left_box = nil, -- running localleftbox
+ internal_left_box_width = 0, -- running localleftbox width
+ init_internal_left_box = nil, -- running localleftbox
+ init_internal_left_box_width = 0, -- running localleftbox width
+ internal_right_box = nil, -- running localrightbox
+ internal_right_box_width = 0, -- running localrightbox width
+
+ best_place = { }, -- how to achieve minimal_demerits
+ best_pl_line = { }, -- corresponding line number
+ easy_line = 0, -- line numbers easy_line are equivalent in break nodes
+ last_special_line = 0, -- line numbers last_special_line all have the same width
+ first_width = 0, -- the width of all lines last_special_line, if no parshape has been specified
+ second_width = 0, -- the width of all lines last_special_line
+ first_indent = 0, -- left margin to go with first_width
+ second_indent = 0, -- left margin to go with second_width
+
+ best_bet = nil, -- use this passive node and its predecessors
+ fewest_demerits = 0, -- the demerits associated with best_bet
+ best_line = 0, -- line number following the last line of the new paragraph
+ line_diff = 0, -- the difference between the current line number and the optimum best_line
+
+ -- not yet used
+
+ best_pl_short = { }, -- shortfall corresponding to minimal_demerits
+ best_pl_glue = { }, -- corresponding glue stretch or shrink
+ do_last_line_fit = false,
+ last_line_fit = last_line_fit,
+
+ minimum_demerits = awful_badness,
+
+ minimal_demerits = {
+
+ [fit_very_loose_class] = awful_badness,
+ [fit_loose_class] = awful_badness,
+ [fit_decent_class] = awful_badness,
+ [fit_tight_class] = awful_badness,
+
+ },
+
+ prev_char_p = nil,
+
+ statistics = {
+
+ noflines = 0,
+ nofprotrudedlines = 0,
+ nofadjustedlines = 0,
+
+ },
+
+ -- -- just a thought ... parshape functions ... it would be nice to
+ -- -- also store the height so far (probably not too hard) although
+ -- -- in most cases we work on grids in such cases
+ --
+ -- adapt_width = function(par,line)
+ -- -- carry attribute, so that we can accumulate
+ -- local left = 655360 * (line - 1)
+ -- local right = 655360 * (line - 1)
+ -- return left, right
+ -- end
- }
+ }
- -- optimizers
+ -- optimizers
- par.used_left_skip = used_skip(par.left_skip)
- par.used_right_skip = used_skip(par.right_skip)
+ par.used_left_skip = used_skip(par.left_skip)
+ par.used_right_skip = used_skip(par.right_skip)
- -- so far
+ -- so far
- if adjust_spacing > 1 then
- local checked_expansion = { par = par }
- setmetatableindex(checked_expansion,check_expand_pars)
- par.checked_expansion = checked_expansion
+ if adjust_spacing > 1 then
+ local checked_expansion = { par = par }
+ setmetatableindex(checked_expansion,check_expand_pars)
+ par.checked_expansion = checked_expansion
- if par.tolerance < hztolerance then
- if not hzwarned then
- report_parbuilders("setting tolerance to %a for hz",hztolerance)
- hzwarned = true
+ if par.tolerance < hztolerance then
+ if not hzwarned then
+ report_parbuilders("setting tolerance to %a for hz",hztolerance)
+ hzwarned = true
+ end
+ par.tolerance = hztolerance
end
- par.tolerance = hztolerance
- end
- expand_kerns = expand_kerns_mode or (adjust_spacing == 2)
+ expand_kerns = expand_kerns_mode or (adjust_spacing == 2)
- end
+ end
- -- we need par for the error message
+ -- we need par for the error message
- local background = par.background
+ local background = par.background
- local l = check_shrinkage(par,left_skip)
- local r = check_shrinkage(par,right_skip)
+ local l = check_shrinkage(par,left_skip)
+ local r = check_shrinkage(par,right_skip)
- local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l)
- local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r)
+ local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l)
+ local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r)
- local l_order = stretch_orders[lstretch_order]
- local r_order = stretch_orders[rstretch_order]
+ local l_order = fillcodes[lstretch_order]
+ local r_order = fillcodes[rstretch_order]
- background.size = lwidth + rwidth
- background.shrink = lshrink + rshrink
- background[l_order] = lstretch
- background[r_order] = rstretch + background[r_order]
+ background.size = lwidth + rwidth
+ background.shrink = lshrink + rshrink
+ background[l_order] = lstretch
+ background[r_order] = rstretch + background[r_order]
- -- this will move up so that we can assign the whole par table
+ -- this will move up so that we can assign the whole par table
- if not par_shape_ptr then
- if hang_indent == 0 then
- par.second_width = hsize
- par.second_indent = 0
- else
- local abs_hang_after = hang_after >0 and hang_after or -hang_after
- local abs_hang_indent = hang_indent>0 and hang_indent or -hang_indent
- par.last_special_line = abs_hang_after
- if hang_after < 0 then
- par.first_width = hsize - abs_hang_indent
- if hang_indent >= 0 then
- par.first_indent = hang_indent
- else
- par.first_indent = 0
- end
+ if not par_shape_ptr then
+ if hang_indent == 0 then
par.second_width = hsize
par.second_indent = 0
else
- par.first_width = hsize
- par.first_indent = 0
- par.second_width = hsize - abs_hang_indent
- if hang_indent >= 0 then
- par.second_indent = hang_indent
- else
+ local abs_hang_after = hang_after >0 and hang_after or -hang_after
+ local abs_hang_indent = hang_indent>0 and hang_indent or -hang_indent
+ par.last_special_line = abs_hang_after
+ if hang_after < 0 then
+ par.first_width = hsize - abs_hang_indent
+ if hang_indent >= 0 then
+ par.first_indent = hang_indent
+ else
+ par.first_indent = 0
+ end
+ par.second_width = hsize
par.second_indent = 0
+ else
+ par.first_width = hsize
+ par.first_indent = 0
+ par.second_width = hsize - abs_hang_indent
+ if hang_indent >= 0 then
+ par.second_indent = hang_indent
+ else
+ par.second_indent = 0
+ end
end
end
+ else
+ local last_special_line = #par_shape_ptr
+ par.last_special_line = last_special_line
+ local parshape = par_shape_ptr[last_special_line]
+ par.second_width = parshape[2]
+ par.second_indent = parshape[1]
end
- else
- local last_special_line = #par_shape_ptr
- par.last_special_line = last_special_line
- local parshape = par_shape_ptr[last_special_line]
- par.second_width = parshape[2]
- par.second_indent = parshape[1]
- end
- if par.looseness == 0 then
- par.easy_line = par.last_special_line
- else
- par.easy_line = max_halfword
- end
+ if par.looseness == 0 then
+ par.easy_line = par.last_special_line
+ else
+ par.easy_line = max_halfword
+ end
- if pretolerance >= 0 then
- par.threshold = pretolerance
- par.second_pass = false
- par.final_pass = false
- else
- par.threshold = tolerance
- par.second_pass = true
- par.final_pass = par.emergency_stretch <= 0
- if trace_basic then
- if par.final_pass then
- report_parbuilders("enabling second and final pass")
- else
- report_parbuilders("enabling second pass")
+ if pretolerance >= 0 then
+ par.threshold = pretolerance
+ par.second_pass = false
+ par.final_pass = false
+ else
+ par.threshold = tolerance
+ par.second_pass = true
+ par.final_pass = par.emergency_stretch <= 0
+ if trace_basic then
+ if par.final_pass then
+ report_parbuilders("enabling second and final pass")
+ else
+ report_parbuilders("enabling second pass")
+ end
end
end
- end
- if last_line_fit > 0 then
- local final_par_glue = par.final_par_glue
- local stretch = getfield(final_par_glue,"stretch")
- local stretch_order = getfield(final_par_glue,"stretch_order")
- if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then
- par.do_last_line_fit = true
- local si = stretch_orders[stretch_order]
- if trace_lastlinefit or trace_basic then
- report_parbuilders("enabling last line fit, stretch order %a set to %a, linefit is %a",si,stretch,last_line_fit)
+ if last_line_fit > 0 then
+ local final_par_glue = par.final_par_glue
+ local stretch = getfield(final_par_glue,"stretch")
+ local stretch_order = getfield(final_par_glue,"stretch_order")
+ if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then
+ par.do_last_line_fit = true
+ local si = fillcodes[stretch_order]
+ if trace_lastlinefit or trace_basic then
+ report_parbuilders("enabling last line fit, stretch order %a set to %a, linefit is %a",si,stretch,last_line_fit)
+ end
+ par.fill_width[si] = stretch
end
- par.fill_width[si] = stretch
end
- end
- return par
-end
+ return par
+ end
--- there are still all kind of artefacts in here (a side effect I guess of pdftex,
--- etex, omega and other extensions that got obscured by patching)
+ -- there are still all kind of artefacts in here (a side effect I guess of pdftex,
+ -- etex, omega and other extensions that got obscured by patching)
-local function post_line_break(par)
+ local function post_line_break(par)
- local prevgraf = texnest[texnest.ptr].prevgraf
- local current_line = prevgraf + 1 -- the current line number being justified
+ local prevgraf = texnest[texnest.ptr].prevgraf
+ local current_line = prevgraf + 1 -- the current line number being justified
- local adjust_spacing = par.adjust_spacing
- local protrude_chars = par.protrude_chars
- local statistics = par.statistics
+ local adjust_spacing = par.adjust_spacing
+ local protrude_chars = par.protrude_chars
+ local statistics = par.statistics
- local stack = new_dir_stack()
+ local stack = new_dir_stack()
- local leftskip = par.used_left_skip -- used or normal ?
- local rightskip = par.right_skip
- local parshape = par.par_shape_ptr
- ----- ignored_dimen = par.ignored_dimen
+ local leftskip = par.used_left_skip -- used or normal ?
+ local rightskip = par.right_skip
+ local parshape = par.par_shape_ptr
+ ----- ignored_dimen = par.ignored_dimen
- local adapt_width = par.adapt_width
+ local adapt_width = par.adapt_width
- -- reverse the links of the relevant passive nodes, goto first breakpoint
+ -- reverse the links of the relevant passive nodes, goto first breakpoint
- local current_break = nil
+ local current_break = nil
- local break_node = par.best_bet.break_node
- repeat
- local first_break = break_node
- break_node = break_node.prev_break
- first_break.prev_break = current_break
- current_break = first_break
- until not break_node
+ local break_node = par.best_bet.break_node
+ repeat
+ local first_break = break_node
+ break_node = break_node.prev_break
+ first_break.prev_break = current_break
+ current_break = first_break
+ until not break_node
- local head = par.head
+ local head = par.head
- -- maybe : each_...
+ -- maybe : each_...
- while current_break do
+ while current_break do
- inject_dirs_at_begin_of_line(stack,head)
+ inject_dirs_at_begin_of_line(stack,head)
- local disc_break = false
- local post_disc_break = false
- local glue_break = false
+ local disc_break = false
+ local post_disc_break = false
+ local glue_break = false
- local lineend = nil -- q lineend refers to the last node of the line (and paragraph)
- local lastnode = current_break.cur_break -- r lastnode refers to the node after which the dir nodes should be closed
+ local lineend = nil -- lineend : the last node of the line (and paragraph)
+ local lastnode = current_break.cur_break -- lastnode: the node after which the dir nodes should be closed
- if not lastnode then
- -- only at the end
- lastnode = slide_node_list(head) -- todo: find_tail
- if lastnode == par.final_par_glue then
- lineend = lastnode
- lastnode = getprev(lastnode)
- end
- else -- todo: use insert_list_after
- local id = getid(lastnode)
- if id == glue_code then
- -- lastnode is normal skip
- lastnode = replace_node(lastnode,new_rightskip(rightskip))
- glue_break = true
- lineend = lastnode
- lastnode = getprev(lastnode)
- elseif id == disc_code then
- local prevlast = getprev(lastnode)
- local nextlast = getnext(lastnode)
- local subtype = getsubtype(lastnode)
- local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true)
- if subtype == second_disc_code then
- if not (getid(prevlast) == disc_code and getsubtype(prevlast) == first_disc_code) then
- report_parbuilders('unsupported disc at location %a',3)
- end
- if pre then
- flush_node_list(pre)
- pre = nil -- signal
+ if not lastnode then
+ -- only at the end
+ lastnode = slide_node_list(head) -- todo: find_tail
+ if lastnode == par.final_par_glue then
+ lineend = lastnode
+ lastnode = getprev(lastnode)
+ end
+ else -- todo: use insert_list_after
+ local id = getid(lastnode)
+ if id == glue_code then
+ -- lastnode is normal skip
+ lastnode = replace_node(lastnode,new_rightskip(rightskip))
+ glue_break = true
+ lineend = lastnode
+ lastnode = getprev(lastnode)
+ elseif id == disc_code then
+ local prevlast = getprev(lastnode)
+ local nextlast = getnext(lastnode)
+ local subtype = getsubtype(lastnode)
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true)
+ if subtype == seconddisc_code then
+ if not (getid(prevlast) == disc_code and getsubtype(prevlast) == firstdisc_code) then
+ report_parbuilders('unsupported disc at location %a',3)
+ end
+ if pre then
+ flush_node_list(pre)
+ pre = nil -- signal
+ end
+ if replace then
+ setlink(prevlast,replace)
+ setlink(replacetail,lastnode)
+ replace = nil -- signal
+ end
+ setdisc(lastnode,pre,post,replace)
+ local pre, post, replace = getdisc(prevlast)
+ if pre then
+ flush_node_list(pre)
+ end
+ if replace then
+ flush_node_list(replace)
+ end
+ if post then
+ flush_node_list(post)
+ end
+ setdisc(prevlast) -- nil,nil,nil
+ elseif subtype == firstdisc_code then
+ -- what is v ... next probably
+ if not (getid(v) == disc_code and getsubtype(v) == seconddisc_code) then
+ report_parbuilders('unsupported disc at location %a',4)
+ end
+ setsubtype(nextlast,regulardisc_code)
+ setfield(nextlast,"replace",post)
+ setfield(lastnode,"post") -- nil
end
if replace then
- setlink(prevlast,replace)
- setlink(replacetail,lastnode)
- replace = nil -- signal
+ flush_node_list(replace)
end
- setdisc(lastnode,pre,post,replace)
- local pre, post, replace = getdisc(prevlast)
if pre then
- flush_node_list(pre)
- end
- if replace then
- flush_node_list(replace)
+ setlink(prevlast,pre)
+ setlink(pretail,lastnode)
end
if post then
- flush_node_list(post)
- end
- setdisc(prevlast) -- nil,nil,nil
- elseif subtype == first_disc_code then
- -- what is v ... next probably
- if not (getid(v) == disc_code and getsubtype(v) == second_disc_code) then
- report_parbuilders('unsupported disc at location %a',4)
+ setlink(lastnode,post)
+ setlink(posttail,nextlast)
+ post_disc_break = true
end
- setsubtype(nextlast,regular_disc_code)
- setfield(nextlast,"replace",post)
- setfield(lastnode,"post") -- nil
- end
- if replace then
- flush_node_list(replace)
+ setdisc(lastnode) -- nil, nil, nil
+ disc_break = true
+ elseif id == kern_code then
+ setkern(lastnode,0)
+ elseif getid(lastnode) == math_code then
+ setkern(lastnode,0) -- surround
+ -- new in luatex
+ setglue(lastnode) -- zeros
end
- if pre then
- setlink(prevlast,pre)
- setlink(pretail,lastnode)
+ end
+ lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break)
+ local rightbox = current_break.passive_right_box
+ if rightbox then
+ lastnode = insert_node_after(lastnode,lastnode,copy_node(rightbox))
+ end
+ if not lineend then
+ lineend = lastnode
+ end
+ if lineend and lineend ~= head and protrude_chars > 0 then
+ local id = getid(lineend)
+ local c = (disc_break and (id == glyph_code or id ~= disc_code) and lineend) or getprev(lineend)
+ local p = find_protchar_right(getnext(head),c)
+ if p and getid(p) == glyph_code then
+ local w, last_rightmost_char = right_pw(p)
+ if last_rightmost_char and w ~= 0 then
+ -- so we inherit attributes, lineend is new pseudo head
+ lineend, c = insert_node_after(lineend,c,new_rightmarginkern(copy_node(last_rightmost_char),-w))
+ end
end
- if post then
- setlink(lastnode,post)
- setlink(posttail,nextlast)
- post_disc_break = true
+ end
+ -- we finish the line
+ local r = getnext(lineend)
+ setnext(lineend)
+ if not glue_break then
+ if rightskip then
+ insert_node_after(lineend,lineend,new_rightskip(right_skip)) -- lineend moves on as pseudo head
end
- setdisc(lastnode) -- nil, nil, nil
- disc_break = true
- elseif id == kern_code then
- setkern(lastnode,0)
- elseif getid(lastnode) == math_code then
- setkern(lastnode,0) -- surround
- -- new in luatex
- setglue(lastnode) -- zeros
end
- end
- lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break)
- local rightbox = current_break.passive_right_box
- if rightbox then
- lastnode = insert_node_after(lastnode,lastnode,copy_node(rightbox))
- end
- if not lineend then
- lineend = lastnode
- end
- if lineend and lineend ~= head and protrude_chars > 0 then
- local id = getid(lineend)
- local c = (disc_break and (id == glyph_code or id ~= disc_code) and lineend) or getprev(lineend)
- local p = find_protchar_right(getnext(head),c)
- if p and getid(p) == glyph_code then
- local w, last_rightmost_char = right_pw(p)
- if last_rightmost_char and w ~= 0 then
- -- so we inherit attributes, lineend is new pseudo head
- lineend, c = insert_node_after(lineend,c,new_rightmarginkern(copy_node(last_rightmost_char),-w))
+ -- each time ?
+ local q = getnext(head)
+ setlink(head,r)
+ -- insert leftbox (if needed after parindent)
+ local leftbox = current_break.passive_left_box
+ if leftbox then
+ local first = getnext(q)
+ if first and current_line == (par.first_line + 1) and getid(first) == hlist_code and not getlist(first) then
+ insert_node_after(q,q,copy_node(leftbox))
+ else
+ q = insert_node_before(q,q,copy_node(leftbox))
end
end
- end
- -- we finish the line
- local r = getnext(lineend)
- setnext(lineend)
- if not glue_break then
- if rightskip then
- insert_node_after(lineend,lineend,new_rightskip(right_skip)) -- lineend moves on as pseudo head
+ if protrude_chars > 0 then
+ local p = find_protchar_left(q)
+ if p and getid(p) == glyph_code then
+ local w, last_leftmost_char = left_pw(p)
+ if last_leftmost_char and w ~= 0 then
+ -- so we inherit attributes, q is pseudo head and moves back
+ q = insert_node_before(q,q,new_leftmarginkern(copy_node(last_leftmost_char),-w))
+ end
+ end
end
- end
- -- each time ?
- local q = getnext(head)
- setlink(head,r)
- -- insert leftbox (if needed after parindent)
- local leftbox = current_break.passive_left_box
- if leftbox then
- local first = getnext(q)
- if first and current_line == (par.first_line + 1) and getid(first) == hlist_code and not getlist(first) then
- insert_node_after(q,q,copy_node(leftbox))
+ if leftskip then
+ q = insert_node_before(q,q,new_leftskip(leftskip))
+ end
+ local cur_width, cur_indent
+ if current_line > par.last_special_line then
+ cur_indent = par.second_indent
+ cur_width = par.second_width
+ elseif parshape then
+ local shape = parshape[current_line]
+ cur_indent = shape[1]
+ cur_width = shape[2]
else
- q = insert_node_before(q,q,copy_node(leftbox))
- end
- end
- if protrude_chars > 0 then
- local p = find_protchar_left(q)
- if p and getid(p) == glyph_code then
- local w, last_leftmost_char = left_pw(p)
- if last_leftmost_char and w ~= 0 then
- -- so we inherit attributes, q is pseudo head and moves back
- q = insert_node_before(q,q,new_leftmarginkern(copy_node(last_leftmost_char),-w))
- end
+ cur_indent = par.first_indent
+ cur_width = par.first_width
end
- end
- if leftskip then
- q = insert_node_before(q,q,new_leftskip(leftskip))
- end
- local cur_width, cur_indent
- if current_line > par.last_special_line then
- cur_indent = par.second_indent
- cur_width = par.second_width
- elseif parshape then
- local shape = parshape[current_line]
- cur_indent = shape[1]
- cur_width = shape[2]
- else
- cur_indent = par.first_indent
- cur_width = par.first_width
- end
- if adapt_width then -- extension
- local l, r = adapt_width(par,current_line)
- cur_indent = cur_indent + l
- cur_width = cur_width - l - r
- end
+ if adapt_width then -- extension
+ local l, r = adapt_width(par,current_line)
+ cur_indent = cur_indent + l
+ cur_width = cur_width - l - r
+ end
- statistics.noflines = statistics.noflines + 1
- local finished_line = nil
- if adjust_spacing > 0 then
- statistics.nofadjustedlines = statistics.nofadjustedlines + 1
- finished_line = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
- else
- finished_line = xpack_nodes(q,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
- end
- if protrude_chars > 0 then
- statistics.nofprotrudedlines = statistics.nofprotrudedlines + 1
- end
- -- wrong:
- local adjust_head = texlists.adjust_head
- local pre_adjust_head = texlists.pre_adjust_head
- --
- setshift(finished_line,cur_indent)
- --
- -- -- this is gone:
- --
- -- if par.each_line_height ~= ignored_dimen then
- -- setheight(finished_line,par.each_line_height)
- -- end
- -- if par.each_line_depth ~= ignored_dimen then
- -- setdepth(finished_line,par.each_line_depth)
- -- end
- -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then
- -- setheight(finished_line,par.first_line_height)
- -- end
- -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then
- -- setdepth(finished_line,par.last_line_depth)
- -- end
- --
- if texlists.pre_adjust_head ~= pre_adjust_head then
- append_list(par, texlists.pre_adjust_head)
- texlists.pre_adjust_head = pre_adjust_head
- end
- append_to_vlist(par,finished_line)
- if texlists.adjust_head ~= adjust_head then
- append_list(par, texlists.adjust_head)
- texlists.adjust_head = adjust_head
- end
- --
- local pen
- if current_line + 1 ~= par.best_line then
- if current_break.passive_pen_inter then
- pen = current_break.passive_pen_inter
+ statistics.noflines = statistics.noflines + 1
+ local finished_line = nil
+ if adjust_spacing > 0 then
+ statistics.nofadjustedlines = statistics.nofadjustedlines + 1
+ finished_line = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
else
- pen = par.inter_line_penalty
- end
- if current_line == prevgraf + 1 then
- pen = pen + par.club_penalty
- end
- if current_line + 2 == par.best_line then
- if par.display then
- pen = pen + par.display_widow_penalty
+ finished_line = xpack_nodes(q,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
+ end
+ if protrude_chars > 0 then
+ statistics.nofprotrudedlines = statistics.nofprotrudedlines + 1
+ end
+ -- wrong:
+ local adjust_head = texlists.adjust_head
+ local pre_adjust_head = texlists.pre_adjust_head
+ --
+ setshift(finished_line,cur_indent)
+ --
+ -- -- this is gone:
+ --
+ -- if par.each_line_height ~= ignored_dimen then
+ -- setheight(finished_line,par.each_line_height)
+ -- end
+ -- if par.each_line_depth ~= ignored_dimen then
+ -- setdepth(finished_line,par.each_line_depth)
+ -- end
+ -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then
+ -- setheight(finished_line,par.first_line_height)
+ -- end
+ -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then
+ -- setdepth(finished_line,par.last_line_depth)
+ -- end
+ --
+ if texlists.pre_adjust_head ~= pre_adjust_head then
+ append_list(par, texlists.pre_adjust_head)
+ texlists.pre_adjust_head = pre_adjust_head
+ end
+ append_to_vlist(par,finished_line)
+ if texlists.adjust_head ~= adjust_head then
+ append_list(par, texlists.adjust_head)
+ texlists.adjust_head = adjust_head
+ end
+ --
+ local pen
+ if current_line + 1 ~= par.best_line then
+ if current_break.passive_pen_inter then
+ pen = current_break.passive_pen_inter
else
- pen = pen + par.widow_penalty
+ pen = par.inter_line_penalty
end
- end
- if disc_break then
- if current_break.passive_pen_broken ~= 0 then
- pen = pen + current_break.passive_pen_broken
- else
- pen = pen + par.broken_penalty
+ if current_line == prevgraf + 1 then
+ pen = pen + par.club_penalty
end
- end
- if pen ~= 0 then
- append_to_vlist(par,new_penalty(pen))
- end
- end
- current_line = current_line + 1
- current_break = current_break.prev_break
- if current_break and not post_disc_break then
- local current = head
- local next = nil
- while true do
- next = getnext(current)
- if next == current_break.cur_break then
- break
+ if current_line + 2 == par.best_line then
+ if par.display then
+ pen = pen + par.display_widow_penalty
+ else
+ pen = pen + par.widow_penalty
+ end
end
- local id = getid(next)
- if id == glyph_code then
- break
- elseif id == localpar_code then
- -- nothing
- elseif id < math_code then
- -- messy criterium
- break
- elseif id == math_code then
- -- keep the math node
- setkern(next,0) -- surround
- -- new in luatex
- setglue(lastnode) -- zeros
- break
- elseif id == kern_code then
- local subtype = getsubtype(next)
- if subtype == fontkern_code or subtype == accentkern_code then
- -- fontkerns and accent kerns as well as otf injections
- break
+ if disc_break then
+ if current_break.passive_pen_broken ~= 0 then
+ pen = pen + current_break.passive_pen_broken
+ else
+ pen = pen + par.broken_penalty
end
end
- current = next
+ if pen ~= 0 then
+ append_to_vlist(par,new_penalty(pen))
+ end
end
- if current ~= head then
- setnext(current)
- flush_node_list(getnext(head))
- setlink(head,next)
+ current_line = current_line + 1
+ current_break = current_break.prev_break
+ if current_break and not post_disc_break then
+ local current = head
+ local next = nil
+ while true do
+ next = getnext(current)
+ if next == current_break.cur_break then
+ break
+ end
+ local id = getid(next)
+ if id == glyph_code then
+ break
+ elseif id == localpar_code then
+ -- nothing
+ elseif id < math_code then
+ -- messy criterium
+ break
+ elseif id == math_code then
+ -- keep the math node
+ setkern(next,0) -- surround
+ -- new in luatex
+ setglue(lastnode) -- zeros
+ break
+ elseif id == kern_code then
+ local subtype = getsubtype(next)
+ if subtype == fontkern_code or subtype == accentkern_code then
+ -- fontkerns and accent kerns as well as otf injections
+ break
+ end
+ end
+ current = next
+ end
+ if current ~= head then
+ setnext(current)
+ flush_node_list(getnext(head))
+ setlink(head,next)
+ end
end
end
- end
- -- if current_line ~= par.best_line then
- -- report_parbuilders("line breaking")
- -- end
- par.head = nil -- needs checking
- current_line = current_line - 1
- if trace_basic then
- report_parbuilders("paragraph broken into %a lines",current_line)
- end
- texnest[texnest.ptr].prevgraf = current_line
-end
-
-local function wrap_up(par)
- if par.tracing_paragraphs then
- diagnostics.stop()
- end
- if par.do_last_line_fit then
- local best_bet = par.best_bet
- local active_short = best_bet.active_short
- local active_glue = best_bet.active_glue
- if active_short == 0 then
- if trace_lastlinefit then
- report_parbuilders("disabling last line fit, no active_short")
- end
- par.do_last_line_fit = false
- else
- local glue = par.final_par_glue
- setwidth(glue,getwidth(glue) + active_short - active_glue)
- setfield(glue,"stretch",0)
- if trace_lastlinefit then
- report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue)
- end
+ -- if current_line ~= par.best_line then
+ -- report_parbuilders("line breaking")
+ -- end
+ par.head = nil -- needs checking
+ current_line = current_line - 1
+ if trace_basic then
+ report_parbuilders("paragraph broken into %a lines",current_line)
end
+ texnest[texnest.ptr].prevgraf = current_line
end
- -- we have a bunch of glue and and temp nodes not freed
- local head = par.head
- if getid(head) == temp_code then
- par.head = getnext(head)
- flush_node(head)
- end
- post_line_break(par)
- reset_meta(par)
- register_statistics(par)
- return par.head_field
-end
--- we could do active nodes differently ... table instead of linked list or a list
--- with prev nodes but it doesn't save much (as we still need to keep indices then
--- in next)
-
-local function deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) -- no need for adjust if disabled
- local active = par.active
- local active_width = par.active_width
- prev_r.next = r.next
- -- removes r
- -- r = nil
- if prev_r == active then
- r = active.next
- if r.id == delta_code then
- local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw
- local aw = active_width.stretch + r.stretch active_width.stretch = aw cur_active_width.stretch = aw
- local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw
- local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw
- local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw
- local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw
- local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw
- if checked_expansion then
- local aw = active_width.adjust_stretch + r.adjust_stretch active_width.adjust_stretch = aw cur_active_width.adjust_stretch = aw
- local aw = active_width.adjust_shrink + r.adjust_shrink active_width.adjust_shrink = aw cur_active_width.adjust_shrink = aw
- end
- active.next = r.next
- -- removes r
- -- r = nil
+ local function wrap_up(par)
+ if par.tracing_paragraphs then
+ diagnostics.stop()
end
- elseif prev_r.id == delta_code then
- r = prev_r.next
- if r == active then
- cur_active_width.size = cur_active_width.size - prev_r.size
- cur_active_width.stretch = cur_active_width.stretch - prev_r.stretch
- cur_active_width.fi = cur_active_width.fi - prev_r.fi
- cur_active_width.fil = cur_active_width.fil - prev_r.fil
- cur_active_width.fill = cur_active_width.fill - prev_r.fill
- cur_active_width.filll = cur_active_width.filll - prev_r.filll
- cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink
- if checked_expansion then
- cur_active_width.adjust_stretch = cur_active_width.adjust_stretch - prev_r.adjust_stretch
- cur_active_width.adjust_shrink = cur_active_width.adjust_shrink - prev_r.adjust_shrink
+ if par.do_last_line_fit then
+ local best_bet = par.best_bet
+ local active_short = best_bet.active_short
+ local active_glue = best_bet.active_glue
+ if active_short == 0 then
+ if trace_lastlinefit then
+ report_parbuilders("disabling last line fit, no active_short")
+ end
+ par.do_last_line_fit = false
+ else
+ local glue = par.final_par_glue
+ setwidth(glue,getwidth(glue) + active_short - active_glue)
+ setfield(glue,"stretch",0)
+ if trace_lastlinefit then
+ report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue)
+ end
end
- prev_prev_r.next = active
- -- removes prev_r
- -- prev_r = nil
- prev_r = prev_prev_r
- elseif r.id == delta_code then
- local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn
- local rn = r.stretch cur_active_width.stretch = cur_active_width.stretch + rn prev_r.stretch = prev_r.stretch + rn
- local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn
- local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn
- local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn
- local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn
- local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn
- if checked_expansion then
- local rn = r.adjust_stretch cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + rn prev_r.adjust_stretch = prev_r.adjust_stretch + rn
- local rn = r.adjust_shrink cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + rn prev_r.adjust_shrink = prev_r.adjust_shrink + rn
+ end
+ -- we have a bunch of glue and and temp nodes not freed
+ local head = par.head
+ if getid(head) == temp_code then
+ par.head = getnext(head)
+ flush_node(head)
+ end
+ post_line_break(par)
+ reset_meta(par)
+ register_statistics(par)
+ return par.head_field
+ end
+
+ -- we could do active nodes differently ... table instead of linked list or a list
+ -- with prev nodes but it doesn't save much (as we still need to keep indices then
+ -- in next)
+
+ local function deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) -- no need for adjust if disabled
+ local active = par.active
+ local active_width = par.active_width
+ prev_r.next = r.next
+ -- removes r
+ -- r = nil
+ if prev_r == active then
+ r = active.next
+ if r.id == delta_code then
+ local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw
+ local aw = active_width.stretch + r.stretch active_width.stretch = aw cur_active_width.stretch = aw
+ local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw
+ local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw
+ local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw
+ local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw
+ local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw
+ if checked_expansion then
+ local aw = active_width.adjust_stretch + r.adjust_stretch active_width.adjust_stretch = aw cur_active_width.adjust_stretch = aw
+ local aw = active_width.adjust_shrink + r.adjust_shrink active_width.adjust_shrink = aw cur_active_width.adjust_shrink = aw
+ end
+ active.next = r.next
+ -- removes r
+ -- r = nil
+ end
+ elseif prev_r.id == delta_code then
+ r = prev_r.next
+ if r == active then
+ cur_active_width.size = cur_active_width.size - prev_r.size
+ cur_active_width.stretch = cur_active_width.stretch - prev_r.stretch
+ cur_active_width.fi = cur_active_width.fi - prev_r.fi
+ cur_active_width.fil = cur_active_width.fil - prev_r.fil
+ cur_active_width.fill = cur_active_width.fill - prev_r.fill
+ cur_active_width.filll = cur_active_width.filll - prev_r.filll
+ cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink
+ if checked_expansion then
+ cur_active_width.adjust_stretch = cur_active_width.adjust_stretch - prev_r.adjust_stretch
+ cur_active_width.adjust_shrink = cur_active_width.adjust_shrink - prev_r.adjust_shrink
+ end
+ prev_prev_r.next = active
+ -- removes prev_r
+ -- prev_r = nil
+ prev_r = prev_prev_r
+ elseif r.id == delta_code then
+ local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn
+ local rn = r.stretch cur_active_width.stretch = cur_active_width.stretch + rn prev_r.stretch = prev_r.stretch + rn
+ local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn
+ local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn
+ local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn
+ local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn
+ local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn
+ if checked_expansion then
+ local rn = r.adjust_stretch cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + rn prev_r.adjust_stretch = prev_r.adjust_stretch + rn
+ local rn = r.adjust_shrink cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + rn prev_r.adjust_shrink = prev_r.adjust_shrink + rn
+ end
+ prev_r.next = r.next
+ -- removes r
+ -- r = nil
end
- prev_r.next = r.next
- -- removes r
- -- r = nil
end
+ return prev_r, r
end
- return prev_r, r
-end
-local function lastlinecrap(shortfall,active_short,active_glue,cur_active_width,fill_width,last_line_fit)
- if active_short == 0 or active_glue <= 0 then
- return false, 0, fit_decent_class, 0, 0
- end
- if cur_active_width.fi ~= fill_width.fi or cur_active_width.fil ~= fill_width.fil or cur_active_width.fill ~= fill_width.fill or cur_active_width.filll ~= fill_width.filll then
- return false, 0, fit_decent_class, 0, 0
- end
- local adjustment = active_short > 0 and cur_active_width.stretch or cur_active_width.shrink
- if adjustment <= 0 then
- return false, 0, fit_decent_class, adjustment, 0
- end
- adjustment = calculate_fraction(adjustment,active_short,active_glue,maxdimen)
- if last_line_fit < 1000 then
- adjustment = calculate_fraction(adjustment,last_line_fit,1000,maxdimen) -- uses previous adjustment
- end
- local fit_class = fit_decent_class
- if adjustment > 0 then
- local stretch = cur_active_width.stretch
- if adjustment > shortfall then
- adjustment = shortfall
- end
- if adjustment > 7230584 and stretch < 1663497 then
- return true, fit_very_loose_class, shortfall, adjustment, infinite_badness
+ local function lastlinecrap(shortfall,active_short,active_glue,cur_active_width,fill_width,last_line_fit)
+ if active_short == 0 or active_glue <= 0 then
+ return false, 0, fit_decent_class, 0, 0
end
- -- if adjustment == 0 then -- badness = 0
- -- return true, shortfall, fit_decent_class, 0, 0
- -- elseif stretch <= 0 then -- badness = 10000
- -- return true, shortfall, fit_very_loose_class, adjustment, 10000
- -- end
- -- local badness = (adjustment == 0 and 0) or (stretch <= 0 and 10000) or calculate_badness(adjustment,stretch)
- local badness = calculate_badness(adjustment,stretch)
- if badness > 99 then
- return true, shortfall, fit_very_loose_class, adjustment, badness
- elseif badness > 12 then
- return true, shortfall, fit_loose_class, adjustment, badness
- else
- return true, shortfall, fit_decent_class, adjustment, badness
+ if cur_active_width.fi ~= fill_width.fi or cur_active_width.fil ~= fill_width.fil or cur_active_width.fill ~= fill_width.fill or cur_active_width.filll ~= fill_width.filll then
+ return false, 0, fit_decent_class, 0, 0
end
- elseif adjustment < 0 then
- local shrink = cur_active_width.shrink
- if -adjustment > shrink then
- adjustment = -shrink
+ local adjustment = active_short > 0 and cur_active_width.stretch or cur_active_width.shrink
+ if adjustment <= 0 then
+ return false, 0, fit_decent_class, adjustment, 0
end
- local badness = calculate_badness(-adjustment,shrink)
- if badness > 12 then
- return true, shortfall, fit_tight_class, adjustment, badness
- else
- return true, shortfall, fit_decent_class, adjustment, badness
+ adjustment = calculate_fraction(adjustment,active_short,active_glue,maxdimen)
+ if last_line_fit < 1000 then
+ adjustment = calculate_fraction(adjustment,last_line_fit,1000,maxdimen) -- uses previous adjustment
end
- else
- return false, 0, fit_decent_class, 0, 0
- end
-end
-
--- todo: statistics .. count tries and so
-
-local trialcount = 0
-
-local function try_break(pi, break_type, par, first_p, current, checked_expansion)
-
--- trialcount = trialcount + 1
--- print(trialcount,pi,break_type,current,nuts.tostring(current))
-
- if pi >= infinite_penalty then -- this breakpoint is inhibited by infinite penalty
- local p_active = par.active
- return p_active, p_active and p_active.next
- elseif pi <= -infinite_penalty then -- this breakpoint will be forced
- pi = eject_penalty
- end
-
- local prev_prev_r = nil -- a step behind prev_r, if type(prev_r)=delta_code
- local prev_r = par.active -- stays a step behind r
- local r = nil -- runs through the active list
- local no_break_yet = true -- have we found a feasible break at current?
- local node_r_stays_active = false -- should node r remain in the active list?
- local line_width = 0 -- the current line will be justified to this width
- local line_number = 0 -- line number of current active node
- local old_line_number = 0 -- maximum line number in current equivalence class of lines
-
- local protrude_chars = par.protrude_chars
- local checked_expansion = par.checked_expansion
- local break_width = par.break_width
- local active_width = par.active_width
- local background = par.background
- local minimal_demerits = par.minimal_demerits
- local best_place = par.best_place
- local best_pl_line = par.best_pl_line
- local best_pl_short = par.best_pl_short
- local best_pl_glue = par.best_pl_glue
- local do_last_line_fit = par.do_last_line_fit
- local final_pass = par.final_pass
- local tracing_paragraphs = par.tracing_paragraphs
- -- local par_active = par.active
-
- local adapt_width = par.adapt_width
-
- local parshape = par.par_shape_ptr
-
- local cur_active_width = checked_expansion and { -- distance from current active node
- size = active_width.size,
- stretch = active_width.stretch,
- fi = active_width.fi,
- fil = active_width.fil,
- fill = active_width.fill,
- filll = active_width.filll,
- shrink = active_width.shrink,
- adjust_stretch = active_width.adjust_stretch,
- adjust_shrink = active_width.adjust_shrink,
- } or {
- size = active_width.size,
- stretch = active_width.stretch,
- fi = active_width.fi,
- fil = active_width.fil,
- fill = active_width.fill,
- filll = active_width.filll,
- shrink = active_width.shrink,
- }
-
- while true do
- r = prev_r.next
- if r.id == delta_code then
- cur_active_width.size = cur_active_width.size + r.size
- cur_active_width.stretch = cur_active_width.stretch + r.stretch
- cur_active_width.fi = cur_active_width.fi + r.fi
- cur_active_width.fil = cur_active_width.fil + r.fil
- cur_active_width.fill = cur_active_width.fill + r.fill
- cur_active_width.filll = cur_active_width.filll + r.filll
- cur_active_width.shrink = cur_active_width.shrink + r.shrink
- if checked_expansion then
- cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + r.adjust_stretch
- cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + r.adjust_shrink
+ local fit_class = fit_decent_class
+ if adjustment > 0 then
+ local stretch = cur_active_width.stretch
+ if adjustment > shortfall then
+ adjustment = shortfall
+ end
+ if adjustment > 7230584 and stretch < 1663497 then
+ return true, fit_very_loose_class, shortfall, adjustment, infinite_badness
+ end
+ -- if adjustment == 0 then -- badness = 0
+ -- return true, shortfall, fit_decent_class, 0, 0
+ -- elseif stretch <= 0 then -- badness = 10000
+ -- return true, shortfall, fit_very_loose_class, adjustment, 10000
+ -- end
+ -- local badness = (adjustment == 0 and 0) or (stretch <= 0 and 10000) or calculate_badness(adjustment,stretch)
+ local badness = calculate_badness(adjustment,stretch)
+ if badness > 99 then
+ return true, shortfall, fit_very_loose_class, adjustment, badness
+ elseif badness > 12 then
+ return true, shortfall, fit_loose_class, adjustment, badness
+ else
+ return true, shortfall, fit_decent_class, adjustment, badness
+ end
+ elseif adjustment < 0 then
+ local shrink = cur_active_width.shrink
+ if -adjustment > shrink then
+ adjustment = -shrink
+ end
+ local badness = calculate_badness(-adjustment,shrink)
+ if badness > 12 then
+ return true, shortfall, fit_tight_class, adjustment, badness
+ else
+ return true, shortfall, fit_decent_class, adjustment, badness
end
- prev_prev_r = prev_r
- prev_r = r
else
- line_number = r.line_number
- if line_number > old_line_number then
- local minimum_demerits = par.minimum_demerits
- if minimum_demerits < awful_badness and (old_line_number ~= par.easy_line or r == par.active) then
- if no_break_yet then
- no_break_yet = false
- break_width.size = background.size
- break_width.stretch = background.stretch
- break_width.fi = background.fi
- break_width.fil = background.fil
- break_width.fill = background.fill
- break_width.filll = background.filll
- break_width.shrink = background.shrink
- if checked_expansion then
- break_width.adjust_stretch = 0
- break_width.adjust_shrink = 0
+ return false, 0, fit_decent_class, 0, 0
+ end
+ end
+
+ -- todo: statistics .. count tries and so
+
+ local trialcount = 0
+
+ local function try_break(pi, break_type, par, first_p, current, checked_expansion)
+
+ -- trialcount = trialcount + 1
+ -- print(trialcount,pi,break_type,current,nuts.tostring(current))
+
+ if pi >= infinite_penalty then -- this breakpoint is inhibited by infinite penalty
+ local p_active = par.active
+ return p_active, p_active and p_active.next
+ elseif pi <= -infinite_penalty then -- this breakpoint will be forced
+ pi = eject_penalty
+ end
+
+ local prev_prev_r = nil -- a step behind prev_r, if type(prev_r)=delta_code
+ local prev_r = par.active -- stays a step behind r
+ local r = nil -- runs through the active list
+ local no_break_yet = true -- have we found a feasible break at current?
+ local node_r_stays_active = false -- should node r remain in the active list?
+ local line_width = 0 -- the current line will be justified to this width
+ local line_number = 0 -- line number of current active node
+ local old_line_number = 0 -- maximum line number in current equivalence class of lines
+
+ local protrude_chars = par.protrude_chars
+ local checked_expansion = par.checked_expansion
+ local break_width = par.break_width
+ local active_width = par.active_width
+ local background = par.background
+ local minimal_demerits = par.minimal_demerits
+ local best_place = par.best_place
+ local best_pl_line = par.best_pl_line
+ local best_pl_short = par.best_pl_short
+ local best_pl_glue = par.best_pl_glue
+ local do_last_line_fit = par.do_last_line_fit
+ local final_pass = par.final_pass
+ local tracing_paragraphs = par.tracing_paragraphs
+ -- local par_active = par.active
+
+ local adapt_width = par.adapt_width
+
+ local parshape = par.par_shape_ptr
+
+ local cur_active_width = checked_expansion and { -- distance from current active node
+ size = active_width.size,
+ stretch = active_width.stretch,
+ fi = active_width.fi,
+ fil = active_width.fil,
+ fill = active_width.fill,
+ filll = active_width.filll,
+ shrink = active_width.shrink,
+ adjust_stretch = active_width.adjust_stretch,
+ adjust_shrink = active_width.adjust_shrink,
+ } or {
+ size = active_width.size,
+ stretch = active_width.stretch,
+ fi = active_width.fi,
+ fil = active_width.fil,
+ fill = active_width.fill,
+ filll = active_width.filll,
+ shrink = active_width.shrink,
+ }
+
+ while true do
+ r = prev_r.next
+ if r.id == delta_code then
+ cur_active_width.size = cur_active_width.size + r.size
+ cur_active_width.stretch = cur_active_width.stretch + r.stretch
+ cur_active_width.fi = cur_active_width.fi + r.fi
+ cur_active_width.fil = cur_active_width.fil + r.fil
+ cur_active_width.fill = cur_active_width.fill + r.fill
+ cur_active_width.filll = cur_active_width.filll + r.filll
+ cur_active_width.shrink = cur_active_width.shrink + r.shrink
+ if checked_expansion then
+ cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + r.adjust_stretch
+ cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + r.adjust_shrink
+ end
+ prev_prev_r = prev_r
+ prev_r = r
+ else
+ line_number = r.line_number
+ if line_number > old_line_number then
+ local minimum_demerits = par.minimum_demerits
+ if minimum_demerits < awful_badness and (old_line_number ~= par.easy_line or r == par.active) then
+ if no_break_yet then
+ no_break_yet = false
+ break_width.size = background.size
+ break_width.stretch = background.stretch
+ break_width.fi = background.fi
+ break_width.fil = background.fil
+ break_width.fill = background.fill
+ break_width.filll = background.filll
+ break_width.shrink = background.shrink
+ if checked_expansion then
+ break_width.adjust_stretch = 0
+ break_width.adjust_shrink = 0
+ end
+ if current then
+ compute_break_width(par,break_type,current)
+ end
end
- if current then
- compute_break_width(par,break_type,current)
+ if prev_r.id == delta_code then
+ prev_r.size = prev_r.size - cur_active_width.size + break_width.size
+ prev_r.stretch = prev_r.stretch - cur_active_width.stretc + break_width.stretch
+ prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi
+ prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil
+ prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill
+ prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll
+ prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink
+ if checked_expansion then
+ prev_r.adjust_stretch = prev_r.adjust_stretch - cur_active_width.adjust_stretch + break_width.adjust_stretch
+ prev_r.adjust_shrink = prev_r.adjust_shrink - cur_active_width.adjust_shrink + break_width.adjust_shrink
+ end
+ elseif prev_r == par.active then
+ active_width.size = break_width.size
+ active_width.stretch = break_width.stretch
+ active_width.fi = break_width.fi
+ active_width.fil = break_width.fil
+ active_width.fill = break_width.fill
+ active_width.filll = break_width.filll
+ active_width.shrink = break_width.shrink
+ if checked_expansion then
+ active_width.adjust_stretch = break_width.adjust_stretch
+ active_width.adjust_shrink = break_width.adjust_shrink
+ end
+ else
+ local q = checked_expansion and {
+ id = delta_code,
+ subtype = nosubtype_code,
+ next = r,
+ size = break_width.size - cur_active_width.size,
+ stretch = break_width.stretch - cur_active_width.stretch,
+ fi = break_width.fi - cur_active_width.fi,
+ fil = break_width.fil - cur_active_width.fil,
+ fill = break_width.fill - cur_active_width.fill,
+ filll = break_width.filll - cur_active_width.filll,
+ shrink = break_width.shrink - cur_active_width.shrink,
+ adjust_stretch = break_width.adjust_stretch - cur_active_width.adjust_stretch,
+ adjust_shrink = break_width.adjust_shrink - cur_active_width.adjust_shrink,
+ } or {
+ id = delta_code,
+ subtype = nosubtype_code,
+ next = r,
+ size = break_width.size - cur_active_width.size,
+ stretch = break_width.stretch - cur_active_width.stretch,
+ fi = break_width.fi - cur_active_width.fi,
+ fil = break_width.fil - cur_active_width.fil,
+ fill = break_width.fill - cur_active_width.fill,
+ filll = break_width.filll - cur_active_width.filll,
+ shrink = break_width.shrink - cur_active_width.shrink,
+ }
+ prev_r.next = q
+ prev_prev_r = prev_r
+ prev_r = q
end
- end
- if prev_r.id == delta_code then
- prev_r.size = prev_r.size - cur_active_width.size + break_width.size
- prev_r.stretch = prev_r.stretch - cur_active_width.stretc + break_width.stretch
- prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi
- prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil
- prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill
- prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll
- prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink
- if checked_expansion then
- prev_r.adjust_stretch = prev_r.adjust_stretch - cur_active_width.adjust_stretch + break_width.adjust_stretch
- prev_r.adjust_shrink = prev_r.adjust_shrink - cur_active_width.adjust_shrink + break_width.adjust_shrink
+ local adj_demerits = par.adj_demerits
+ local abs_adj_demerits = adj_demerits > 0 and adj_demerits or -adj_demerits
+ if abs_adj_demerits >= awful_badness - minimum_demerits then
+ minimum_demerits = awful_badness - 1
+ else
+ minimum_demerits = minimum_demerits + abs_adj_demerits
end
- elseif prev_r == par.active then
- active_width.size = break_width.size
- active_width.stretch = break_width.stretch
- active_width.fi = break_width.fi
- active_width.fil = break_width.fil
- active_width.fill = break_width.fill
- active_width.filll = break_width.filll
- active_width.shrink = break_width.shrink
- if checked_expansion then
- active_width.adjust_stretch = break_width.adjust_stretch
- active_width.adjust_shrink = break_width.adjust_shrink
+ for fit_class = fit_very_loose_class, fit_tight_class do
+ if minimal_demerits[fit_class] <= minimum_demerits then
+ -- insert a new active node from best_place[fit_class] to current
+ par.pass_number = par.pass_number + 1
+ local prev_break = best_place[fit_class]
+ local passive = {
+ id = passive_code,
+ subtype = nosubtype_code,
+ next = par.passive,
+ cur_break = current,
+ serial = par.pass_number,
+ prev_break = prev_break,
+ passive_pen_inter = par.internal_pen_inter,
+ passive_pen_broken = par.internal_pen_broken,
+ passive_last_left_box = par.internal_left_box,
+ passive_last_left_box_width = par.internal_left_box_width,
+ passive_left_box = prev_break and prev_break.passive_last_left_box or par.init_internal_left_box,
+ passive_left_box_width = prev_break and prev_break.passive_last_left_box_width or par.init_internal_left_box_width,
+ passive_right_box = par.internal_right_box,
+ passive_right_box_width = par.internal_right_box_width,
+ -- analysis = table.fastcopy(cur_active_width),
+ }
+ par.passive = passive
+ local q = {
+ id = break_type,
+ subtype = fit_class,
+ break_node = passive,
+ line_number = best_pl_line[fit_class] + 1,
+ total_demerits = minimal_demerits[fit_class], -- or 0,
+ next = r,
+ }
+ if do_last_line_fit then
+ local active_short = best_pl_short[fit_class]
+ local active_glue = best_pl_glue[fit_class]
+ q.active_short = active_short
+ q.active_glue = active_glue
+ if trace_lastlinefit then
+ report_parbuilders("setting short to %i and glue to %p using class %a",active_short,active_glue,fit_class)
+ end
+ end
+ -- q.next = r -- already done
+ prev_r.next = q
+ prev_r = q
+ if tracing_paragraphs then
+ diagnostics.break_node(par,q,fit_class,break_type,current)
+ end
+ end
+ minimal_demerits[fit_class] = awful_badness
end
- else
- local q = checked_expansion and {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = break_width.size - cur_active_width.size,
- stretch = break_width.stretch - cur_active_width.stretch,
- fi = break_width.fi - cur_active_width.fi,
- fil = break_width.fil - cur_active_width.fil,
- fill = break_width.fill - cur_active_width.fill,
- filll = break_width.filll - cur_active_width.filll,
- shrink = break_width.shrink - cur_active_width.shrink,
- adjust_stretch = break_width.adjust_stretch - cur_active_width.adjust_stretch,
- adjust_shrink = break_width.adjust_shrink - cur_active_width.adjust_shrink,
- } or {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = break_width.size - cur_active_width.size,
- stretch = break_width.stretch - cur_active_width.stretch,
- fi = break_width.fi - cur_active_width.fi,
- fil = break_width.fil - cur_active_width.fil,
- fill = break_width.fill - cur_active_width.fill,
- filll = break_width.filll - cur_active_width.filll,
- shrink = break_width.shrink - cur_active_width.shrink,
- }
- prev_r.next = q
- prev_prev_r = prev_r
- prev_r = q
- end
- local adj_demerits = par.adj_demerits
- local abs_adj_demerits = adj_demerits > 0 and adj_demerits or -adj_demerits
- if abs_adj_demerits >= awful_badness - minimum_demerits then
- minimum_demerits = awful_badness - 1
- else
- minimum_demerits = minimum_demerits + abs_adj_demerits
- end
- for fit_class = fit_very_loose_class, fit_tight_class do
- if minimal_demerits[fit_class] <= minimum_demerits then
- -- insert a new active node from best_place[fit_class] to current
- par.pass_number = par.pass_number + 1
- local prev_break = best_place[fit_class]
- local passive = {
- id = passive_code,
- subtype = nosubtype_code,
- next = par.passive,
- cur_break = current,
- serial = par.pass_number,
- prev_break = prev_break,
- passive_pen_inter = par.internal_pen_inter,
- passive_pen_broken = par.internal_pen_broken,
- passive_last_left_box = par.internal_left_box,
- passive_last_left_box_width = par.internal_left_box_width,
- passive_left_box = prev_break and prev_break.passive_last_left_box or par.init_internal_left_box,
- passive_left_box_width = prev_break and prev_break.passive_last_left_box_width or par.init_internal_left_box_width,
- passive_right_box = par.internal_right_box,
- passive_right_box_width = par.internal_right_box_width,
--- analysis = table.fastcopy(cur_active_width),
- }
- par.passive = passive
- local q = {
- id = break_type,
- subtype = fit_class,
- break_node = passive,
- line_number = best_pl_line[fit_class] + 1,
- total_demerits = minimal_demerits[fit_class], -- or 0,
+ par.minimum_demerits = awful_badness
+ if r ~= par.active then
+ local q = checked_expansion and {
+ id = delta_code,
+ subtype = nosubtype_code,
+ next = r,
+ size = cur_active_width.size - break_width.size,
+ stretch = cur_active_width.stretch - break_width.stretch,
+ fi = cur_active_width.fi - break_width.fi,
+ fil = cur_active_width.fil - break_width.fil,
+ fill = cur_active_width.fill - break_width.fill,
+ filll = cur_active_width.filll - break_width.filll,
+ shrink = cur_active_width.shrink - break_width.shrink,
+ adjust_stretch = cur_active_width.adjust_stretch - break_width.adjust_stretch,
+ adjust_shrink = cur_active_width.adjust_shrink - break_width.adjust_shrink,
+ } or {
+ id = delta_code,
+ subtype = nosubtype_code,
next = r,
+ size = cur_active_width.size - break_width.size,
+ stretch = cur_active_width.stretch - break_width.stretch,
+ fi = cur_active_width.fi - break_width.fi,
+ fil = cur_active_width.fil - break_width.fil,
+ fill = cur_active_width.fill - break_width.fill,
+ filll = cur_active_width.filll - break_width.filll,
+ shrink = cur_active_width.shrink - break_width.shrink,
}
- if do_last_line_fit then
- local active_short = best_pl_short[fit_class]
- local active_glue = best_pl_glue[fit_class]
- q.active_short = active_short
- q.active_glue = active_glue
- if trace_lastlinefit then
- report_parbuilders("setting short to %i and glue to %p using class %a",active_short,active_glue,fit_class)
- end
- end
-- q.next = r -- already done
prev_r.next = q
+ prev_prev_r = prev_r
prev_r = q
- if tracing_paragraphs then
- diagnostics.break_node(par,q,fit_class,break_type,current)
- end
end
- minimal_demerits[fit_class] = awful_badness
- end
- par.minimum_demerits = awful_badness
- if r ~= par.active then
- local q = checked_expansion and {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = cur_active_width.size - break_width.size,
- stretch = cur_active_width.stretch - break_width.stretch,
- fi = cur_active_width.fi - break_width.fi,
- fil = cur_active_width.fil - break_width.fil,
- fill = cur_active_width.fill - break_width.fill,
- filll = cur_active_width.filll - break_width.filll,
- shrink = cur_active_width.shrink - break_width.shrink,
- adjust_stretch = cur_active_width.adjust_stretch - break_width.adjust_stretch,
- adjust_shrink = cur_active_width.adjust_shrink - break_width.adjust_shrink,
- } or {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = cur_active_width.size - break_width.size,
- stretch = cur_active_width.stretch - break_width.stretch,
- fi = cur_active_width.fi - break_width.fi,
- fil = cur_active_width.fil - break_width.fil,
- fill = cur_active_width.fill - break_width.fill,
- filll = cur_active_width.filll - break_width.filll,
- shrink = cur_active_width.shrink - break_width.shrink,
- }
- -- q.next = r -- already done
- prev_r.next = q
- prev_prev_r = prev_r
- prev_r = q
end
- end
- if r == par.active then
- return r, r and r.next -- p_active, n_active
- end
- if line_number > par.easy_line then
- old_line_number = max_halfword - 1
- line_width = par.second_width
- else
- old_line_number = line_number
- if line_number > par.last_special_line then
+ if r == par.active then
+ return r, r and r.next -- p_active, n_active
+ end
+ if line_number > par.easy_line then
+ old_line_number = max_halfword - 1
line_width = par.second_width
- elseif parshape then
- line_width = parshape[line_number][2]
else
- line_width = par.first_width
+ old_line_number = line_number
+ if line_number > par.last_special_line then
+ line_width = par.second_width
+ elseif parshape then
+ line_width = parshape[line_number][2]
+ else
+ line_width = par.first_width
+ end
end
- end
- if adapt_width then
- local l, r = adapt_width(par,line_number)
- line_width = line_width - l - r
- end
- end
- local artificial_demerits = false -- has d been forced to zero
- local shortfall = line_width - cur_active_width.size - par.internal_right_box_width -- used in badness calculations
- if not r.break_node then
- shortfall = shortfall - par.init_internal_left_box_width
- else
- shortfall = shortfall - (r.break_node.passive_last_left_box_width or 0)
- end
- local pw, lp, rp -- used later on
- if protrude_chars > 1 then
- -- this is quite time consuming
- local b = r.break_node
- local l = b and b.cur_break or first_p
- local o = current and getprev(current)
- if current and getid(current) == disc_code then
- local pre, _, _, pretail = getdisc(current,true)
- if pre then
- o = pretail
- else
- o = find_protchar_right(l,o)
+ if adapt_width then
+ local l, r = adapt_width(par,line_number)
+ line_width = line_width - l - r
end
- else
- o = find_protchar_right(l,o)
end
- if o and getid(o) == glyph_code then
- pw, rp = right_pw(o)
- shortfall = shortfall + pw
- end
- local id = getid(l)
- if id == glyph_code then
- -- ok ?
- elseif id == disc_code and getfield(l,"post") then
- l = getfield(l,"post") -- TODO: first char could be a disc
+ local artificial_demerits = false -- has d been forced to zero
+ local shortfall = line_width - cur_active_width.size - par.internal_right_box_width -- used in badness calculations
+ if not r.break_node then
+ shortfall = shortfall - par.init_internal_left_box_width
else
- l = find_protchar_left(l)
- end
- if l and getid(l) == glyph_code then
- pw, lp = left_pw(l)
- shortfall = shortfall + pw
+ shortfall = shortfall - (r.break_node.passive_last_left_box_width or 0)
end
- end
- if checked_expansion and shortfall ~= 0 then
- local margin_kern_stretch = 0
- local margin_kern_shrink = 0
+ local pw, lp, rp -- used later on
if protrude_chars > 1 then
- if lp then
- local data = expansions[getfont(lp)][getchar(lp)]
- if data then
- margin_kern_stretch, margin_kern_shrink = data.glyphstretch, data.glyphshrink
+ -- this is quite time consuming
+ local b = r.break_node
+ local l = b and b.cur_break or first_p
+ local o = current and getprev(current)
+ if current and getid(current) == disc_code then
+ local pre, _, _, pretail = getdisc(current,true)
+ if pre then
+ o = pretail
+ else
+ o = find_protchar_right(l,o)
end
+ else
+ o = find_protchar_right(l,o)
end
- if rp then
- local data = expansions[getfont(lp)][getchar(lp)]
- if data then
- margin_kern_stretch = margin_kern_stretch + data.glyphstretch
- margin_kern_shrink = margin_kern_shrink + data.glyphshrink
- end
+ if o and getid(o) == glyph_code then
+ pw, rp = right_pw(o)
+ shortfall = shortfall + pw
end
- end
- local total = cur_active_width.adjust_stretch + margin_kern_stretch
- if shortfall > 0 and total > 0 then
- if total > shortfall then
- shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2
+ local id = getid(l)
+ if id == glyph_code then
+ -- ok ?
+ elseif id == disc_code and getfield(l,"post") then
+ l = getfield(l,"post") -- TODO: first char could be a disc
else
- shortfall = shortfall - total
+ l = find_protchar_left(l)
end
- else
- total = cur_active_width.adjust_shrink + margin_kern_shrink
- if shortfall < 0 and total > 0 then
- if total > - shortfall then
- shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2
- else
- shortfall = shortfall + total
- end
+ if l and getid(l) == glyph_code then
+ pw, lp = left_pw(l)
+ shortfall = shortfall + pw
end
end
- end
- local b = 0
- local g = 0
- local fit_class = fit_decent_class
- local found = false
- if shortfall > 0 then
- if cur_active_width.fi ~= 0 or cur_active_width.fil ~= 0 or cur_active_width.fill ~= 0 or cur_active_width.filll ~= 0 then
- if not do_last_line_fit then
- -- okay
- elseif not current then
- found, shortfall, fit_class, g, b = lastlinecrap(shortfall,r.active_short,r.active_glue,cur_active_width,par.fill_width,par.last_line_fit)
+ if checked_expansion and shortfall ~= 0 then
+ local margin_kern_stretch = 0
+ local margin_kern_shrink = 0
+ if protrude_chars > 1 then
+ if lp then
+ local char, font = isglyph(lp)
+ local data = expansions[font][char]
+ if data then
+ margin_kern_stretch, margin_kern_shrink = data.glyphstretch, data.glyphshrink
+ end
+ end
+ if rp then
+ local char, font = isglyph(rp)
+ local data = expansions[font][char]
+ if data then
+ margin_kern_stretch = margin_kern_stretch + data.glyphstretch
+ margin_kern_shrink = margin_kern_shrink + data.glyphshrink
+ end
+ end
+ end
+ local total = cur_active_width.adjust_stretch + margin_kern_stretch
+ if shortfall > 0 and total > 0 then
+ if total > shortfall then
+ shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2
+ else
+ shortfall = shortfall - total
+ end
else
- shortfall = 0
+ total = cur_active_width.adjust_shrink + margin_kern_shrink
+ if shortfall < 0 and total > 0 then
+ if total > - shortfall then
+ shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2
+ else
+ shortfall = shortfall + total
+ end
+ end
end
- else
- local stretch = cur_active_width.stretch
- if shortfall > 7230584 and stretch < 1663497 then
- b = infinite_badness
- fit_class = fit_very_loose_class
+ end
+ local b = 0
+ local g = 0
+ local fit_class = fit_decent_class
+ local found = false
+ if shortfall > 0 then
+ if cur_active_width.fi ~= 0 or cur_active_width.fil ~= 0 or cur_active_width.fill ~= 0 or cur_active_width.filll ~= 0 then
+ if not do_last_line_fit then
+ -- okay
+ elseif not current then
+ found, shortfall, fit_class, g, b = lastlinecrap(shortfall,r.active_short,r.active_glue,cur_active_width,par.fill_width,par.last_line_fit)
+ else
+ shortfall = 0
+ end
else
- b = calculate_badness(shortfall,stretch)
- if b > 99 then
+ local stretch = cur_active_width.stretch
+ if shortfall > 7230584 and stretch < 1663497 then
+ b = infinite_badness
fit_class = fit_very_loose_class
- elseif b > 12 then
- fit_class = fit_loose_class
else
- fit_class = fit_decent_class
+ b = calculate_badness(shortfall,stretch)
+ if b > 99 then
+ fit_class = fit_very_loose_class
+ elseif b > 12 then
+ fit_class = fit_loose_class
+ else
+ fit_class = fit_decent_class
+ end
end
end
- end
- else
- local shrink = cur_active_width.shrink
- if -shortfall > shrink then
- b = infinite_badness + 1
- else
- b = calculate_badness(-shortfall,shrink)
- end
- if b > 12 then
- fit_class = fit_tight_class
- else
- fit_class = fit_decent_class
- end
- end
- if do_last_line_fit and not found then
- if not current then
- -- g = 0
- shortfall = 0
- elseif shortfall > 0 then
- g = cur_active_width.stretch
- elseif shortfall < 0 then
- g = cur_active_width.shrink
else
- g = 0
+ local shrink = cur_active_width.shrink
+ if -shortfall > shrink then
+ b = infinite_badness + 1
+ else
+ b = calculate_badness(-shortfall,shrink)
+ end
+ if b > 12 then
+ fit_class = fit_tight_class
+ else
+ fit_class = fit_decent_class
+ end
end
- end
- -- ::FOUND::
- local continue_only = false -- brrr
- if b > infinite_badness or pi == eject_penalty then
- if final_pass and par.minimum_demerits == awful_badness and r.next == par.active and prev_r == par.active then
- artificial_demerits = true -- set demerits zero, this break is forced
- node_r_stays_active = false
- elseif b > par.threshold then
- prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion)
- continue_only = true
- else
- node_r_stays_active = false
+ if do_last_line_fit and not found then
+ if not current then
+ -- g = 0
+ shortfall = 0
+ elseif shortfall > 0 then
+ g = cur_active_width.stretch
+ elseif shortfall < 0 then
+ g = cur_active_width.shrink
+ else
+ g = 0
+ end
end
- else
- prev_r = r
- if b > par.threshold then
- continue_only = true
+ -- ::FOUND::
+ local continue_only = false -- brrr
+ if b > infinite_badness or pi == eject_penalty then
+ if final_pass and par.minimum_demerits == awful_badness and r.next == par.active and prev_r == par.active then
+ artificial_demerits = true -- set demerits zero, this break is forced
+ node_r_stays_active = false
+ elseif b > par.threshold then
+ prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion)
+ continue_only = true
+ else
+ node_r_stays_active = false
+ end
else
- node_r_stays_active = true
- end
- end
- if not continue_only then
- local d = 0
- if not artificial_demerits then
- d = par.line_penalty + b
- if (d >= 0 and d or -d) >= 10000 then -- abs(d)
- d = 100000000
+ prev_r = r
+ if b > par.threshold then
+ continue_only = true
else
- d = d * d
+ node_r_stays_active = true
end
- if pi == 0 then
- -- nothing
- elseif pi > 0 then
- d = d + pi * pi
- elseif pi > eject_penalty then
- d = d - pi * pi
- end
- if break_type == hyphenated_code and r.id == hyphenated_code then
- if current then
- d = d + par.double_hyphen_demerits
+ end
+ if not continue_only then
+ local d = 0
+ if not artificial_demerits then
+ d = par.line_penalty + b
+ if (d >= 0 and d or -d) >= 10000 then -- abs(d)
+ d = 100000000
else
- d = d + par.final_hyphen_demerits
+ d = d * d
+ end
+ if pi == 0 then
+ -- nothing
+ elseif pi > 0 then
+ d = d + pi * pi
+ elseif pi > eject_penalty then
+ d = d - pi * pi
+ end
+ if break_type == hyphenated_code and r.id == hyphenated_code then
+ if current then
+ d = d + par.double_hyphen_demerits
+ else
+ d = d + par.final_hyphen_demerits
+ end
+ end
+ local delta = fit_class - r.subtype
+ if (delta >= 0 and delta or -delta) > 1 then -- abs(delta)
+ d = d + par.adj_demerits
end
end
- local delta = fit_class - r.subtype
- if (delta >= 0 and delta or -delta) > 1 then -- abs(delta)
- d = d + par.adj_demerits
+ if tracing_paragraphs then
+ diagnostics.feasible_break(par,current,r,b,pi,d,artificial_demerits)
end
- end
- if tracing_paragraphs then
- diagnostics.feasible_break(par,current,r,b,pi,d,artificial_demerits)
- end
- d = d + r.total_demerits -- this is the minimum total demerits from the beginning to current via r
- if d <= minimal_demerits[fit_class] then
- minimal_demerits[fit_class] = d
- best_place [fit_class] = r.break_node
- best_pl_line [fit_class] = line_number
- if do_last_line_fit then
- best_pl_short[fit_class] = shortfall
- best_pl_glue [fit_class] = g
- if trace_lastlinefit then
- report_parbuilders("storing last line fit short %a and glue %p in class %a",shortfall,g,fit_class)
+ d = d + r.total_demerits -- this is the minimum total demerits from the beginning to current via r
+ if d <= minimal_demerits[fit_class] then
+ minimal_demerits[fit_class] = d
+ best_place [fit_class] = r.break_node
+ best_pl_line [fit_class] = line_number
+ if do_last_line_fit then
+ best_pl_short[fit_class] = shortfall
+ best_pl_glue [fit_class] = g
+ if trace_lastlinefit then
+ report_parbuilders("storing last line fit short %a and glue %p in class %a",shortfall,g,fit_class)
+ end
+ end
+ if d < par.minimum_demerits then
+ par.minimum_demerits = d
end
end
- if d < par.minimum_demerits then
- par.minimum_demerits = d
+ if not node_r_stays_active then
+ prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion)
end
end
- if not node_r_stays_active then
- prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion)
- end
end
end
end
-end
-
--- we can call the normal one for simple box building in the otr so we need
--- frequent enabling/disabling
-local dcolor = { [0] = "red", "green", "blue", "magenta", "cyan", "gray" }
+ -- we can call the normal one for simple box building in the otr so we need
+ -- frequent enabling/disabling
-local temp_head = new_temp()
+ local temp_head = new_temp()
-function constructors.methods.basic(head,d)
- head = tonut(head)
-
- if trace_basic then
- report_parbuilders("starting at %a",head)
- end
+ function constructors.methods.basic(head,d)
+ if trace_basic then
+ report_parbuilders("starting at %a",head)
+ end
- local par = initialize_line_break(head,d)
+ local par = initialize_line_break(head,d)
- local checked_expansion = par.checked_expansion
- local active_width = par.active_width
- local disc_width = par.disc_width
- local background = par.background
- local tracing_paragraphs = par.tracing_paragraphs
+ local checked_expansion = par.checked_expansion
+ local active_width = par.active_width
+ local disc_width = par.disc_width
+ local background = par.background
+ local tracing_paragraphs = par.tracing_paragraphs
- local dirstack = new_dir_stack()
+ local dirstack = new_dir_stack()
- if tracing_paragraphs then
- diagnostics.start()
- if par.pretolerance >= 0 then
- diagnostics.current_pass(par,"firstpass")
+ if tracing_paragraphs then
+ diagnostics.start()
+ if par.pretolerance >= 0 then
+ diagnostics.current_pass(par,"firstpass")
+ end
end
- end
- while true do
- reset_meta(par)
- if par.threshold > infinite_badness then
- par.threshold = infinite_badness
- end
- par.active.next = {
- id = unhyphenated_code,
- subtype = fit_decent_class,
- next = par.active,
- break_node = nil,
- line_number = par.first_line + 1,
- total_demerits = 0,
- active_short = 0,
- active_glue = 0,
- }
- active_width.size = background.size
- active_width.stretch = background.stretch
- active_width.fi = background.fi
- active_width.fil = background.fil
- active_width.fill = background.fill
- active_width.filll = background.filll
- active_width.shrink = background.shrink
-
- if checked_expansion then
- active_width.adjust_stretch = 0
- active_width.adjust_shrink = 0
- end
+ while true do
+ reset_meta(par)
+ if par.threshold > infinite_badness then
+ par.threshold = infinite_badness
+ end
+ par.active.next = {
+ id = unhyphenated_code,
+ subtype = fit_decent_class,
+ next = par.active,
+ break_node = nil,
+ line_number = par.first_line + 1,
+ total_demerits = 0,
+ active_short = 0,
+ active_glue = 0,
+ }
+ active_width.size = background.size
+ active_width.stretch = background.stretch
+ active_width.fi = background.fi
+ active_width.fil = background.fil
+ active_width.fill = background.fill
+ active_width.filll = background.filll
+ active_width.shrink = background.shrink
- par.passive = nil -- = 0
- par.printed_node = temp_head -- only when tracing, shared
- par.pass_number = 0
--- par.auto_breaking = true
+ if checked_expansion then
+ active_width.adjust_stretch = 0
+ active_width.adjust_shrink = 0
+ end
- setnext(temp_head,head)
+ par.passive = nil -- = 0
+ par.printed_node = temp_head -- only when tracing, shared
+ par.pass_number = 0
+ -- par.auto_breaking = true
- local current = head
- local first_p = current
+ setnext(temp_head,head)
- local auto_breaking = true
+ local current = head
+ local first_p = current
- par.font_in_short_display = 0
+ local auto_breaking = true
- if current then
- local id = getid(current)
- if id == localpar_code then
- par.init_internal_left_box = getfield(current,"box_left")
- par.init_internal_left_box_width = getfield(current,"box_left_width")
- par.internal_pen_inter = getfield(current,"pen_inter")
- par.internal_pen_broken = getfield(current,"pen_broken")
- par.internal_left_box = par.init_internal_left_box
- par.internal_left_box_width = par.init_internal_left_box_width
- par.internal_right_box = getfield(current,"box_right")
- par.internal_right_box_width = getfield(current,"box_right_width")
+ par.font_in_short_display = 0
+
+ if current then
+ local id = getid(current)
+ if id == localpar_code then
+ par.init_internal_left_box = getfield(current,"box_left")
+ par.init_internal_left_box_width = getfield(current,"box_left_width")
+ par.internal_pen_inter = getfield(current,"pen_inter")
+ par.internal_pen_broken = getfield(current,"pen_broken")
+ par.internal_left_box = par.init_internal_left_box
+ par.internal_left_box_width = par.init_internal_left_box_width
+ par.internal_right_box = getfield(current,"box_right")
+ par.internal_right_box_width = getfield(current,"box_right_width")
+ end
end
- end
- -- all passes are combined in this loop so maybe we should split this into
- -- three function calls; we then also need to do the wrap_up elsewhere
+ -- all passes are combined in this loop so maybe we should split this into
+ -- three function calls; we then also need to do the wrap_up elsewhere
- -- split into normal and expansion loop
+ -- split into normal and expansion loop
- -- use an active local
+ -- use an active local
- local fontexp, lastfont -- we can pass fontexp to calculate width if needed
+ local fontexp, lastfont -- we can pass fontexp to calculate width if needed
- -- i flattened the inner loop over glyphs .. it looks nicer and the extra p_active ~= n_active
- -- test is fast enough (and try_break now returns the updated values); the kern helper has been
- -- inlined as it did a double check on id so in fact we had hardly any code to share
+ -- i flattened the inner loop over glyphs .. it looks nicer and the extra p_active ~= n_active
+ -- test is fast enough (and try_break now returns the updated values); the kern helper has been
+ -- inlined as it did a double check on id so in fact we had hardly any code to share
- local p_active = par.active
- local n_active = p_active and p_active.next
- local second_pass = par.second_pass
+ local p_active = par.active
+ local n_active = p_active and p_active.next
+ local second_pass = par.second_pass
- trialcount = 0
+ trialcount = 0
- while current and p_active ~= n_active do
- local char, id = isglyph(current)
- if char then
- local wd, ht, dp = getwhd(current)
- if is_rotated[par.line_break_dir] then
- active_width.size = active_width.size + ht + dp
- else
- active_width.size = active_width.size + wd
- end
- if checked_expansion then
- local currentfont = getfont(current)
- local data = checked_expansion[currentfont]
- if data then
- if currentfont ~= lastfont then
- fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer
- lastfont = currentfont
- end
- if fontexps then
- local expansion = fontexps[char]
- if expansion then
- active_width.adjust_stretch = active_width.adjust_stretch + expansion.glyphstretch
- active_width.adjust_shrink = active_width.adjust_shrink + expansion.glyphshrink
+ while current and p_active ~= n_active do
+ local char, id = isglyph(current)
+ if char then
+ local wd, ht, dp = getwhd(current)
+ if is_rotated(par.line_break_dir) then
+ active_width.size = active_width.size + ht + dp
+ else
+ active_width.size = active_width.size + wd
+ end
+ if checked_expansion then
+ local font = id -- == font
+ local data = checked_expansion[font]
+ if data then
+ if font ~= lastfont then
+ fontexps = checked_expansion[font] -- a bit redundant for the par line packer
+ lastfont = currentfont
+ end
+ if fontexps then
+ local expansion = fontexps[char]
+ if expansion then
+ active_width.adjust_stretch = active_width.adjust_stretch + expansion.glyphstretch
+ active_width.adjust_shrink = active_width.adjust_shrink + expansion.glyphshrink
+ end
end
end
end
- end
- elseif id == hlist_code or id == vlist_code then
- local wd, ht, dp = getwhd(current)
- if is_parallel[getdir(current)][par.line_break_dir] then
- active_width.size = active_width.size + wd
- else
- active_width.size = active_width.size + ht + dp
- end
- elseif id == glue_code then
--- if par.auto_breaking then
- if auto_breaking then
- local prev_p = getprev(current)
- if prev_p and prev_p ~= temp_head then
- local id = getid(prev_p)
- -- we need to check this with the latest patches to the tex kernel
- if (id == glyph_code) or (id < math_code) then
- p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
- elseif id == kern_code then
- local s = getsubtype(prev_p)
- if s ~= userkern_code and s ~= italickern_code then
+ elseif id == hlist_code or id == vlist_code then
+ local wd, ht, dp = getwhd(current)
+ if textdir_parallel(getdirection(current),par.line_break_dir) then
+ active_width.size = active_width.size + wd
+ else
+ active_width.size = active_width.size + ht + dp
+ end
+ elseif id == glue_code then
+ -- if par.auto_breaking then
+ if auto_breaking then
+ local prev_p = getprev(current)
+ if prev_p and prev_p ~= temp_head then
+ local id = getid(prev_p)
+ -- we need to check this with the latest patches to the tex kernel
+ if (id == glyph_code) or (id < math_code) then
p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ elseif id == kern_code then
+ local s = getsubtype(prev_p)
+ if s ~= userkern_code and s ~= italickern_code then
+ p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ end
end
end
end
- end
- check_shrinkage(par,current)
- local width, stretch, shrink, stretch_order = getglue(current)
- local order = stretch_orders[stretch_order]
- active_width.size = active_width.size + width
- active_width[order] = active_width[order] + stretch
- active_width.shrink = active_width.shrink + shrink
- elseif id == disc_code then
- local subtype = getsubtype(current)
- if subtype ~= second_disc_code then
- local line_break_dir = par.line_break_dir
- if second_pass or subtype <= automatic_disc_code then
- local actual_pen = subtype == automatic_disc_code and par.ex_hyphen_penalty or par.hyphen_penalty
- -- 0.81 :
- -- local actual_pen = getpenalty(current)
- --
- local pre, post, replace = getdisc(current)
- if not pre then -- trivial pre-break
- disc_width.size = 0
- if checked_expansion then
- disc_width.adjust_stretch = 0
- disc_width.adjust_shrink = 0
- end
- p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion)
- else
- local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre)
- disc_width.size = size
- active_width.size = active_width.size + size
- if checked_expansion then
- disc_width.adjust_stretch = adjust_stretch
- disc_width.adjust_shrink = adjust_shrink
- active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch
- active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink
+ check_shrinkage(par,current)
+ local width, stretch, shrink, stretch_order = getglue(current)
+ local order = fillcodes[stretch_order]
+ active_width.size = active_width.size + width
+ active_width[order] = active_width[order] + stretch
+ active_width.shrink = active_width.shrink + shrink
+ elseif id == disc_code then
+ local subtype = getsubtype(current)
+ if subtype ~= seconddisc_code then
+ local line_break_dir = par.line_break_dir
+ if second_pass or subtype <= automaticdisc_code then
+ local actual_pen = subtype == automaticdisc_code and par.ex_hyphen_penalty or par.hyphen_penalty
+ -- 0.81 :
+ -- local actual_pen = getpenalty(current)
+ --
+ local pre, post, replace = getdisc(current)
+ if not pre then -- trivial pre-break
+ disc_width.size = 0
+ if checked_expansion then
+ disc_width.adjust_stretch = 0
+ disc_width.adjust_shrink = 0
+ end
+ p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion)
else
- -- disc_width.adjust_stretch = 0
- -- disc_width.adjust_shrink = 0
- end
- p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion)
- if subtype == first_disc_code then
- local cur_p_next = getnext(current)
- if getid(cur_p_next) ~= disc_code or getsubtype(cur_p_next) ~= second_disc_code then
- report_parbuilders("unsupported disc at location %a",1)
+ local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre)
+ disc_width.size = size
+ active_width.size = active_width.size + size
+ if checked_expansion then
+ disc_width.adjust_stretch = adjust_stretch
+ disc_width.adjust_shrink = adjust_shrink
+ active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch
+ active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink
else
- local pre = getfield(cur_p_next,"pre")
- if pre then
- local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre)
- disc_width.size = disc_width.size + size
- if checked_expansion then
- disc_width.adjust_stretch = disc_width.adjust_stretch + adjust_stretch
- disc_width.adjust_shrink = disc_width.adjust_shrink + adjust_shrink
- end
- p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, cur_p_next, checked_expansion)
- --
- -- I will look into this some day ... comment in linebreak.w says that this fails,
- -- maybe this is what Taco means with his comment in the luatex manual.
- --
- -- do_one_seven_eight(sub_disc_width_from_active_width);
- -- do_one_seven_eight(reset_disc_width);
- -- s = vlink_no_break(vlink(current));
- -- add_to_widths(s, line_break_dir, adjust_spacing,disc_width);
- -- ext_try_break(...,first_p,vlink(current));
- --
+ -- disc_width.adjust_stretch = 0
+ -- disc_width.adjust_shrink = 0
+ end
+ p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion)
+ if subtype == firstdisc_code then
+ local cur_p_next = getnext(current)
+ if getid(cur_p_next) ~= disc_code or getsubtype(cur_p_next) ~= seconddisc_code then
+ report_parbuilders("unsupported disc at location %a",1)
else
- report_parbuilders("unsupported disc at location %a",2)
+ local pre = getfield(cur_p_next,"pre")
+ if pre then
+ local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre)
+ disc_width.size = disc_width.size + size
+ if checked_expansion then
+ disc_width.adjust_stretch = disc_width.adjust_stretch + adjust_stretch
+ disc_width.adjust_shrink = disc_width.adjust_shrink + adjust_shrink
+ end
+ p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, cur_p_next, checked_expansion)
+ --
+ -- I will look into this some day ... comment in linebreak.w says that this fails,
+ -- maybe this is what Taco means with his comment in the luatex manual.
+ --
+ -- do_one_seven_eight(sub_disc_width_from_active_width);
+ -- do_one_seven_eight(reset_disc_width);
+ -- s = vlink_no_break(vlink(current));
+ -- add_to_widths(s, line_break_dir, adjust_spacing,disc_width);
+ -- ext_try_break(...,first_p,vlink(current));
+ --
+ else
+ report_parbuilders("unsupported disc at location %a",2)
+ end
end
end
+ -- beware, we cannot restore to a saved value as the try_break adapts active_width
+ active_width.size = active_width.size - disc_width.size
+ if checked_expansion then
+ active_width.adjust_stretch = active_width.adjust_stretch - disc_width.adjust_stretch
+ active_width.adjust_shrink = active_width.adjust_shrink - disc_width.adjust_shrink
+ end
end
- -- beware, we cannot restore to a saved value as the try_break adapts active_width
- active_width.size = active_width.size - disc_width.size
+ end
+ if replace then
+ local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace)
+ active_width.size = active_width.size + size
if checked_expansion then
- active_width.adjust_stretch = active_width.adjust_stretch - disc_width.adjust_stretch
- active_width.adjust_shrink = active_width.adjust_shrink - disc_width.adjust_shrink
+ active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch
+ active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink
end
end
end
- if replace then
- local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace)
- active_width.size = active_width.size + size
- if checked_expansion then
- active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch
- active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink
+ elseif id == kern_code then
+ local s = getsubtype(current)
+ if s == userkern_code or s == italickern_code then
+ local v = getnext(current)
+ -- if par.auto_breaking and getid(v) == glue_code then
+ if auto_breaking and getid(v) == glue_code then
+ p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ end
+ local active_width = par.active_width
+ active_width.size = active_width.size + getkern(current)
+ else
+ local kern = getkern(current)
+ if kern ~= 0 then
+ active_width.size = active_width.size + kern
+ if checked_expansion and expand_kerns and getsubtype(current) == fontkern_code then
+ local stretch, shrink = kern_stretch_shrink(current,kern)
+ if expand_kerns == "stretch" then
+ active_width.adjust_stretch = active_width.adjust_stretch + stretch
+ elseif expand_kerns == "shrink" then
+ active_width.adjust_shrink = active_width.adjust_shrink + shrink
+ else
+ active_width.adjust_stretch = active_width.adjust_stretch + stretch
+ active_width.adjust_shrink = active_width.adjust_shrink + shrink
+ end
+ end
end
end
- end
- elseif id == kern_code then
- local s = getsubtype(current)
- if s == userkern_code or s == italickern_code then
+ elseif id == math_code then
+ -- par.auto_breaking = getsubtype(current) == endmath_code
+ auto_breaking = getsubtype(current) == endmath_code
local v = getnext(current)
- -- if par.auto_breaking and getid(v) == glue_code then
+ -- if par.auto_breaking and getid(v) == glue_code then
if auto_breaking and getid(v) == glue_code then
p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
end
local active_width = par.active_width
- active_width.size = active_width.size + getkern(current)
- else
- local kern = getkern(current)
- if kern ~= 0 then
- active_width.size = active_width.size + kern
- if checked_expansion and expand_kerns and getsubtype(current) == fontkern_code then
- local stretch, shrink = kern_stretch_shrink(current,kern)
- if expand_kerns == "stretch" then
- active_width.adjust_stretch = active_width.adjust_stretch + stretch
- elseif expand_kerns == "shrink" then
- active_width.adjust_shrink = active_width.adjust_shrink + shrink
- else
- active_width.adjust_stretch = active_width.adjust_stretch + stretch
- active_width.adjust_shrink = active_width.adjust_shrink + shrink
- end
- end
+ active_width.size = active_width.size + getkern(current) -- surround
+ -- new in luatex
+ + getwidth(current)
+ elseif id == rule_code then
+ active_width.size = active_width.size + getwidth(current)
+ elseif id == penalty_code then
+ p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion)
+ elseif id == dir_code then
+ par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir
+ elseif id == localpar_code then
+ par.internal_pen_inter = getfield(current,"pen_inter")
+ par.internal_pen_broken = getfield(current,"pen_broken")
+ par.internal_left_box = getfield(current,"box_left")
+ par.internal_left_box_width = getfield(current,"box_left_width")
+ par.internal_right_box = getfield(current,"box_right")
+ par.internal_right_box_width = getfield(current,"box_right_width")
+ elseif trace_unsupported then
+ if id == mark_code or id == ins_code or id == adjust_code then
+ -- skip
+ else
+ report_parbuilders("node of type %a found in paragraph",type(id))
end
end
- elseif id == math_code then
--- par.auto_breaking = getsubtype(current) == endmath_code
- auto_breaking = getsubtype(current) == endmath_code
- local v = getnext(current)
--- if par.auto_breaking and getid(v) == glue_code then
- if auto_breaking and getid(v) == glue_code then
- p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
- end
- local active_width = par.active_width
- active_width.size = active_width.size + getkern(current) -- surround
- -- new in luatex
- + getwidth(current)
- elseif id == rule_code then
- active_width.size = active_width.size + getwidth(current)
- elseif id == penalty_code then
- p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion)
- elseif id == dir_code then
- par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir
- elseif id == localpar_code then
- par.internal_pen_inter = getfield(current,"pen_inter")
- par.internal_pen_broken = getfield(current,"pen_broken")
- par.internal_left_box = getfield(current,"box_left")
- par.internal_left_box_width = getfield(current,"box_left_width")
- par.internal_right_box = getfield(current,"box_right")
- par.internal_right_box_width = getfield(current,"box_right_width")
- elseif trace_unsupported then
- if id == mark_code or id == ins_code or id == adjust_code then
- -- skip
- else
- report_parbuilders("node of type %a found in paragraph",type(id))
- end
+ current = getnext(current)
end
- current = getnext(current)
- end
- if not current then
- local p_active, n_active = try_break(eject_penalty, hyphenated_code, par, first_p, current, checked_expansion)
- if n_active ~= p_active then
- local r = n_active
- par.fewest_demerits = awful_badness
- repeat -- use local d
- if r.id ~= delta_code and r.total_demerits < par.fewest_demerits then
- par.fewest_demerits = r.total_demerits
- par.best_bet = r
- end
- r = r.next
- until r == p_active
- par.best_line = par.best_bet.line_number
- local asked_looseness = par.looseness
- if asked_looseness == 0 then
- return tonode(wrap_up(par))
- end
- local r = n_active
- local actual_looseness = 0
- -- minimize assignments to par but happens seldom
- repeat
- if r.id ~= delta_code then
- local line_diff = r.line_number - par.best_line
- par.line_diff = line_diff
- if (line_diff < actual_looseness and asked_looseness <= line_diff) or
- (line_diff > actual_looseness and asked_looseness >= line_diff) then
- par.best_bet = r
- actual_looseness = line_diff
+ if not current then
+ local p_active, n_active = try_break(eject_penalty, hyphenated_code, par, first_p, current, checked_expansion)
+ if n_active ~= p_active then
+ local r = n_active
+ par.fewest_demerits = awful_badness
+ repeat -- use local d
+ if r.id ~= delta_code and r.total_demerits < par.fewest_demerits then
par.fewest_demerits = r.total_demerits
- elseif line_diff == actual_looseness and r.total_demerits < par.fewest_demerits then
par.best_bet = r
- par.fewest_demerits = r.total_demerits
end
+ r = r.next
+ until r == p_active
+ par.best_line = par.best_bet.line_number
+ local asked_looseness = par.looseness
+ if asked_looseness == 0 then
+ return wrap_up(par)
+ end
+ local r = n_active
+ local actual_looseness = 0
+ -- minimize assignments to par but happens seldom
+ repeat
+ if r.id ~= delta_code then
+ local line_diff = r.line_number - par.best_line
+ par.line_diff = line_diff
+ if (line_diff < actual_looseness and asked_looseness <= line_diff) or
+ (line_diff > actual_looseness and asked_looseness >= line_diff) then
+ par.best_bet = r
+ actual_looseness = line_diff
+ par.fewest_demerits = r.total_demerits
+ elseif line_diff == actual_looseness and r.total_demerits < par.fewest_demerits then
+ par.best_bet = r
+ par.fewest_demerits = r.total_demerits
+ end
+ end
+ r = r.next
+ until r == p_active
+ par.best_line = par.best_bet.line_number
+ if actual_looseness == asked_looseness or par.final_pass then
+ return wrap_up(par)
end
- r = r.next
- until r == p_active
- par.best_line = par.best_bet.line_number
- if actual_looseness == asked_looseness or par.final_pass then
- return tonode(wrap_up(par))
end
end
- end
- reset_meta(par) -- clean up the memory by removing the break nodes
- if not second_pass then
- if tracing_paragraphs then
- diagnostics.current_pass(par,"secondpass")
- end
- par.threshold = par.tolerance
- par.second_pass = true
- par.final_pass = par.emergency_stretch <= 0
- else
- if tracing_paragraphs then
- diagnostics.current_pass(par,"emergencypass")
+ reset_meta(par) -- clean up the memory by removing the break nodes
+ if not second_pass then
+ if tracing_paragraphs then
+ diagnostics.current_pass(par,"secondpass")
+ end
+ par.threshold = par.tolerance
+ par.second_pass = true
+ par.final_pass = par.emergency_stretch <= 0
+ else
+ if tracing_paragraphs then
+ diagnostics.current_pass(par,"emergencypass")
+ end
+ par.background.stretch = par.background.stretch + par.emergency_stretch
+ par.final_pass = true
end
- par.background.stretch = par.background.stretch + par.emergency_stretch
- par.final_pass = true
end
+ return wrap_up(par)
end
- return tonode(wrap_up(par))
+
end
-- standard tex logging .. will be adapted ..
@@ -2531,16 +2572,19 @@ do
while a do
local char, id = isglyph(a)
if char then
- local font = getfont(a)
- if font ~= font_in_short_display then
- write(target,tex.fontidentifier(font) .. ' ')
- font_in_short_display = font
+ -- id == font
+ if id ~= font_in_short_display then
+ write(target,tex.fontidentifier(id) .. ' ')
+ font_in_short_display = id
end
- -- todo: instead of components the split tounicode string
- if getsubtype(a) == ligature_code then
- font_in_short_display = short_display(target,getcomponents(a),font_in_short_display)
+ local u = chardata[id][char]
+ local u = u.unicode or char
+ if type(u) == "table" then
+ for i=1,#u do
+ write(target,utfchar(u[i]))
+ end
else
- write(target,utfchar(char))
+ write(target,utfchar(u))
end
elseif id == disc_code then
local pre, post, replace = getdisc(a)
@@ -2713,55 +2757,6 @@ do
local setnodecolor = nodes.tracers.colors.set
- local function glyph_width_height_depth(curdir,pdir,p)
- local wd, ht, dp = getwhd(p)
- if is_rotated[curdir] then
- if is_parallel[curdir][pdir] then
- local half = (ht + dp) / 2
- return wd, half, half
- else
- local half = wd / 2
- return ht + dp, half, half
- end
- elseif is_rotated[pdir] then
- if is_parallel[curdir][pdir] then
- local half = (ht + dp) / 2
- return wd, half, half
- else
- return ht + dp, wd, 0 -- weird
- end
- else
- if glyphdir_is_equal[curdir][pdir] then
- return wd, ht, dp
- elseif is_opposite[curdir][pdir] then
- return wd, dp, ht
- else -- can this happen?
- return ht + dp, wd, 0
- end
- end
- end
-
- local function pack_width_height_depth(curdir,pdir,p)
- local wd, ht, dp = getwhd(p)
- if is_rotated[curdir] then
- if is_parallel[curdir][pdir] then
- local half = (ht + dp) / 2
- return wd, half, half
- else -- can this happen?
- local half = wd / 2
- return ht + dp, half, half
- end
- else
- if pardir_is_equal[curdir][pdir] then
- return wd, ht, dp
- elseif is_opposite[curdir][pdir] then
- return wd, dp, ht
- else -- weird dimensions, can this happen?
- return ht + dp, wd, 0
- end
- end
- end
-
-- local function xpack(head,width,method,direction,analysis)
--
-- -- inspect(analysis)
@@ -2776,7 +2771,7 @@ do
-- local hlist = new_hlist()
--
-- setlist(hlist,head)
- -- setdir(hlist,direction or tex.textdir)
+ -- setdirection(hlist,direction or tex.textdirection)
-- setwhd(hlist,width,height,depth)
--
-- if delta == 0 then
@@ -2889,7 +2884,7 @@ do
local hlist = new_hlist()
- setdir(hlist,direction)
+ setdirection(hlist,direction)
if head == nil then
setwidth(hlist,width)
@@ -2942,10 +2937,10 @@ do
local char, id = isglyph(current)
if char then
if cal_expand_ratio then
- local currentfont = getfont(current)
- if currentfont ~= lastfont then
- fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer
- lastfont = currentfont
+ local font = id -- == font
+ if font ~= lastfont then
+ fontexps = checked_expansion[font] -- a bit redundant for the par line packer
+ lastfont = font
end
if fontexps then
local expansion = fontexps[char]
@@ -2958,7 +2953,7 @@ do
end
end
-- use inline
- local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ?
+ local wd, ht, dp = getwhd(current)
natural = natural + wd
if ht > height then
height = ht
@@ -2984,7 +2979,7 @@ do
end
elseif id == disc_code then
local subtype = getsubtype(current)
- if subtype ~= second_disc_code then
+ if subtype ~= seconddisc_code then
-- todo : local stretch, shrink = char_stretch_shrink(s)
local replace = getfield(current,"replace")
if replace then
@@ -3008,7 +3003,7 @@ do
end
elseif id == hlist_code or id == vlist_code then
local sh = getshift(current)
- local wd, ht, dp = pack_width_height_depth(hpack_dir,getdir(current) or hpack_dir,current) -- added: or pack_dir
+ local wd, ht, dp = getwhd(current)
local hs, ds = ht - sh, dp + sh
natural = natural + wd
if hs > height then
@@ -3114,14 +3109,13 @@ do
local fontexps, lastfont
for i=1,expansion_index do
- local g = expansion_stack[i]
- local e = 0
- local char = isglyph(g)
+ local g = expansion_stack[i]
+ local e = 0
+ local char, font = isglyph(g)
if char then
- local currentfont = getfont(g)
- if currentfont ~= lastfont then
- fontexps = expansions[currentfont]
- lastfont = currentfont
+ if font ~= lastfont then
+ fontexps = expansions[font]
+ lastfont = font
end
local data = fontexps[char]
if trace_expansion then
@@ -3133,7 +3127,7 @@ do
local stretch, shrink = kern_stretch_shrink(g,kern)
e = font_expand_ratio * stretch / 1000
end
- setfield(g,"expansion_factor",e)
+ setexpansion(g,e)
end
end
local tso = total_stretch[order]
@@ -3171,14 +3165,13 @@ do
local fontexps, lastfont
for i=1,expansion_index do
- local g = expansion_stack[i]
- local e = 0
- local char = isglyph(g)
+ local g = expansion_stack[i]
+ local e = 0
+ local char, font = isglyph(g)
if char then
- local currentfont = getfont(g)
- if currentfont ~= lastfont then
- fontexps = expansions[currentfont]
- lastfont = currentfont
+ if font ~= lastfont then
+ fontexps = expansions[font]
+ lastfont = font
end
local data = fontexps[char]
if trace_expansion then
@@ -3190,7 +3183,7 @@ do
local stretch, shrink = kern_stretch_shrink(g,kern)
e = font_expand_ratio * shrink / 1000
end
- setfield(g,"expansion_factor",e)
+ setexpansion(g,e)
end
end
local tso = total_shrink[order]
@@ -3214,7 +3207,7 @@ do
local overfullrule = tex.overfullrule
if fuzz > hfuzz and overfullrule > 0 then
-- weird, is always called and no rules shows up
- setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdir(hlist))) -- todo: find_tail
+ setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdirection(hlist))) -- todo: find_tail
end
diagnostics.overfull_hbox(hlist,line,-delta)
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-met.lua b/Master/texmf-dist/tex/context/base/mkiv/node-met.lua
index 12a9256bc66..f5db4babdcd 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-met.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-met.lua
@@ -68,65 +68,70 @@ end
nodes = nodes or { }
local nodes = nodes
-local nodecodes = nodes.nodecodes
-
-nodes.tostring = node.tostring or tostring
-nodes.copy = node.copy
-nodes.copy_node = node.copy
-nodes.copy_list = node.copy_list
-nodes.delete = node.delete
-nodes.dimensions = node.dimensions
-nodes.rangedimensions = node.rangedimensions
-nodes.end_of_math = node.end_of_math
-nodes.flush = node.flush_node
-nodes.flush_node = node.flush_node
-nodes.flush_list = node.flush_list
-nodes.free = node.free
-nodes.insert_after = node.insert_after
-nodes.insert_before = node.insert_before
-nodes.hpack = node.hpack
-nodes.new = node.new
-nodes.tail = node.tail
-nodes.traverse = node.traverse
-nodes.traverse_id = node.traverse_id
-nodes.traverse_char = node.traverse_char
-nodes.slide = node.slide
-nodes.vpack = node.vpack
-nodes.fields = node.fields
-nodes.is_node = node.is_node
-nodes.setglue = node.setglue
-
-nodes.first_glyph = node.first_glyph
-nodes.has_glyph = node.has_glyph or node.first_glyph
-
-nodes.current_attr = node.current_attr
-nodes.has_field = node.has_field
-nodes.last_node = node.last_node
-nodes.usedlist = node.usedlist
-nodes.protrusion_skippable = node.protrusion_skippable
-nodes.check_discretionaries = node.check_discretionaries
-nodes.write = node.write
-
-nodes.count = node.count
-nodes.length = node.length
-
-nodes.has_attribute = node.has_attribute
-nodes.set_attribute = node.set_attribute
-nodes.find_attribute = node.find_attribute
-nodes.unset_attribute = node.unset_attribute
-
-nodes.protect_glyph = node.protect_glyph
-nodes.protect_glyphs = node.protect_glyphs
-nodes.unprotect_glyph = node.unprotect_glyph
-nodes.unprotect_glyphs = node.unprotect_glyphs
-nodes.kerning = node.kerning
-nodes.ligaturing = node.ligaturing
-nodes.mlist_to_hlist = node.mlist_to_hlist
-
-nodes.effective_glue = node.effective_glue
-nodes.getglue = node.getglue
-nodes.setglue = node.setglue
-nodes.is_zero_glue = node.is_zero_glue
+local nodecodes = nodes.nodecodes
+
+nodes.tostring = node.tostring or tostring
+nodes.copy = node.copy
+nodes.copy_node = node.copy
+nodes.copy_list = node.copy_list
+nodes.delete = node.delete
+nodes.dimensions = node.dimensions
+nodes.rangedimensions = node.rangedimensions
+nodes.end_of_math = node.end_of_math
+nodes.flush = node.flush_node
+nodes.flush_node = node.flush_node
+nodes.flush_list = node.flush_list
+nodes.free = node.free
+nodes.insert_after = node.insert_after
+nodes.insert_before = node.insert_before
+nodes.hpack = node.hpack
+nodes.new = node.new
+nodes.tail = node.tail
+nodes.traverse = node.traverse
+nodes.traverse_id = node.traverse_id
+nodes.traverse_char = node.traverse_char
+nodes.traverse_glyph = node.traverse_glyph
+nodes.traverse_list = node.traverse_list
+nodes.slide = node.slide
+nodes.vpack = node.vpack
+nodes.fields = node.fields
+nodes.is_node = node.is_node
+nodes.setglue = node.setglue
+nodes.uses_font = node.uses_font
+
+nodes.first_glyph = node.first_glyph
+nodes.has_glyph = node.has_glyph or node.first_glyph
+
+nodes.current_attr = node.current_attr
+nodes.has_field = node.has_field
+nodes.last_node = node.last_node
+nodes.usedlist = node.usedlist
+nodes.protrusion_skippable = node.protrusion_skippable
+nodes.check_discretionaries = node.check_discretionaries
+nodes.write = node.write
+nodes.flatten_discretionaries = node.flatten_discretionaries
+
+nodes.count = node.count
+nodes.length = node.length
+
+nodes.has_attribute = node.has_attribute
+nodes.set_attribute = node.set_attribute
+nodes.find_attribute = node.find_attribute
+nodes.unset_attribute = node.unset_attribute
+
+nodes.protect_glyph = node.protect_glyph
+nodes.protect_glyphs = node.protect_glyphs
+nodes.unprotect_glyph = node.unprotect_glyph
+nodes.unprotect_glyphs = node.unprotect_glyphs
+nodes.kerning = node.kerning
+nodes.ligaturing = node.ligaturing
+nodes.hyphenating = node.hyphenating
+nodes.mlist_to_hlist = node.mlist_to_hlist
+
+nodes.effective_glue = node.effective_glue
+nodes.getglue = node.getglue
+nodes.setglue = node.setglue
+nodes.is_zero_glue = node.is_zero_glue
nodes.tonode = function(n) return n end
nodes.tonut = function(n) return n end
@@ -163,7 +168,7 @@ local n_setlink = node.setlink or -- always
-- not that fast but not used often anyway
local h = nil
for i=1,select("#",...) do
- local n = (select(i,...))
+ local n = select(i,...)
if not n then
-- go on
elseif h then
@@ -621,7 +626,7 @@ local messyhack = table.tohash { -- temporary solution
nodecodes.action,
}
-table.setmetatableindex(keys,function(t,k)
+setmetatableindex(keys,function(t,k)
local v = (k == "attributelist" or k == nodecodes.attributelist) and { } or getfields(k)
if messyhack[k] then
for i=1,#v do
@@ -638,7 +643,7 @@ table.setmetatableindex(keys,function(t,k)
return v
end)
-table.setmetatableindex(whatsitkeys,function(t,k)
+setmetatableindex(whatsitkeys,function(t,k)
local v = getfields(whatsit_code,k)
if v[ 0] then v[#v+1] = "next" v[ 0] = nil end
if v[-1] then v[#v+1] = "prev" v[-1] = nil end
@@ -659,46 +664,3 @@ end
nodes.keys = keys -- [id][subtype]
nodes.fields = nodefields -- (n)
-
--- for the moment (pre 6380)
-
-if not nodes.unprotect_glyph then
-
- local protect_glyph = nodes.protect_glyph
- local protect_glyphs = nodes.protect_glyphs
- local unprotect_glyph = nodes.unprotect_glyph
- local unprotect_glyphs = nodes.unprotect_glyphs
-
- local getnext = nodes.getnext
- local setnext = nodes.setnext
-
- function nodes.protectglyphs(first,last)
- if first == last then
- return protect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = protect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return protect_glyphs(first)
- end
- end
-
- function nodes.unprotectglyphs(first,last)
- if first == last then
- return unprotect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = unprotect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return unprotect_glyphs(first)
- end
- end
-
-end
-
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-mig.lua b/Master/texmf-dist/tex/context/base/mkiv/node-mig.lua
index b3820a7d86c..32b09a1869c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-mig.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-mig.lua
@@ -89,12 +89,11 @@ local function locate(head,first,last,ni,nm)
end
function nodes.handlers.migrate(head,where)
- local done = false
if head then
if trace_migrations then
report_nodes("migration sweep %a",where)
end
- local current = tonut(head)
+ local current = head
while current do
local id = getid(current)
-- inserts_too is a temp hack, we should only do them when it concerns
@@ -124,13 +123,12 @@ function nodes.handlers.migrate(head,where)
setlink(last,n)
end
setlink(current,first)
- done = true
current = last
end
end
current = getnext(next)
end
- return head, done
+ return head
end
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua b/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua
index 3e9a08b4804..6a38cca67a0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua
@@ -96,6 +96,7 @@ local fastcopy = table.fastcopy
local nodecodes = nodes.nodecodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
local nuts = nodes.nuts or { }
nodes.nuts = nuts
@@ -126,11 +127,11 @@ nodes.tonut = tonut
-- function nuts.reportattr()
-- inspect(hash)
-- end
---
+
-- local function track(name)
-- local n = 0
--- local f = nuts[name]
--- function nuts[name](...)
+-- local f = direct[name]
+-- direct[name] = function(...)
-- n = n + 1
-- if n % 1000 == 0 then
-- print(name,n)
@@ -138,112 +139,81 @@ nodes.tonut = tonut
-- return f(...)
-- end
-- end
---
-- track("getfield")
-- helpers
-if not direct.getfam then -- LUATEXVERSION < 1.070
-
- local getfield = direct.getfield
- local setfield = direct.setfield
-
- direct.getfam = function(n) return getfield(n,"small_fam") end
- direct.setfam = function(n,f) setfield(n,"small_fam",f) end
-
-end
-
-if not direct.getdirection then
-
- local getdir = direct.getdir
- local setdir = direct.setdir
-
- direct.getdirection = function(n)
- local d = getdir(n)
- if d == "TLT" then return 0 end
- if d == "+TLT" then return 0, false end
- if d == "-TLT" then return 0, true end
- if d == "TRT" then return 1 end
- if d == "+TRT" then return 1, false end
- if d == "-TRT" then return 1, true end
- if d == "LTL" then return 2 end
- if d == "+LTL" then return 2, false end
- if d == "-LTL" then return 2, true end
- if d == "RTT" then return 3 end
- if d == "+RTT" then return 3, false end
- if d == "-RTT" then return 3, true end
- end
-
- direct.setdirection = function(n,d,c)
- if d == 0 then if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end
- elseif d == 1 then if c == true then setdir(n,"-TRT") elseif c == false then setdir(n,"+TRT") else setdir(n,"TRT") end
- elseif d == 2 then if c == true then setdir(n,"-LTL") elseif c == false then setdir(n,"+LTL") else setdir(n,"LTL") end
- elseif d == 3 then if c == true then setdir(n,"-RTT") elseif c == false then setdir(n,"+RTT") else setdir(n,"RTT") end
- else if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end end
- end
-
-end
-
-local nuts = nodes.nuts
-
-nuts.tostring = direct.tostring
-nuts.copy = direct.copy
-nuts.copy_node = direct.copy
-nuts.copy_list = direct.copy_list
-nuts.delete = direct.delete
-nuts.dimensions = direct.dimensions
-nuts.rangedimensions = direct.rangedimensions
-nuts.end_of_math = direct.end_of_math
-nuts.flush = direct.flush_node
-nuts.flush_node = direct.flush_node
-nuts.flush_list = direct.flush_list
-nuts.free = direct.free
-nuts.insert_after = direct.insert_after
-nuts.insert_before = direct.insert_before
-nuts.hpack = direct.hpack
-nuts.new = direct.new
-nuts.tail = direct.tail
-nuts.traverse = direct.traverse
-nuts.traverse_id = direct.traverse_id
-nuts.traverse_char = direct.traverse_char
-nuts.slide = direct.slide
-nuts.writable_spec = direct.writable_spec
-nuts.vpack = direct.vpack
-nuts.is_node = direct.is_node
-nuts.is_direct = direct.is_direct
-nuts.is_nut = direct.is_direct
-nuts.first_glyph = direct.first_glyph
-nuts.has_glyph = direct.has_glyph or direct.first_glyph
-nuts.count = direct.count
-nuts.length = direct.length
-nuts.find_attribute = direct.find_attribute
-nuts.unset_attribute = direct.unset_attribute
-
-nuts.current_attr = direct.current_attr
-nuts.has_field = direct.has_field
-nuts.last_node = direct.last_node
-nuts.usedlist = direct.usedlist
-nuts.protrusion_skippable = direct.protrusion_skippable
-nuts.check_discretionaries = direct.check_discretionaries
-nuts.write = direct.write
-
-nuts.has_attribute = direct.has_attribute
-nuts.set_attribute = direct.set_attribute
-nuts.unset_attribute = direct.unset_attribute
-
-nuts.protect_glyph = direct.protect_glyph
-nuts.protect_glyphs = direct.protect_glyphs
-nuts.unprotect_glyph = direct.unprotect_glyph
-nuts.unprotect_glyphs = direct.unprotect_glyphs
-nuts.ligaturing = direct.ligaturing
-nuts.kerning = direct.kerning
-
-if not direct.mlist_to_hlist then -- needed
+local nuts = nodes.nuts
+
+nuts.check_discretionaries = direct.check_discretionaries
+nuts.copy = direct.copy
+nuts.copy_list = direct.copy_list
+nuts.copy_node = direct.copy
+nuts.count = direct.count
+nuts.current_attr = direct.current_attr
+nuts.delete = direct.delete
+nuts.dimensions = direct.dimensions
+nuts.end_of_math = direct.end_of_math
+nuts.find_attribute = direct.find_attribute
+nuts.first_glyph = direct.first_glyph
+nuts.flatten_discretionaries = direct.flatten_discretionaries
+nuts.flush = direct.flush_node
+nuts.flush_list = direct.flush_list
+nuts.flush_node = direct.flush_node
+nuts.free = direct.free
+nuts.get_synctex_fields = direct.get_synctex_fields
+nuts.has_attribute = direct.has_attribute
+nuts.has_field = direct.has_field
+nuts.has_glyph = direct.has_glyph or direct.first_glyph
+nuts.hpack = direct.hpack
+nuts.insert_after = direct.insert_after
+nuts.insert_before = direct.insert_before
+nuts.is_direct = direct.is_direct
+nuts.is_node = direct.is_node
+nuts.is_nut = direct.is_direct
+nuts.kerning = direct.kerning
+nuts.hyphenating = direct.hyphenating
+nuts.last_node = direct.last_node
+nuts.length = direct.length
+nuts.ligaturing = direct.ligaturing
+nuts.new = direct.new
+nuts.protect_glyph = direct.protect_glyph
+nuts.protect_glyphs = direct.protect_glyphs
+nuts.flush_components = direct.flush_components
+nuts.protrusion_skippable = direct.protrusion_skippable
+nuts.rangedimensions = direct.rangedimensions
+nuts.set_attribute = direct.set_attribute
+nuts.set_synctex_fields = direct.set_synctex_fields
+nuts.slide = direct.slide
+nuts.tail = direct.tail
+nuts.tostring = direct.tostring
+nuts.traverse = direct.traverse
+nuts.traverse_char = direct.traverse_char
+nuts.traverse_glyph = direct.traverse_glyph
+nuts.traverse_id = direct.traverse_id
+nuts.traverse_list = direct.traverse_list
+nuts.unprotect_glyph = direct.unprotect_glyph
+nuts.unprotect_glyphs = direct.unprotect_glyphs
+nuts.unset_attribute = direct.unset_attribute
+nuts.unset_attribute = direct.unset_attribute
+nuts.usedlist = direct.usedlist
+nuts.uses_font = direct.uses_font
+nuts.vpack = direct.vpack
+nuts.writable_spec = direct.writable_spec
+nuts.write = direct.write
+nuts.mlist_to_hlist = direct.mlist_to_hlist
+
+if not nuts.mlist_to_hlist then
local n_mlist_to_hlist = node.mlist_to_hlist
- function nuts.mlist_to_hlist(head)
- return tonode(n_mlist_to_hlist(tonut(head)))
+ function nuts.mlist_to_hlist(head,...)
+ if head then
+ local head = n_mlist_to_hlist(tonode(head),...)
+ if head then
+ return tonut(head)
+ end
+ end
end
end
@@ -276,6 +246,14 @@ nuts.setdisc = direct.setdisc
nuts.getdiscretionary = direct.getdisc
nuts.setdiscretionary = direct.setdisc
+nuts.getdata = direct.getdata
+nuts.setdata = direct.setdata
+nuts.getvalue = direct.getdata
+nuts.setvalue = direct.setdata
+
+nuts.getexpansion = direct.getexpansion
+nuts.setexpansion = direct.setexpansion
+
nuts.getwhd = direct.getwhd
nuts.setwhd = direct.setwhd
nuts.getwidth = direct.getwidth
@@ -286,6 +264,8 @@ nuts.getdepth = direct.getdepth
nuts.setdepth = direct.setdepth
nuts.getshift = direct.getshift
nuts.setshift = direct.setshift
+nuts.getorientation = direct.getorientation or function() end
+nuts.setorientation = direct.setorientation or function() end
nuts.getnucleus = direct.getnucleus
nuts.setnucleus = direct.setnucleus
@@ -726,14 +706,10 @@ nodes.properties = {
data = propertydata,
}
-------.set_properties_mode(true,false) -- shallow copy ... problem: in fonts we then affect the originals too
-direct.set_properties_mode(true,true) -- create metatable, slower but needed for font-otj.lua (unless we use an intermediate table)
-
--- todo:
---
--- function direct.set_properties_mode()
--- -- we really need the set modes
--- end
+if direct.set_properties_mode then
+ direct.set_properties_mode(true,true) -- create metatable, slower but needed for font-otj.lua (unless we use an intermediate table)
+ function direct.set_properties_mode() end
+end
-- experimental code with respect to copying attributes has been removed
-- as it doesn't pay of (most attributes are only accessed once anyway)
@@ -770,8 +746,22 @@ nuts.theprop = function(n)
return p
end
-nodes.setprop = nodes.setproperty
-nodes.getprop = nodes.getproperty
+nuts.isdone = function(n,k)
+ local p = propertydata[n]
+ if not p then
+ propertydata[n] = { [k] = true }
+ return false
+ end
+ local v = p[k]
+ if v == nil then
+ propertydata[n] = { [k] = true }
+ return false
+ end
+ return v
+end
+
+-- nodes.setprop = nodes.setproperty
+-- nodes.getprop = nodes.getproperty
function nuts.copy_properties(source,target,what)
local newprops = propertydata[source]
@@ -800,116 +790,3 @@ function nuts.copy_properties(source,target,what)
end
return newprops -- for checking
end
-
--- here:
-
-nuts.get_synctex_fields = direct.get_synctex_fields
-nuts.set_synctex_fields = direct.set_synctex_fields
-
--- for now
-
-nodes.uses_font = nodes.uses_font
-nuts.uses_font = direct.uses_font
-
-if not nuts.uses_font then
-
- local glyph_code = nodecodes.glyph
- local getdisc = nuts.getdisc
- local getfont = nuts.getfont
- local traverse_id = nuts.traverse_id
- local tonut = nodes.tonut
-
- function nuts.uses_font(n,font)
- local pre, post, replace = getdisc(n)
- if pre then
- -- traverse_char
- for n in traverse_id(glyph_code,pre) do
- if getfont(n) == font then
- return true
- end
- end
- end
- if post then
- for n in traverse_id(glyph_code,post) do
- if getfont(n) == font then
- return true
- end
- end
- end
- if replace then
- for n in traverse_id(glyph_code,replace) do
- if getfont(n) == font then
- return true
- end
- end
- end
- return false
- end
-
- function nodes.uses_font(n,font)
- return nuts.uses_font(tonut(n),font)
- end
-
-end
-
--- for the moment (pre 6380)
-
-if not nuts.unprotect_glyph then
-
- local protect_glyph = nuts.protect_glyph
- local protect_glyphs = nuts.protect_glyphs
- local unprotect_glyph = nuts.unprotect_glyph
- local unprotect_glyphs = nuts.unprotect_glyphs
-
- local getnext = nuts.getnext
- local setnext = nuts.setnext
-
- function nuts.protectglyphs(first,last)
- if first == last then
- return protect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = protect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return protect_glyphs(first)
- end
- end
-
- function nuts.unprotectglyphs(first,last)
- if first == last then
- return unprotect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = unprotect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return unprotect_glyphs(first)
- end
- end
-
-end
-
-if LUATEXFUNCTIONALITY < 6384 then -- LUATEXVERSION < 1.070
-
- local getfield = nuts.getfield
- local setfield = nuts.setfield
-
- function nuts.getboxglue(n,glue_set,glue_order,glue_sign)
- return
- getfield(n,"glue_set"),
- getfield(n,"glue_order"),
- getfield(n,"glue_sign")
- end
-
- function nuts.setboxglue(n,glue_set,glue_order,glue_sign)
- setfield(n,"glue_set", glue_set or 0)
- setfield(n,"glue_order",glue_order or 0)
- setfield(n,"glue_sign", glue_sign or 0)
- end
-
-end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-par.lua b/Master/texmf-dist/tex/context/base/mkiv/node-par.lua
new file mode 100644
index 00000000000..8564c8764bd
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-par.lua
@@ -0,0 +1,48 @@
+if not modules then modules = { } end modules ['node-par'] = {
+ 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 starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+
+local sequencers = utilities.sequencers
+
+-- This are called a lot!
+
+local actions = nodes.tasks.actions("everypar")
+
+local function everypar(head)
+ starttiming(builders)
+ head = actions(head)
+ stoptiming(builders)
+ return head
+end
+
+callbacks.register("insert_local_par",everypar,"after paragraph start")
+
+local actions = sequencers.new {
+ name = "newgraf",
+ arguments = "mode,indented",
+ returnvalues = "indented",
+ results = "indented",
+}
+
+sequencers.appendgroup(actions,"before") -- user
+sequencers.appendgroup(actions,"system") -- private
+sequencers.appendgroup(actions,"after" ) -- user
+
+local function newgraf(mode,indented)
+ local runner = actions.runner
+ if runner then
+ starttiming(builders)
+ indent = runner(mode,indented)
+ stoptiming(builders)
+ end
+ return indented
+end
+
+callbacks.register("new_graf",newgraf,"before paragraph start")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
index 5ebfca87d14..485e742b64a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
@@ -26,12 +26,14 @@ local getid = nuts.getid
local getnext = nuts.getnext
local getprev = nuts.getprev
local getsubtype = nuts.getsubtype
-local getfield = nuts.getfield
local getlist = nuts.getlist
local setlist = nuts.setlist
+local getprop = nuts.getprop
+
local removenode = nuts.remove
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+
+local nextnode = nuts.traversers.node
+local nextwhatsit = nuts.traversers.whatsit
local nodecodes = nodes.nodecodes
local whatsitcodes = nodes.whatsitcodes
@@ -39,18 +41,17 @@ local whatsitcodes = nodes.whatsitcodes
local whatsit_code = nodecodes.whatsit
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-local userdefined_code = whatsitcodes.userdefined
+
+local userdefinedwhatsit_code = whatsitcodes.userdefined
local nodepool = nodes.pool
-local new_usernumber = nodepool.usernumber
+local new_usernode = nodepool.usernode
local variables = interfaces.variables
local v_before = variables.before
local v_after = variables.after
local v_here = variables.here
-local cache = { }
-local nofslots = 0
local property_id = nodepool.userids["property"]
local properties = nodes.properties
@@ -71,15 +72,8 @@ local function register(where,data,...)
where = v_after
end
if data then
- local data = { where, data, ... }
nofslots = nofslots + 1
- if nofslots > 1 then
- cache[nofslots] = data
- else
- -- report("restarting attacher")
- cache = { data } -- also forces collection
- end
- return new_usernumber(property_id,nofslots)
+ return new_usernode(property_id,{ where, data, ... })
end
end
@@ -108,17 +102,9 @@ local f_delayed = formatters["return function(target,head,where,propdata,paren
local f_immediate = formatters["return function(target,head,where,propdata) %s end"]
local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties
+local nofslots = 0
function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end
--- local kind = type(code)
--- if kind == "string" then
--- code, err = load(f_delayed(code))
--- if code then
--- code = code()
--- end
--- elseif kind ~= "function" then
--- code = nil
--- end
if code then
local delayed = propdata.delayed
if delayed then
@@ -131,15 +117,6 @@ function actions.delayed(target,head,where,propdata,code,...) -- this one is use
end
function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end
--- local kind = type(code)
--- if kind == "string" then
--- code, err = load(f_delayed(code))
--- if code then
--- code = code()
--- end
--- elseif kind ~= "function" then
--- code = nil
--- end
if code then
local delayed = propdata.delayed
if delayed then
@@ -170,81 +147,41 @@ function actions.immediate(target,head,where,propdata,code,...) -- this one is u
end
end
--- another experiment (a table or function closure are equally efficient); a function
--- is easier when we want to experiment with different (compatible) implementations
-
--- local nutpool = nuts.pool
--- local nut_usernumber = nutpool.usernumber
-
--- function nodes.nuts.pool.deferredfunction(...)
--- nofdelayed = nofdelayed + 1
--- local n = nut_usernumber(property_id,0)
--- propertydata[n] = { deferred = { ... } }
--- return n
--- end
-
--- function nodes.nuts.pool.deferredfunction(f)
--- nofdelayed = nofdelayed + 1
--- local n = nut_usernumber(property_id,0)
--- propertydata[n] = { deferred = f }
--- return n
--- end
-
--- maybe actions will get parent too
-
local function delayed(head,parent) -- direct based
- for target in traverse(head) do
+ for target, id in nextnode, head do
local p = propertydata[target]
if p then
- -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v)
- -- if deferred then
- -- -- if #deferred > 0 then
- -- -- deferred[1](unpack(deferred,2))
- -- -- else
- -- -- deferred[1]()
- -- -- end
- -- deferred()
- -- p.deferred = false
- -- if nofdelayed == 1 then
- -- nofdelayed = 0
- -- return head
- -- else
- -- nofdelayed = nofdelayed - 1
- -- end
- -- else
- local delayed = p.delayed
- if delayed then
- for i=1,#delayed do
- local d = delayed[i]
- local code = d[2]
- local kind = type(code)
- if kind == "string" then
- code, err = load(f_delayed(code))
- if code then
- code = code()
- end
- end
- local where = d[1]
- if where then
- local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent
- if h and h ~= head then
- head = h
- end
- else
- code(unpack(d,3))
+ local delayed = p.delayed
+ if delayed then
+ for i=1,#delayed do
+ local d = delayed[i]
+ local code = d[2]
+ local kind = type(code)
+ if kind == "string" then
+ code, err = load(f_delayed(code))
+ if code then
+ code = code()
end
end
- p.delayed = nil
- if nofdelayed == 1 then
- nofdelayed = 0
- return head
+ local where = d[1]
+ if where then
+ local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent
+ if h and h ~= head then
+ head = h
+ end
else
- nofdelayed = nofdelayed - 1
+ code(unpack(d,3))
end
end
- -- end
+ p.delayed = nil
+ if nofdelayed == 1 then
+ nofdelayed = 0
+ return head
+ else
+ nofdelayed = nofdelayed - 1
+ end
+ end
end
- local id = getid(target)
if id == hlist_code or id == vlist_code then
local list = getlist(target)
if list then
@@ -268,14 +205,13 @@ function properties.delayed(head) --
if nofdelayed > 0 then
-- if next(propertydata) then
starttiming(properties)
- head = delayed(tonut(head))
+ head = delayed(head)
stoptiming(properties)
- return tonode(head), true -- done in shipout anyway
-- else
-- delayed = 0
- -- end
+ -- end
end
- return head, false
+ return head
end
-- more explicit ones too
@@ -284,7 +220,7 @@ local anchored = {
[v_before] = function(n)
while n do
n = getprev(n)
- if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then
+ if getid(n) == whatsit_code and getsubtype(n) == user_code and getprop(n,"id") == property_id then
-- continue
else
return n
@@ -296,7 +232,7 @@ local anchored = {
n = getnext(n)
if getid(n) == whatsit_code then
local subtype = getsubtype(n)
- if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then
+ if (subtype == userdefinedwhatsit_code and getprop(n,"id") == property_id) then
-- continue
else
return n
@@ -320,26 +256,22 @@ end)
function properties.attach(head)
if nofslots <= 0 then
- return head, false
+ return head
end
- local done = false
local last = nil
- local head = tonut(head)
starttiming(properties)
- for source in traverse_id(whatsit_code,head) do
- if getsubtype(source) == userdefined_code then
+ for source, subtype in nextwhatsit, head do
+ if subtype == userdefinedwhatsit_code then
if last then
removenode(head,last,true)
last = nil
end
- if getfield(source,"user_id") == property_id then
- local slot = getfield(source,"value")
- local data = cache[slot]
+ if getprop(source,"id") == property_id then
+ local data = getprop(source,"data")
if data then
- cache[slot] = nil
local where = data[1]
local target = anchored[where](source)
if target then
@@ -393,7 +325,7 @@ function properties.attach(head)
target,nodecodes[getid(target)],serialize(propertydata[target],false))
end
end
- if nofslots == 1 then
+ if nofslots == 1 then
nofslots = 0
last = source
break
@@ -412,25 +344,22 @@ function properties.attach(head)
stoptiming(properties)
- return head, done
+ return head
end
-local tasks = nodes.tasks
-
-- maybe better hard coded in-place
--- tasks.prependaction("processors","before","nodes.properties.attach")
--- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed")
-
statistics.register("properties processing time", function()
return statistics.elapsedseconds(properties)
end)
-- only for development
+-- local tasks = nodes.tasks
+--
-- local function show(head,level,report)
--- for target in traverse(head) do
+-- for target in nextnode, head do
-- local p = propertydata[target]
-- if p then
-- report("level %i, node %i, id %s, data %s",
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-pro.lua b/Master/texmf-dist/tex/context/base/mkiv/node-pro.lua
index 4509bac18db..b6b1305886f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-pro.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-pro.lua
@@ -35,7 +35,7 @@ do
local n = 0
local function reconstruct(head) -- we probably have a better one
- local t, n, h = { }, 0, tonut(head)
+ local t, n, h = { }, 0, head
while h do
n = n + 1
local char, id = isglyph(h)
@@ -49,7 +49,7 @@ do
return concat(t)
end
- function processors.tracer(what,state,head,groupcode,before,after,show)
+ function processors.tracer(what,head,groupcode,before,after,show)
if not groupcode then
groupcode = "unknown"
elseif groupcode == "" then
@@ -57,16 +57,14 @@ do
end
n = n + 1
if show then
- report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s, stream: %s",what,n,state,groupcode,before,after,reconstruct(head))
+ report_nodes("%s: location %a, group %a, # before %a, # after %s, stream: %s",what,n,groupcode,before,after,reconstruct(head))
else
- report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s",what,n,state,groupcode,before,after)
+ report_nodes("%s: location %a, group %a, # before %a, # after %s",what,n,groupcode,before,after)
end
end
end
-local tracer = processors.tracer
-
processors.enabled = true -- this will become a proper state (like trackers)
do
@@ -74,154 +72,131 @@ do
local has_glyph = nodes.has_glyph
local count_nodes = nodes.countall
- function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction
+ local texget = tex.get
+
+ local tracer = processors.tracer
+
+ local function pre_linebreak_filter(head,groupcode)
local found = force_processors or has_glyph(head)
if found then
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode) -- ,size,packtype,direction
+ head = actions(head,groupcode)
local after = count_nodes(head,true)
- if done then
- tracer("pre_linebreak","changed",head,groupcode,before,after,true)
- else
- tracer("pre_linebreak","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("pre_linebreak",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode) -- ,size,packtype,direction
- return done and head or true
+ head = actions(head,groupcode)
end
elseif trace_callbacks then
local n = count_nodes(head,false)
- tracer("pre_linebreak","no chars",head,groupcode,n,n)
+ tracer("pre_linebreak",head,groupcode,n,n)
end
- return true
+ return head
end
local function hpack_filter(head,groupcode,size,packtype,direction,attributes)
local found = force_processors or has_glyph(head)
if found then
+ --
+ -- yes or no or maybe an option
+ --
+ if not direction then
+ direction = texget("textdir")
+ end
+ --
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode,size,packtype,direction,attributes)
+ head = actions(head,groupcode,size,packtype,direction,attributes)
local after = count_nodes(head,true)
- if done then
- tracer("hpack","changed",head,groupcode,before,after,true)
- else
- tracer("hpack","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("hpack",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode,size,packtype,direction,attributes)
- return done and head or true
+ head = actions(head,groupcode,size,packtype,direction,attributes)
end
elseif trace_callbacks then
local n = count_nodes(head,false)
- tracer("hpack","no chars",head,groupcode,n,n)
+ tracer("hpack",head,groupcode,n,n)
end
- return true
+ return head
end
- processors.hpack_filter = hpack_filter
+ processors.pre_linebreak_filter = pre_linebreak_filter
+ processors.hpack_filter = hpack_filter
do
- local setfield = nodes.setfield
- local hpack = nodes.hpack
+ local hpack = nodes.hpack
function nodes.fullhpack(head,...)
- local ok = hpack_filter(head)
- if not done or done == true then
- ok = head
- end
- local hp, b = hpack(ok,...)
- setfield(hp,"prev",nil)
- setfield(hp,"next",nil)
- return hp, b
+ return hpack((hpack_filter(head)),...)
end
end
do
- local setboth = nuts.setboth
- local hpack = nuts.hpack
+ local hpack = nuts.hpack
function nuts.fullhpack(head,...)
- local ok = hpack_filter(tonode(head))
- if not done or done == true then
- ok = head
- else
- ok = tonut(ok)
- end
- local hp, b = hpack(...)
- setboth(hp)
- return hp, b
+ return hpack(tonut(hpack_filter(tonode(head))),...)
end
end
- callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter, "all kind of horizontal manipulations (before par break)")
- callbacks.register('hpack_filter' , processors.hpack_filter, "all kind of horizontal manipulations (before hbox creation)")
+ callbacks.register('pre_linebreak_filter', pre_linebreak_filter, "horizontal manipulations (before par break)")
+ callbacks.register('hpack_filter' , hpack_filter, "horizontal manipulations (before hbox creation)")
end
do
+ -- Beware, these are packaged boxes so no first_glyph test needed. Maybe some day I'll add a hash
+ -- with valid groupcodes. Watch out, much can pass twice, for instance vadjust passes two times,
local actions = tasks.actions("finalizers") -- head, where
local count_nodes = nodes.countall
- -- beware, these are packaged boxes so no first_glyph test
- -- maybe some day a hash with valid groupcodes
- --
- -- beware, much can pass twice, for instance vadjust passes two times
- --
- -- something weird here .. group mvl when making a vbox
+ local tracer = processors.tracer
- function processors.post_linebreak_filter(head,groupcode)
+ local function post_linebreak_filter(head,groupcode)
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode)
+ head = actions(head,groupcode)
local after = count_nodes(head,true)
- if done then
- tracer("post_linebreak","changed",head,groupcode,before,after,true)
- else
- tracer("post_linebreak","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("post_linebreak",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode)
- return done and head or true
+ head = actions(head,groupcode)
end
+ return head
end
- callbacks.register('post_linebreak_filter', processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)")
+ processors.post_linebreak_filter = post_linebreak_filter
+
+ callbacks.register("post_linebreak_filter", post_linebreak_filter,"horizontal manipulations (after par break)")
end
do
- local texnest = tex.nest
+ local texnest = tex.nest
- local getlist = nodes.getlist
- local setlist = nodes.setlist
- local getsubtype = nodes.getsubtype
+ local getlist = nodes.getlist
+ local setlist = nodes.setlist
+ local getsubtype = nodes.getsubtype
- local line_code = nodes.listcodes.line
+ local linelist_code = nodes.listcodes.line
- local actions = tasks.actions("contributers")
+ local actions = tasks.actions("contributers")
function processors.contribute_filter(groupcode)
if groupcode == "box" then -- "pre_box"
local whatever = texnest[texnest.ptr]
if whatever then
local line = whatever.tail
- if line and getsubtype(line) == line_code then
+ if line and getsubtype(line) == linelist_code then
local head = getlist(line)
if head then
- local okay, done = actions(head,groupcode,line)
- if okay and okay ~= head then
- setlist(line,okay)
+ local result = actions(head,groupcode,line)
+ if result and result ~= head then
+ setlist(line,result)
end
end
end
@@ -229,7 +204,7 @@ do
end
end
- callbacks.register('contribute_filter', processors.contribute_filter,"things done with lines")
+ callbacks.register("contribute_filter", processors.contribute_filter,"things done with lines")
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua
index 1ec77e83de3..e12bd95bdd6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua
@@ -67,21 +67,25 @@ local getattr = nuts.getattr
local setattr = nuts.setattr
local getsubtype = nuts.getsubtype
local getwhd = nuts.getwhd
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local setshift = nuts.setshift
local getboxglue = nuts.getboxglue
local hpack_list = nuts.hpack
local vpack_list = nuts.vpack
-local list_dimensions = nuts.dimensions
-local list_rangedimensions = nuts.rangedimensions
+local getdimensions = nuts.dimensions
+local getrangedimensions = nuts.rangedimensions
local traverse = nuts.traverse
local find_node_tail = nuts.tail
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local listcodes = nodes.listcodes
+local dirvalues = nodes.dirvalues
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
+
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local glue_code = nodecodes.glue
@@ -90,11 +94,11 @@ local rule_code = nodecodes.rule
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local leftskip_code = skipcodes.leftskip
-local rightskip_code = skipcodes.rightskip
-local parfillskip_code = skipcodes.parfillskip
+local leftskip_code = gluecodes.leftskip
+local rightskip_code = gluecodes.rightskip
+local parfillskip_code = gluecodes.parfillskip
-local line_code = listcodes.line
+----- linelist_code = listcodes.line
local new_rule = nodepool.rule
local new_kern = nodepool.kern
@@ -113,9 +117,9 @@ local implement = interfaces.implement
local function hlist_dimensions(start,stop,parent)
local last = stop and getnext(stop)
if parent then
- return list_rangedimensions(parent,start,last)
+ return getrangedimensions(parent,start,last)
else
- return list_dimensions(start,last)
+ return getdimensions(start,last)
end
end
@@ -250,11 +254,13 @@ local function dimensions(parent,start,stop) -- in principle we could move some
end
end
--- is pardir important at all?
-
local function inject_range(head,first,last,reference,make,stack,parent,pardir,txtdir)
local width, height, depth, line = dimensions(parent,first,last)
- if txtdir == "+TRT" or (txtdir == "===" and pardir == "TRT") then -- KH: textdir == "===" test added
+ if txtdir == righttoleft_code then
+ width = - width
+ elseif textdir == lefttoright_code then
+ -- go on
+ elseif pardir == righttoleft_code then
width = - width
end
local result, resolved = make(width,height,depth,reference)
@@ -264,7 +270,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t
local l = getlist(line)
if trace_areas then
report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","line",
- reference,pardir or "---",txtdir or "---",
+ reference,pardir or "?",txtdir or "?",
tosequence(l,nil,true),width,height,depth)
end
setlist(line,result)
@@ -273,7 +279,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t
elseif head == first then
if trace_areas then
report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","head",
- reference,pardir or "---",txtdir or "---",
+ reference,pardir or "?",txtdir or "?",
tosequence(first,last,true),width,height,depth)
end
setlink(result,first)
@@ -281,7 +287,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t
else
if trace_areas then
report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","middle",
- reference,pardir or "---",txtdir or "---",
+ reference,pardir or "?",txtdir or "?",
tosequence(first,last,true),width,height,depth)
end
if first == last and getid(parent) == vlist_code and getid(first) == hlist_code then
@@ -306,7 +312,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir)
local correction = 0
local moveright = false
local first = getlist(current)
- if id == hlist_code then -- box_code line_code
+ if id == hlist_code then -- boxlist_code linelist_code
-- can be either an explicit hbox or a line and there is no way
-- to recognize this; anyway only if ht/dp (then inline)
local sr = stack[reference]
@@ -337,7 +343,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir)
correction = height + depth
height, depth = depth, height -- ugly hack, needed because pdftex backend does something funny
end
- if pardir == "TRT" then
+ if pardir == righttoleft_code then
width = - width
end
local result, resolved = make(width,height,depth,reference)
@@ -345,7 +351,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir)
if result and resolved then
if trace_areas then
report_area("%s: %04i %s %s %s: w=%p, h=%p, d=%p, c=%S","box",
- reference,pardir or "---",txtdir or "----","[]",width,height,depth,resolved)
+ reference,pardir or "?",txtdir or "?","[]",width,height,depth,resolved)
end
if not first then
setlist(current,result)
@@ -370,12 +376,6 @@ end
local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main
local first, last, firstdir, reference
- if not pardir then
- pardir = "==="
- end
- if not texdir then
- txtdir = "==="
- end
local current = head
while current do
local id = getid(current)
@@ -404,8 +404,8 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
end
local list = getlist(current)
if list then
- local h, ok
- h, ok, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
+ local h
+ h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
if h ~= current then
setlist(current,h)
end
@@ -416,9 +416,12 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left?
--
elseif id == dir_code then
- txtdir = getdir(current)
- elseif id == localpar_code then -- only test at begin
- pardir = getdir(current)
+ local direction, pop = getdirection(current)
+ txtdir = not pop and direction -- we might need a stack
+ elseif id == localpar_code then
+ if getsubtype(current) == 0 then
+ pardir = getdirection(current)
+ end
else
local r = getattr(current,attribute)
if not r then
@@ -441,46 +444,183 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
if reference and (done[reference] or 0) == 0 then
head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
end
- return head, true, pardir, txtdir
+ return head, pardir, txtdir
end
--- local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular !
--- if not pardir then
--- pardir = "==="
--- end
--- if not texdir then
--- txtdir = "==="
+-- -- not faster either:
+--
+-- local findattr = node.direct.find_attribute
+--
+-- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main
+-- local first, last, firstdir, reference
+-- local someatt = findattr(head,attribute)
+-- if someatt then
+-- local current = head
+-- while current do
+-- local id = getid(current)
+-- if id == hlist_code or id == vlist_code then
+-- local r = getattr(current,attribute)
+-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
+-- -- test \goto{\TeX}[page(2)] test \gotobox{\hbox {x} \hbox {x}}[page(2)]
+-- -- if r and (not skip or r >) skip then -- maybe no > test
+-- -- inject_list(id,current,r,make,stack,pardir,txtdir)
+-- -- end
+-- if r then
+-- if not reference then
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- elseif r == reference then
+-- -- same link
+-- last = current
+-- elseif (done[reference] or 0) == 0 then
+-- if not skip or r > skip then -- maybe no > test
+-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- reference, first, last, firstdir = nil, nil, nil, nil
+-- end
+-- else
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- end
+-- done[r] = (done[r] or 0) + 1
+-- end
+-- local list = getlist(current)
+-- if list then
+-- local h
+-- h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
+-- if h ~= current then
+-- setlist(current,h)
+-- end
+-- end
+-- if r then
+-- done[r] = done[r] - 1
+-- end
+-- elseif id == dir_code then
+-- local direction, pop = getdirection(current)
+-- txtdir = not pop and direction -- we might need a stack
+-- elseif id == localpar_code then -- only test at begin
+-- pardir = getdirection(current)
+-- elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left?
+-- --
+-- else
+-- local r = getattr(current,attribute)
+-- if not r then
+-- -- just go on, can be kerns
+-- elseif not reference then
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- elseif r == reference then
+-- last = current
+-- elseif (done[reference] or 0) == 0 then -- or id == glue_code and getsubtype(current) == right_skip_code
+-- if not skip or r > skip then -- maybe no > test
+-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- reference, first, last, firstdir = nil, nil, nil, nil
+-- end
+-- else
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- end
+-- end
+-- current = getnext(current)
+-- end
+-- if reference and (done[reference] or 0) == 0 then
+-- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- end
+-- else
+-- local current = head
+-- while current do
+-- local id = getid(current)
+-- if id == hlist_code or id == vlist_code then
+-- local list = getlist(current)
+-- if list then
+-- local h = inject_areas(list,attribute,make,stack,done,skip or 0,current,pardir,txtdir)
+-- if h ~= current then
+-- setlist(current,h)
+-- end
+-- end
+-- elseif id == dir_code then
+-- local direction, pop = getdirection(current)
+-- txtdir = not pop and direction -- we might need a stack
+-- elseif id == localpar_code then -- only test at begin
+-- pardir = getdirection(current)
+-- end
+-- current = getnext(current)
+-- end
-- end
+-- return head, pardir, txtdir
+-- end
+
+-- -- maybe first check for glyphs and use a goto:
+--
+-- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main
+-- local first, last, firstdir, reference
-- local current = head
-- while current do
-- local id = getid(current)
--- if id == hlist_code or id == vlist_code then
--- local r = getattr(current,attribute)
--- if r and not done[r] then
--- done[r] = true
--- inject_list(id,current,r,make,stack,pardir,txtdir)
+-- local r -- else scope message due to goto
+-- if id == glyph_code then
+-- goto rest
+-- elseif id == hlist_code or id == vlist_code then
+-- r = getattr(current,attribute)
+-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
+-- -- test \goto{\TeX}[page(2)] test \gotobox{\hbox {x} \hbox {x}}[page(2)]
+-- -- if r and (not skip or r >) skip then -- maybe no > test
+-- -- inject_list(id,current,r,make,stack,pardir,txtdir)
+-- -- end
+-- if r then
+-- if not reference then
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- elseif r == reference then
+-- -- same link
+-- last = current
+-- elseif (done[reference] or 0) == 0 then
+-- if not skip or r > skip then -- maybe no > test
+-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- reference, first, last, firstdir = nil, nil, nil, nil
+-- end
+-- else
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- end
+-- done[r] = (done[r] or 0) + 1
-- end
-- local list = getlist(current)
-- if list then
--- local h = inject_area(list,attribute,make,stack,done,current,pardir,txtdir)
+-- local h
+-- h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
-- if h ~= current then
-- setlist(current,h)
-- end
-- end
+-- if r then
+-- done[r] = done[r] - 1
+-- end
+-- elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left?
+-- --
-- elseif id == dir_code then
--- txtdir = getdir(current)
--- elseif id == localpar_code then
--- pardir = getdir(current)
--- else
--- local r = getattr(current,attribute)
--- if r and not done[r] then
--- done[r] = true
--- head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir)
+-- local direction, pop = getdirection(current)
+-- txtdir = not pop and direction -- we might need a stack
+-- elseif id == localpar_code then -- only test at begin
+-- pardir = getdirection(current)
+-- end
+-- goto next
+-- ::rest::
+-- r = getattr(current,attribute)
+-- if not r then
+-- -- just go on, can be kerns
+-- elseif not reference then
+-- reference, first, last, firstdir = r, current, current, txtdir
+-- elseif r == reference then
+-- last = current
+-- elseif (done[reference] or 0) == 0 then -- or id == glue_code and getsubtype(current) == right_skip_code
+-- if not skip or r > skip then -- maybe no > test
+-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- reference, first, last, firstdir = nil, nil, nil, nil
-- end
+-- else
+-- reference, first, last, firstdir = r, current, current, txtdir
-- end
+-- ::next::
-- current = getnext(current)
-- end
--- return head, true
+-- if reference and (done[reference] or 0) == 0 then
+-- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+-- end
+-- return head, pardir, txtdir
-- end
-- tracing: todo: use predefined colors
@@ -595,11 +735,11 @@ nodes.references = {
-- todo: get rid of n (n is just a number, can be used for tracing, obsolete)
-local function setreference(h,d,r)
+local function setreference(h,d,r) -- h and d can be nil
topofstack = topofstack + 1
-- the preroll permits us to determine samepage (but delayed also has some advantages)
-- so some part of the backend work is already done here
- stack[topofstack] = { r, h, d, codeinjections.prerollreference(r) }
+ stack[topofstack] = { r, h or false, d or false, codeinjections.prerollreference(r) }
-- texsetattribute(attribute,topofstack) -- todo -> at tex end
texsetcount("lastreferenceattribute",topofstack)
end
@@ -615,7 +755,11 @@ local function makereference(width,height,depth,reference) -- height and depth a
if trace_references then
report_reference("resolving attribute %a",reference)
end
- local resolved, ht, dp, set, n = sr[1], sr[2], sr[3], sr[4], sr[5]
+ local resolved = sr[1]
+ local ht = sr[2]
+ local dp = sr[3]
+ local set = sr[4]
+ local n = sr[5]
-- logs.report("temp","child: ht=%p dp=%p, parent: ht=%p dp=%p",ht,dp,height,depth)
if ht then
if height < ht then height = ht end
@@ -672,11 +816,9 @@ end
function nodes.references.handler(head)
if head and topofstack > 0 then
- local head = tonut(head)
- local head, done = inject_areas(head,attribute,makereference,stack,done)
- return tonode(head), done
+ return (inject_areas(head,attribute,makereference,stack,done))
else
- return head, false
+ return head
end
end
@@ -706,7 +848,11 @@ local function makedestination(width,height,depth,reference)
if trace_destinations then
report_destination("resolving attribute %a",reference)
end
- local resolved, ht, dp, name, view = sr[1], sr[2], sr[3], sr[4], sr[5] -- sr[4] will change to just internal
+ local resolved = sr[1]
+ local ht = sr[2]
+ local dp = sr[3]
+ local name = sr[4]
+ local view = sr[5]
if ht then
if height < ht then height = ht end
if depth < dp then depth = dp end
@@ -783,21 +929,12 @@ local function makedestination(width,height,depth,reference)
end
end
--- function nodes.destinations.handler(head)
--- if head and topofstack > 0 then
--- return inject_area(head,attribute,makedestination,stack,done) -- singular
--- else
--- return head, false
--- end
--- end
function nodes.destinations.handler(head)
if head and topofstack > 0 then
- local head = tonut(head)
- local head, done = inject_areas(head,attribute,makedestination,stack,done)
- return tonode(head), done
+ return (inject_areas(head,attribute,makedestination,stack,done))
else
- return head, false
+ return head
end
end
@@ -907,15 +1044,3 @@ statistics.register("interactive elements", function()
return nil
end
end)
-
-function references.enableinteraction()
- enableaction("shipouts","nodes.references.handler")
- enableaction("shipouts","nodes.destinations.handler")
- function references.enableinteraction() end
-end
-
-implement {
- name = "enableinteraction",
- actions = references.enableinteraction,
- onlyonce = true
-}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-res.lua b/Master/texmf-dist/tex/context/base/mkiv/node-res.lua
index a6211e80e4c..d9999968ae6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-res.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-res.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['node-res'] = {
license = "see context related readme files"
}
+local type, next = type, next
local gmatch, format = string.gmatch, string.format
--[[ldx--
@@ -13,34 +14,39 @@ local gmatch, format = string.gmatch, string.format
for debugging node management.
--ldx]]--
-local report_nodes = logs.reporter("nodes","housekeeping")
-
local nodes, node = nodes, node
-nodes.pool = nodes.pool or { }
-local nodepool = nodes.pool
+local report_nodes = logs.reporter("nodes","housekeeping")
-local whatsitcodes = nodes.whatsitcodes
-local skipcodes = nodes.skipcodes
-local kerncodes = nodes.kerncodes
-local rulecodes = nodes.rulecodes
-local nodecodes = nodes.nodecodes
-local gluecodes = nodes.gluecodes
-local boundarycodes = nodes.boundarycodes
-local usercodes = nodes.usercodes
+nodes.pool = nodes.pool or { }
+local nodepool = nodes.pool
-local glyph_code = nodecodes.glyph
+local whatsitcodes = nodes.whatsitcodes
+local gluecodes = nodes.gluecodes
+local kerncodes = nodes.kerncodes
+local rulecodes = nodes.rulecodes
+local nodecodes = nodes.nodecodes
+local leadercodes = nodes.leadercodes
+local boundarycodes = nodes.boundarycodes
+local usercodes = nodes.usercodes
-local allocate = utilities.storage.allocate
+local nodeproperties = nodes.properties.data
-local texgetcount = tex.getcount
+local glyph_code = nodecodes.glyph
+local rule_code = nodecodes.rule
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local whatsit_code = nodecodes.whatsit
-local reserved, nofreserved = { }, 0
+local currentfont = font.current
+local texgetcount = tex.getcount
--- user nodes
+local allocate = utilities.storage.allocate
-local userids = allocate()
-local lastid = 0
+local reserved = { }
+local nofreserved = 0
+local userids = allocate()
+local lastid = 0
setmetatable(userids, {
__index = function(t,k)
@@ -89,6 +95,9 @@ local setwidth = nuts.setwidth
local setsubtype = nuts.setsubtype
local setleader = nuts.setleader
+local setdata = nuts.setdata
+local setvalue = nuts.setvalue
+
local copy_nut = nuts.copy
local new_nut = nuts.new
local flush_nut = nuts.flush
@@ -147,68 +156,68 @@ nutpool.register = register_node -- could be register_nut
-- so far
-local disc = register_nut(new_nut("disc"))
-local kern = register_nut(new_nut("kern",kerncodes.userkern))
-local fontkern = register_nut(new_nut("kern",kerncodes.fontkern))
-local italickern = register_nut(new_nut("kern",kerncodes.italiccorrection))
-local penalty = register_nut(new_nut("penalty"))
-local glue = register_nut(new_nut("glue")) -- glue.spec = nil
-local glue_spec = register_nut(new_nut("glue_spec"))
-local glyph = register_nut(new_nut("glyph",0))
+local disc = register_nut(new_nut(nodecodes.disc))
+local kern = register_nut(new_nut(kern_code,kerncodes.userkern))
+local fontkern = register_nut(new_nut(kern_code,kerncodes.fontkern))
+local italickern = register_nut(new_nut(kern_code,kerncodes.italiccorrection))
+local penalty = register_nut(new_nut(nodecodes.penalty))
+local glue = register_nut(new_nut(glue_code)) -- glue.spec = nil
+local glue_spec = register_nut(new_nut(nodecodes.gluespec))
+local glyph = register_nut(new_nut(glyph_code,0))
-local textdir = register_nut(new_nut("dir"))
+local textdir = register_nut(new_nut(nodecodes.dir))
-local latelua = register_nut(new_nut("whatsit",whatsitcodes.latelua))
-local special = register_nut(new_nut("whatsit",whatsitcodes.special))
+local latelua = register_nut(new_nut(whatsit_code,whatsitcodes.latelua))
+local savepos = register_nut(new_nut(whatsit_code,whatsitcodes.savepos))
-local user_node = new_nut("whatsit",whatsitcodes.userdefined)
+local user_node = new_nut(whatsit_code,whatsitcodes.userdefined)
-local user_number = register_nut(copy_nut(user_node)) setfield(user_number, "type",usercodes.number)
-local user_nodes = register_nut(copy_nut(user_node)) setfield(user_nodes, "type",usercodes.node)
-local user_string = register_nut(copy_nut(user_node)) setfield(user_string, "type",usercodes.string)
-local user_tokens = register_nut(copy_nut(user_node)) setfield(user_tokens, "type",usercodes.token)
------ user_lua = register_nut(copy_nut(user_node)) setfield(user_lua, "type",usercodes.lua) -- in > 0.95
-local user_attributes = register_nut(copy_nut(user_node)) setfield(user_attributes,"type",usercodes.attribute)
+if CONTEXTLMTXMODE < 2 then
+ setfield(user_node,"type",usercodes.number)
+end
-local left_margin_kern = register_nut(new_nut("margin_kern",0))
-local right_margin_kern = register_nut(new_nut("margin_kern",1))
+local left_margin_kern = register_nut(new_nut(nodecodes.marginkern,0))
+local right_margin_kern = register_nut(new_nut(nodecodes.marginkern,1))
-local lineskip = register_nut(new_nut("glue",skipcodes.lineskip))
-local baselineskip = register_nut(new_nut("glue",skipcodes.baselineskip))
-local leftskip = register_nut(new_nut("glue",skipcodes.leftskip))
-local rightskip = register_nut(new_nut("glue",skipcodes.rightskip))
+local lineskip = register_nut(new_nut(glue_code,gluecodes.lineskip))
+local baselineskip = register_nut(new_nut(glue_code,gluecodes.baselineskip))
+local leftskip = register_nut(new_nut(glue_code,gluecodes.leftskip))
+local rightskip = register_nut(new_nut(glue_code,gluecodes.rightskip))
-local temp = register_nut(new_nut("temp",0))
+local temp = register_nut(new_nut(nodecodes.temp,0))
-local noad = register_nut(new_nut("noad"))
-local delimiter = register_nut(new_nut("delim"))
-local fence = register_nut(new_nut("fence"))
-local submlist = register_nut(new_nut("sub_mlist"))
-local accent = register_nut(new_nut("accent"))
-local radical = register_nut(new_nut("radical"))
-local fraction = register_nut(new_nut("fraction"))
-local subbox = register_nut(new_nut("sub_box"))
-local mathchar = register_nut(new_nut("math_char"))
-local mathtextchar = register_nut(new_nut("math_text_char"))
-local choice = register_nut(new_nut("choice"))
+local noad = register_nut(new_nut(nodecodes.noad))
+local delimiter = register_nut(new_nut(nodecodes.delim))
+local fence = register_nut(new_nut(nodecodes.fence))
+local submlist = register_nut(new_nut(nodecodes.submlist))
+local accent = register_nut(new_nut(nodecodes.accent))
+local radical = register_nut(new_nut(nodecodes.radical))
+local fraction = register_nut(new_nut(nodecodes.fraction))
+local subbox = register_nut(new_nut(nodecodes.subbox))
+local mathchar = register_nut(new_nut(nodecodes.mathchar))
+local mathtextchar = register_nut(new_nut(nodecodes.mathtextchar))
+local choice = register_nut(new_nut(nodecodes.choice))
-local boundary = register_nut(new_nut("boundary",boundarycodes.user))
-local wordboundary = register_nut(new_nut("boundary",boundarycodes.word))
+local boundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.user))
+local wordboundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.word))
-local cleader = register_nut(copy_nut(glue)) setsubtype(cleader,gluecodes.cleaders) setglue(cleader,0,65536,0,2,0)
+local cleader = register_nut(copy_nut(glue)) setsubtype(cleader,leadercodes.cleaders) setglue(cleader,0,65536,0,2,0)
-- the dir field needs to be set otherwise crash:
-local rule = register_nut(new_nut("rule")) setdir(rule, "TLT")
-local emptyrule = register_nut(new_nut("rule",rulecodes.empty)) setdir(rule, "TLT")
-local userrule = register_nut(new_nut("rule",rulecodes.user)) setdir(rule, "TLT")
-local hlist = register_nut(new_nut("hlist")) setdir(hlist,"TLT")
-local vlist = register_nut(new_nut("vlist")) setdir(vlist,"TLT")
+local lefttoright_code = nodes.dirvalues.lefttoright
+
+local rule = register_nut(new_nut(rule_code)) setdirection(rule, lefttoright_code)
+local emptyrule = register_nut(new_nut(rule_code,rulecodes.empty)) setdirection(rule, lefttoright_code)
+local userrule = register_nut(new_nut(rule_code,rulecodes.user)) setdirection(rule, lefttoright_code)
+local outlinerule = register_nut(new_nut(rule_code,rulecodes.outline)) setdirection(rule, lefttoright_code)
+local hlist = register_nut(new_nut(nodecodes.hlist)) setdirection(hlist,lefttoright_code)
+local vlist = register_nut(new_nut(nodecodes.vlist)) setdirection(vlist,lefttoright_code)
function nutpool.glyph(fnt,chr)
local n = copy_nut(glyph)
if fnt then
- setfont(n,fnt,chr)
+ setfont(n,fnt == true and currentfont() or fnt,chr)
elseif chr then
setchar(n,chr)
end
@@ -234,7 +243,7 @@ end
function nutpool.boundary(v)
local n = copy_nut(boundary)
if v and v ~= 0 then
- setfield(n,"value",v)
+ setvalue(n,v)
end
return n
end
@@ -242,7 +251,7 @@ end
function nutpool.wordboundary(v)
local n = copy_nut(wordboundary)
if v and v ~= 0 then
- setfield(n,"value",v)
+ setvalue(n,v)
end
return n
end
@@ -335,7 +344,7 @@ function nutpool.disc(pre,post,replace)
return d
end
-function nutpool.textdir(dir)
+function nutpool.textdir(dir) -- obsolete !
local t = copy_nut(textdir)
if dir then
setdir(t,dir)
@@ -355,35 +364,49 @@ function nutpool.direction(dir,swap)
return t
end
-function nutpool.rule(width,height,depth,dir) -- w/h/d == nil will let them adapt
+function nutpool.rule(width,height,depth,direction) -- w/h/d == nil will let them adapt
local n = copy_nut(rule)
if width or height or depth then
setwhd(n,width,height,depth)
end
- if dir then
- setdir(n,dir)
+ if direction then
+ setdirection(n,direction)
end
return n
end
-function nutpool.emptyrule(width,height,depth,dir) -- w/h/d == nil will let them adapt
+function nutpool.emptyrule(width,height,depth,direction) -- w/h/d == nil will let them adapt
local n = copy_nut(emptyrule)
if width or height or depth then
setwhd(n,width,height,depth)
end
- if dir then
- setdir(n,dir)
+ if direction then
+ setdirection(n,direction)
end
return n
end
-function nutpool.userrule(width,height,depth,dir) -- w/h/d == nil will let them adapt
+function nutpool.userrule(width,height,depth,direction) -- w/h/d == nil will let them adapt
local n = copy_nut(userrule)
if width or height or depth then
setwhd(n,width,height,depth)
end
- if dir then
- setdir(n,dir)
+ if direction then
+ setdirection(n,direction)
+ end
+ return n
+end
+
+function nutpool.outlinerule(width,height,depth,line,direction) -- w/h/d == nil will let them adapt
+ local n = copy_nut(outlinerule)
+ if width or height or depth then
+ setwhd(n,width,height,depth)
+ end
+ if line then
+ setfield(n,"transform",line)
+ end
+ if direction then
+ setdirection(n,direction)
end
return n
end
@@ -399,13 +422,32 @@ function nutpool.leader(width,list)
return n
end
-function nutpool.latelua(code)
- local n = copy_nut(latelua)
- setfield(n,"string",code)
- return n
+function nutpool.savepos()
+ return copy_nut(savepos)
end
-nutpool.lateluafunction = nutpool.latelua
+if CONTEXTLMTXMODE > 1 then
+
+ function nutpool.latelua(code)
+ local n = copy_nut(latelua)
+ nodeproperties[n] = { data = code }
+ return n
+ end
+
+else
+
+ function nutpool.latelua(code)
+ local n = copy_nut(latelua)
+ if type(code) == "table" then
+ local action = code.action
+ local specification = code.specification or code
+ code = function() action(specification) end
+ end
+ setdata(n,code)
+ return n
+ end
+
+end
function nutpool.leftmarginkern(glyph,width)
local n = copy_nut(left_margin_kern)
@@ -494,86 +536,21 @@ function nodepool.vlist(list,width,height,depth,shift)
return tonode(new_vlist(list and tonut(list),width,height,depth,shift))
end
--- local num = userids["my id"]
--- local str = userids[num]
-
-function nutpool.usernumber(id,num)
- local n = copy_nut(user_number)
- if num then
- setfield(n,"user_id",id)
- setfield(n,"value",num)
- elseif id then
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.userlist(id,list)
- local n = copy_nut(user_nodes)
- if list then
- setfield(n,"user_id",id)
- setfield(n,"value",list)
- else
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.userstring(id,str)
- local n = copy_nut(user_string)
- if str then
- setfield(n,"user_id",id)
- setfield(n,"value",str)
- else
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.usertokens(id,tokens)
- local n = copy_nut(user_tokens)
- if tokens then
- setfield(n,"user_id",id)
- setfield(n,"value",tokens)
- else
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.userlua(id,code)
- local n = copy_nut(user_lua)
- if code then
- setfield(n,"user_id",id)
- setfield(n,"value",code)
- else
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.userattributes(id,attr)
- local n = copy_nut(user_attributes)
- if attr then
- setfield(n,"user_id",id)
- setfield(n,"value",attr)
- else
- setfield(n,"value",id)
- end
- return n
-end
-
-function nutpool.special(str)
- local n = copy_nut(special)
- setfield(n,"data",str)
+function nutpool.usernode(id,data)
+ local n = copy_nut(user_node)
+ nodeproperties[n] = {
+ id = id,
+ data = data,
+ }
return n
end
-- housekeeping
local function cleanup(nofboxes) -- todo
- if nodes.tracers.steppers then -- to be resolved
- nodes.tracers.steppers.reset() -- todo: make a registration subsystem
+ local tracers = nodes.tracers
+ if tracers and tracers.steppers then -- to be resolved
+ tracers.steppers.reset() -- todo: make a registration subsystem
end
local nl = 0
local nr = nofreserved
@@ -624,3 +601,45 @@ statistics.register("node memory usage", function() -- comes after cleanup !
end)
lua.registerfinalizer(cleanup, "cleanup reserved nodes")
+
+-- experiment
+
+do
+
+ local glyph = tonode(glyph)
+ local traverse_id = nodes.traverse_id
+
+ local traversers = table.setmetatableindex(function(t,k)
+ local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph)
+ t[k] = v
+ return v
+ end)
+
+ traversers.node = nodes.traverse (glyph)
+ traversers.char = nodes.traverse_char (glyph)
+ if nuts.traverse_glyph then traversers.glyph = nodes.traverse_glyph(glyph) end
+ if nuts.traverse_list then traversers.list = nodes.traverse_list (glyph) end
+
+ nodes.traversers = traversers
+
+end
+
+do
+
+ local glyph = glyph
+ local traverse_id = nuts.traverse_id
+
+ local traversers = table.setmetatableindex(function(t,k)
+ local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph)
+ t[k] = v
+ return v
+ end)
+
+ traversers.node = nuts.traverse (glyph)
+ traversers.char = nuts.traverse_char (glyph)
+ if nuts.traverse_glyph then traversers.glyph = nuts.traverse_glyph(glyph) end
+ if nuts.traverse_list then traversers.list = nuts.traverse_list (glyph) end
+
+ nuts.traversers = traversers
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua b/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua
index 2b0368c2bc5..ea0e5c7a0c8 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua
@@ -37,18 +37,20 @@ local setlink = nuts.setlink
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local getattr = nuts.getattr
local setattr = nuts.setattr
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
local setwhd = nuts.setwhd
-local setdir = nuts.setdir
local setattrlist = nuts.setattrlist
local setshift = nuts.setshift
local getwidth = nuts.getwidth
local setwidth = nuts.setwidth
+local setfield = nuts.setfield
+
+local isglyph = nuts.isglyph
local flushlist = nuts.flush_list
local effective_glue = nuts.effective_glue
@@ -56,17 +58,16 @@ local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local find_tail = nuts.tail
local setglue = nuts.setglue
-local traverse_id = nuts.traverse_id
-local list_dimensions = nuts.rangedimensions
+local getrangedimensions = nuts.rangedimensions
local hpack_nodes = nuts.hpack
-local current_attr = nuts.current_attr
local copy_list = nuts.copy_list
+local nexthlist = nuts.traversers.hlist
+
local nodecodes = nodes.nodecodes
local rulecodes = nodes.rulecodes
local gluecodes = nodes.gluecodes
local listcodes = nodes.listcodes
-local kerncodes = nodes.kerncodes
local glyph_code = nodecodes.glyph
local localpar_code = nodecodes.localpar
@@ -74,8 +75,8 @@ local dir_code = nodecodes.dir
local glue_code = nodecodes.glue
local hlist_code = nodecodes.hlist
-local indent_code = listcodes.indent
-local line_code = listcodes.line
+local indentlist_code = listcodes.indent
+local linelist_code = listcodes.line
local leftskip_code = gluecodes.leftskip
local rightskip_code = gluecodes.rightskip
@@ -121,8 +122,8 @@ local setmetatableindex = table.setmetatableindex
--
-local striprange = nodes.striprange
-local processwords = nodes.processwords
+local striprange = nuts.striprange
+local processwords = nuts.processwords
--
@@ -144,7 +145,7 @@ local function usernutrule(t,noattributes)
if noattributes == false or noattributes == nil then
-- avoid fuzzy ones
else
- setattrlist(r,current_attr())
+ setattrlist(r,true)
end
properties[r] = t
return r
@@ -156,9 +157,11 @@ local function userrule(t,noattributes)
return tonode(usernutrule(t,noattributes))
end
-rules.userrule = userrule
-local ruleactions = { }
-rules.ruleactions = ruleactions
+rules.userrule = userrule
+local ruleactions = { }
+
+rules .ruleactions = ruleactions
+nutrules.ruleactions = ruleactions -- convenient
local function mathradical(n,h,v)
----- size = getfield(n,"index")
@@ -203,18 +206,18 @@ local subtypeactions = {
[rulecodes.radical] = mathradical,
}
-callbacks.register(
- "process_rule",
- function(n,h,v)
- local n = tonut(n)
- local s = getsubtype(n)
- local a = subtypeactions[s]
- if a then
- a(n,h,v)
- end
- end,
- "handle additional user rule features"
-)
+local function process_rule(n,h,v)
+ local n = tonut(n)
+ local s = getsubtype(n)
+ local a = subtypeactions[s]
+ if a then
+ a(n,h,v)
+ end
+end
+
+callbacks.register("process_rule",process_rule,"handle additional user rule features")
+
+callbacks.functions.process_rule = process_rule
--
@@ -239,9 +242,9 @@ end
local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose
local font = nil
- local id = getid(f)
- if id == glyph_code then
- font = getfont(f)
+ local char, id = isglyph(f)
+ if char then
+ font = id
elseif id == hlist_code then
font = getattr(f,a_runningtext)
end
@@ -263,7 +266,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
if not f then
return head
end
- local w, ht, dp = list_dimensions(parent,f,getnext(l))
+ local w, ht, dp = getrangedimensions(parent,f,getnext(l))
local method = d.method
local empty = d.empty == v_yes
local offset = d.offset
@@ -331,7 +334,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
end
end
if mp and mp ~= "" then
- local r = userrule {
+ local r = usernutrule {
width = w,
height = ht,
depth = dp,
@@ -344,16 +347,17 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
ca = color,
ta = transparency,
}
- inject(tonut(r),w,ht,dp)
+ inject(r,w,ht,dp)
else
local tx = d.text
if tx then
- tx = copy_list(tx)
+ local l = copy_list(tx)
if d["repeat"] == v_yes then
- tx = new_leader(w,tx)
+ l = new_leader(w,l)
+ setattrlist(l,tx)
end
- local r = hpack_nodes(tx,w,"exactly")
- inject(r,w,ht,dp)
+ l = hpack_nodes(l,w,"exactly")
+ inject(l,w,ht,dp)
else
for i=1,level do
local ht = (offset+(i-1)*dy)*e + rulethickness - m
@@ -373,10 +377,8 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
return head
end
-local process = nodes.processwords
-
rules.handler = function(head)
- return process(a_ruled,data,flush_ruled,head)
+ return processwords(a_ruled,data,flush_ruled,head)
end
function rules.enable()
@@ -409,7 +411,7 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha
local next = getnext(last)
setprev(first)
setnext(last)
- local width, height, depth = list_dimensions(parent,first,next)
+ local width, height, depth = getrangedimensions(parent,first,next)
local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack
if first == head then
head = list
@@ -429,9 +431,9 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha
return head
end
-local process = nodes.processwords
-
-nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end
+nodes.shifts.handler = function(head)
+ return processwords(a_shifted,data,flush_shifted,head)
+end
function nodes.shifts.enable()
enableaction("shipouts","nodes.shifts.handler")
@@ -459,7 +461,7 @@ local function linefiller(current,data,width,location)
local ca = data.ca
local ta = data.ta
if mp and mp ~= "" then
- return tonut(userrule {
+ return usernutrule {
width = width,
height = height,
depth = depth,
@@ -470,18 +472,56 @@ local function linefiller(current,data,width,location)
ca = ca,
ta = ta,
option = location,
- direction = getdir(current),
- })
+ direction = getdirection(current),
+ }
else
- local linefiller = new_rule(width,height,depth)
+ local rule = new_rule(width,height,depth)
if ca then
- setattr(linefiller,a_colorspace,ma)
- setattr(linefiller,a_color,ca)
+ setattr(rule,a_colorspace,ma)
+ setattr(rule,a_color,ca)
end
if ta then
- setattr(linefiller,a_transparency,ta)
+ setattr(rule,a_transparency,ta)
+ end
+ return rule
+ end
+end
+
+function nodes.linefillers.filler(current,data,width,height,depth)
+ if width and width > 0 then
+ local height = height or data.height or 0
+ local depth = depth or data.depth or 0
+ if (height + depth) ~= 0 then
+ local mp = data.mp
+ local ma = data.ma
+ local ca = data.ca
+ local ta = data.ta
+ if mp and mp ~= "" then
+ return usernutrule {
+ width = width,
+ height = height,
+ depth = depth,
+ type = "mp",
+ line = data.rulethickness,
+ data = mp,
+ ma = ma,
+ ca = ca,
+ ta = ta,
+ option = location,
+ direction = getdirection(current),
+ }
+ else
+ local rule = new_rule(width,height,depth)
+ if ca then
+ setattr(rule,a_colorspace,ma)
+ setattr(rule,a_color,ca)
+ end
+ if ta then
+ setattr(rule,a_transparency,ta)
+ end
+ return rule
+ end
end
- return linefiller
end
end
@@ -496,119 +536,115 @@ local function find_attr(head,attr)
end
function nodes.linefillers.handler(head)
--- local current = tonut(head) -- when we hook into the contributers
- for current in traverse_id(hlist_code,tonut(head)) do
- if getsubtype(current) == line_code then
- local list = getlist(current)
- if list then
- -- why doesn't leftskip take the attributes
- -- or list[linefiller] or maybe first match (maybe we need a fast helper for that)
- local a = getattr(current,a_linefiller)
- if a then
- local class = a % 1000
- local data = data[class]
- if data then
- local location = data.location
- local scope = data.scope
- local distance = data.distance
- local threshold = data.threshold
- local leftlocal = false
- local rightlocal = false
- --
- if scope == v_right then
- leftlocal = true
- elseif scope == v_left then
- rightlocal = true
- elseif scope == v_local then
- leftlocal = true
- rightlocal = true
- end
- --
- if location == v_left or location == v_both then
- local lskip = nil -- leftskip
- local iskip = nil -- indentation
- local head = list
- while head do
- local id = getid(head)
- if id == glue_code then
- if getsubtype(head) == leftskip_code then
- lskip = head
- else
- break
- end
- elseif id == localpar_code or id == dir_code then
- -- go on
- elseif id == hlist_code then
- if getsubtype(head) == indent_code then
- iskip = head
- end
- break
+ for current, subtype, list in nexthlist, head do
+ if list and subtype == linelist_code then
+ -- why doesn't leftskip take the attributes
+ -- or list[linefiller] or maybe first match (maybe we need a fast helper for that)
+ local a = getattr(current,a_linefiller)
+ if a then
+ local class = a % 1000
+ local data = data[class]
+ if data then
+ local location = data.location
+ local scope = data.scope
+ local distance = data.distance
+ local threshold = data.threshold
+ local leftlocal = false
+ local rightlocal = false
+ --
+ if scope == v_right then
+ leftlocal = true
+ elseif scope == v_left then
+ rightlocal = true
+ elseif scope == v_local then
+ leftlocal = true
+ rightlocal = true
+ end
+ --
+ if location == v_left or location == v_both then
+ local lskip = nil -- leftskip
+ local iskip = nil -- indentation
+ local head = list
+ while head do
+ local id = getid(head)
+ if id == glue_code then
+ if getsubtype(head) == leftskip_code then
+ lskip = head
else
break
end
- head = getnext(head)
+ elseif id == localpar_code or id == dir_code then
+ -- go on
+ elseif id == hlist_code then
+ if getsubtype(head) == indentlist_code then
+ iskip = head
+ end
+ break
+ else
+ break
end
- if head then
- local indentation = iskip and getwidth(iskip) or 0
- local leftfixed = lskip and getwidth(lskip) or 0
- local lefttotal = lskip and effective_glue(lskip,current) or 0
- local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance
- if width > threshold then
- if iskip then
- setwidth(iskip,0)
+ head = getnext(head)
+ end
+ if head then
+ local indentation = iskip and getwidth(iskip) or 0
+ local leftfixed = lskip and getwidth(lskip) or 0
+ local lefttotal = lskip and effective_glue(lskip,current) or 0
+ local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance
+ if width > threshold then
+ if iskip then
+ setwidth(iskip,0)
+ end
+ if lskip then
+ setglue(lskip,leftlocal and getwidth(lskip) or nil)
+ if distance > 0 then
+ insert_node_after(list,lskip,new_kern(distance))
end
- if lskip then
- setglue(lskip,leftlocal and getwidth(lskip) or nil)
- if distance > 0 then
- insert_node_after(list,lskip,new_kern(distance))
- end
- insert_node_after(list,lskip,linefiller(current,data,width,"left"))
- else
- insert_node_before(list,head,linefiller(current,data,width,"left"))
- if distance > 0 then
- insert_node_before(list,head,new_kern(distance))
- end
+ insert_node_after(list,lskip,linefiller(current,data,width,"left"))
+ else
+ insert_node_before(list,head,linefiller(current,data,width,"left"))
+ if distance > 0 then
+ insert_node_before(list,head,new_kern(distance))
end
end
end
end
- --
- if location == v_right or location == v_both then
- local pskip = nil -- parfillskip
- local rskip = nil -- rightskip
- local tail = find_tail(list)
- while tail and getid(tail) == glue_code do
- local subtype = getsubtype(tail)
- if subtype == rightskip_code then
- rskip = tail
- elseif subtype == parfillskip_code then
- pskip = tail
- else
- break
- end
- tail = getprev(tail)
+ end
+ --
+ if location == v_right or location == v_both then
+ local pskip = nil -- parfillskip
+ local rskip = nil -- rightskip
+ local tail = find_tail(list)
+ while tail and getid(tail) == glue_code do
+ local subtype = getsubtype(tail)
+ if subtype == rightskip_code then
+ rskip = tail
+ elseif subtype == parfillskip_code then
+ pskip = tail
+ else
+ break
end
- if tail then
- local rightfixed = rskip and getwidth(rskip) or 0
- local righttotal = rskip and effective_glue(rskip,current) or 0
- local parfixed = pskip and getwidth(pskip) or 0
- local partotal = pskip and effective_glue(pskip,current) or 0
- local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance
- if width > threshold then
- if pskip then
- setglue(pskip)
+ tail = getprev(tail)
+ end
+ if tail then
+ local rightfixed = rskip and getwidth(rskip) or 0
+ local righttotal = rskip and effective_glue(rskip,current) or 0
+ local parfixed = pskip and getwidth(pskip) or 0
+ local partotal = pskip and effective_glue(pskip,current) or 0
+ local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance
+ if width > threshold then
+ if pskip then
+ setglue(pskip)
+ end
+ if rskip then
+ setglue(rskip,rightlocal and getwidth(rskip) or nil)
+ if distance > 0 then
+ insert_node_before(list,rskip,new_kern(distance))
end
- if rskip then
- setglue(rskip,rightlocal and getwidth(rskip) or nil)
- if distance > 0 then
- insert_node_before(list,rskip,new_kern(distance))
- end
- insert_node_before(list,rskip,linefiller(current,data,width,"right"))
- else
- insert_node_after(list,tail,linefiller(current,data,width,"right"))
- if distance > 0 then
- insert_node_after(list,tail,new_kern(distance))
- end
+ insert_node_before(list,rskip,linefiller(current,data,width,"right"))
+ else
+ insert_node_after(list,tail,linefiller(current,data,width,"right"))
+ if distance > 0 then
+ insert_node_after(list,tail,new_kern(distance))
end
end
end
@@ -708,3 +744,35 @@ implement {
onlyonce = true,
actions = nodes.linefillers.enable
}
+
+-- We add a bonus feature here:
+
+interfaces.implement {
+ name = "autorule",
+ arguments = {
+ {
+ { "width", "dimension" },
+ { "height", "dimension" },
+ { "depth", "dimension" },
+ { "left", "dimension" },
+ { "right", "dimension" },
+ },
+ },
+ actions = function(t)
+ local l = t.left
+ local r = t.right
+ local n = new_rule(
+ t.width,
+ t.height,
+ t.depth
+ )
+ setattrlist(n,true)
+ if l then
+ setfield(n,"left",l)
+ end
+ if r then
+ setfield(n,"right",r)
+ end
+ context(tonode(n))
+ end
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-rul.mkiv b/Master/texmf-dist/tex/context/base/mkiv/node-rul.mkiv
index 643e93c428d..19f398eb900 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-rul.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-rul.mkiv
@@ -71,7 +71,7 @@
%definesystemattribute[ruled]
%definesystemattribute[shifted]
-\registerctxluafile{node-rul}{}
+\registerctxluafile{node-rul}{optimize}
\installcorenamespace{bar}
\installcorenamespace{barindex}
@@ -146,6 +146,8 @@
{\node_rules_set{#1}\barparameter\c!left}%
{\relax\barparameter\c!right}}
+% store in properties
+
\unexpanded\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings)
{\edef\currentbar{#1}%
\usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
@@ -571,4 +573,39 @@
\c!distance=.25\emwidth,
\c!rulethickness=.25\exheight]
+%D Bonus:
+%D
+%D \starttyping
+%D \startuseMPgraphic{foo}
+%D fill unitsquare
+%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+%D shifted (-ExHeight/8,ExHeight/16)
+%D withcolor RuleColor ;
+%D \stopuseMPgraphic
+%D
+%D \definelinefiller[foo][mp=foo,color=darkred]
+%D
+%D \linefillerhbox[foo]{OEPS}
+%D \stoptyping
+
+\unexpanded\def\node_backgrounds_filler_box#1#2[#3]%
+ {\bgroup
+ \clf_enablebackgroundboxes
+ \dowithnextbox{%
+ \node_linefiller_set{#3}% already sets the attribute
+ #1%
+ attr \backgroundattribute \plusone
+ % attr \linefillerattribute \the\attribute\linefillerattribute
+ {\box\nextbox}%
+ \egroup}%
+ #2}
+
+\unexpanded\def\linefillerhbox{\node_backgrounds_filler_box\hpack\hbox}
+\unexpanded\def\linefillervbox{\node_backgrounds_filler_box\vpack\vbox}
+\unexpanded\def\linefillervtop{\node_backgrounds_filler_box\tpack\vtop}
+
+%D Bonus:
+
+\unexpanded\def\autorule{\clf_autorule}
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-scn.lua b/Master/texmf-dist/tex/context/base/mkiv/node-scn.lua
index b294b30131d..a40a5271a9e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-scn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-scn.lua
@@ -12,8 +12,6 @@ local attributes = attributes
local nodes = nodes
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -26,9 +24,8 @@ local setlist = nuts.setlist
local end_of_math = nuts.end_of_math
local nodecodes = nodes.nodecodes
-local rulecodes = nodes.rulecodes
+local leadercodes = nodes.leadercodes
local gluecodes = nodes.gluecodes
-local listcodes = nodes.listcodes
local kerncodes = nodes.kerncodes
local glyph_code = nodecodes.glyph
@@ -46,7 +43,8 @@ local vlist_code = nodecodes.vlist
local userskip_code = gluecodes.userskip
local spaceskip_code = gluecodes.spaceskip
local xspaceskip_code = gluecodes.xspaceskip
-local leader_code = gluecodes.leaders
+
+local leaders_code = leadercodes.leaders
local fontkern_code = kerncodes.fontkern
@@ -97,7 +95,7 @@ local function striprange(first,last) -- todo: dir
return first, last
end
-nodes.striprange = striprange
+nuts.striprange = striprange
-- todo: order and maybe other dimensions
@@ -205,7 +203,7 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl
elseif id == glue_code then
-- catch \underbar{a} \underbar{a} (subtype test is needed)
local subtype = getsubtype(n)
- if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) then
+ if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leaders_code)) then
l = n
else
head, done = flush(head,f,l,d,level,parent,strip), true
@@ -228,17 +226,11 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl
end
end
-nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir
- head = tonut(head)
- if parent then
- parent = tonut(parent)
- end
- local head, done = processwords(attribute,data,flush,head,parent)
- return tonode(head), done
+nuts.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir
+ return processwords(attribute,data,flush,head,parent)
end
-- works on lines !
-
-- todo: stack because skip can change when nested
local function processranges(attribute,flush,head,parent,depth,skip)
@@ -319,11 +311,6 @@ local function processranges(attribute,flush,head,parent,depth,skip)
end
end
-nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir
- head = tonut(head)
- if parent then
- parent = tonut(parent)
- end
- local head, done = processranges(attribute,flush,head,parent,0)
- return tonode(head), done
+nuts.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir
+ return processranges(attribute,flush,head,parent,0)
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ser.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ser.lua
index 7ed2b8d00d8..6fc2b7ea4cf 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ser.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ser.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['node-ser'] = {
-- beware, some field names will change in a next releases
-- of luatex; this is pretty old code that needs an overhaul
-local type = type
+local type, tostring = type, tostring
local concat, tohash, sortedkeys, printtable, serialize = table.concat, table.tohash, table.sortedkeys, table.print, table.serialize
local formatters, format, rep = string.formatters, string.format, string.rep
@@ -24,16 +24,17 @@ local is_node = nodes.is_node
local nodecodes = nodes.nodecodes
local subtcodes = nodes.codes
-local noadcodes = nodes.noadcodes
local getfields = nodes.fields
local tonode = nodes.tonode
+local tonut = nodes.tonut
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
----- utfchar = utf.char
local f_char = formatters["%U"]
+local f_attr = formatters["<%i>"]
----- fontchars = { } table.setmetatableindex(fontchars,function(t,k) fontchars = fonts.hashes.characters return fontchars[k] end)
----- f_char = utilities.strings.chkuni -- formatters["%!chkuni!"]
@@ -87,7 +88,7 @@ local ignore = allocate ( tohash {
local dimension = allocate ( tohash {
"width", "height", "depth", "shift",
"stretch", "shrink",
- "xoffset", "yoffset", "xadvance",
+ "xoffset", "yoffset",
"surround",
"kern",
"box_left_width", "box_right_width"
@@ -145,6 +146,7 @@ local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true
if ignore[v] then
-- skip
elseif noattributes and v == "attr" then
+ tt[v] = f_attr(tonut(nv))
-- skip
elseif v == "prev" then
tt[v] = ""
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-shp.lua b/Master/texmf-dist/tex/context/base/mkiv/node-shp.lua
index 2e7a3529a54..306e38f6a58 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-shp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-shp.lua
@@ -13,50 +13,51 @@ local format = string.format
local concat, sortedpairs = table.concat, table.sortedpairs
local setmetatableindex = table.setmetatableindex
-local nodecodes = nodes.nodecodes
-local whatsitcodes = nodes.whatsitcodes
-local disccodes = nodes.disccodes
+local nodecodes = nodes.nodecodes
+local whatsitcodes = nodes.whatsitcodes
+local disccodes = nodes.disccodes
-local tasks = nodes.tasks
-local handlers = nodes.handlers
+local tasks = nodes.tasks
+local handlers = nodes.handlers
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local disc_code = nodecodes.disc
-local whatsit_code = nodecodes.whatsit
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local disc_code = nodecodes.disc
+local whatsit_code = nodecodes.whatsit
-local fulldisc_code = disccodes.discretionary
+local discretionarydisc_code = disccodes.discretionary
-local texgetbox = tex.getbox
+local implement = interfaces.implement
-local implement = interfaces.implement
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+local remove_node = nuts.remove
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-local remove_node = nuts.remove
-local traverse_nodes = nuts.traverse
+local nextnode = nuts.traversers.node
-local setfield = nuts.setfield
-local setlink = nuts.setlink
-local setprev = nuts.setprev
-local setnext = nuts.setnext
-local getid = nuts.getid
-local getdisc = nuts.getdisc
-local getboth = nuts.getboth
-local getnext = nuts.getnext
-local getlist = nuts.getlist
-local getsubtype = nuts.getsubtype
+local setfield = nuts.setfield
+local setlink = nuts.setlink
+local setprev = nuts.setprev
+local setnext = nuts.setnext
+local getid = nuts.getid
+local getdisc = nuts.getdisc
+local getboth = nuts.getboth
+local getnext = nuts.getnext
+local getlist = nuts.getlist
+local getsubtype = nuts.getsubtype
-local setlist = nuts.setlist
+local setlist = nuts.setlist
-local removables = {
+local getbox = nuts.getbox
+
+local removables = {
[whatsitcodes.open] = true,
[whatsitcodes.close] = true,
[whatsitcodes.write] = true,
[whatsitcodes.savepos] = true,
[whatsitcodes.latelua] = true,
- [whatsitcodes.pdfdest] = true,
+ -- [whatsitcodes.pdfdest] = true,
}
-- About 10% of the nodes make no sense for the backend. By (at least)
@@ -72,7 +73,7 @@ local function cleanup_redundant(head) -- better name is: flatten_page
while start do
local id = getid(start)
if id == disc_code then
- if getsubtype(start) == fulldisc_code then
+ if getsubtype(start) == discretionarydisc_code then
local _, _, replace, _, _ tail = getdisc(start,true)
if replace then
local prev, next = getboth(start)
@@ -117,6 +118,8 @@ local function cleanup_redundant(head) -- better name is: flatten_page
return head
end
+handlers.cleanuppage = cleanup_redundant -- nut
+
local function cleanup_flushed(head) -- rough
local start = head
while start do
@@ -143,26 +146,20 @@ local function cleanup_flushed(head) -- rough
return head
end
-function handlers.cleanuppage(head)
- return tonode(cleanup_redundant(tonut(head))), true
-end
-
-function handlers.cleanupbox(head)
- return tonode(cleanup_flushed(tonut(head))), true
+function handlers.cleanupbox(box)
+ cleanup_flushed(getbox(box))
end
local actions = tasks.actions("shipouts")
-function handlers.finalize(head,where) -- problem, attr loaded before node, todo ...
- return actions(head,where)
+function handlers.finalizebox(box)
+ actions(getbox(box)) -- nut
end
--- handlers.finalize = actions
-
-- interface
-implement { name = "cleanupbox", actions = { texgetbox, cleanup_flushed }, arguments = "integer" }
-implement { name = "finalizebox", actions = { texgetbox, actions }, arguments = "integer" }
+implement { name = "cleanupbox", actions = handlers.cleanupbox, arguments = "integer" }
+implement { name = "finalizebox", actions = handlers.finalizebox, arguments = "integer" }
-- just in case we want to optimize lookups:
@@ -192,8 +189,7 @@ local function count(head,data,subcategory)
-- no components, pre, post, replace .. can maybe an option .. but
-- we use this for optimization so it makes sense to look the the
-- main node only
- for n in traverse_nodes(tonut(head)) do
- local id = getid(n)
+ for n, id in nextnode, tonut(head) do
local dn = data[nodecodes[id]] -- we could use id and then later convert to nodecodes
dn[subcategory] = dn[subcategory] + 1
if id == hlist_code or id == vlist_code then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-syn.lua b/Master/texmf-dist/tex/context/base/mkiv/node-syn.lua
index 9d716c44a52..a00dc65ec53 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-syn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-syn.lua
@@ -24,7 +24,16 @@ if not modules then modules = { } end modules ['node-syn'] = {
-- I only tested SumatraPDF with SciTE, for which one needs to configure in the
-- viewer:
--
--- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $
+-- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $
+--
+-- In fact, a way more powerful implementation would have been not to add a library
+-- to a viewer, but letthe viewer call an external program:
+--
+-- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $
+--
+-- which would (re)launch the editor in the right spot. That way we can really
+-- tune well to the macro package used and also avoid the fuzzy heuristics of
+-- the library.
--
-- Unfortunately syntex always removes the files at the end and not at the start
-- (this happens in synctexterminate) so we need to work around that by using an
@@ -124,10 +133,9 @@ local openfile, renamefile, removefile = io.open, os.rename, os.remove
local report_system = logs.reporter("system")
local tex = tex
+local texget = tex.get
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getid = nuts.getid
local getlist = nuts.getlist
@@ -168,14 +176,9 @@ local set_synctex_tag = tex.set_synctex_tag
local force_synctex_tag = tex.force_synctex_tag
local force_synctex_line = tex.force_synctex_line
----- get_synctex_tag = tex.get_synctex_tag
------ get_synctex_line = tex.get_synctex_line
+local get_synctex_line = tex.get_synctex_line
local set_synctex_mode = tex.set_synctex_mode
-local getpos = function()
- getpos = backends.codeinjections.getpos
- return getpos()
- end
-
local foundintree = resolvers.foundintree
local eol = "\010"
@@ -199,6 +202,8 @@ local f_vlist_2 = formatters["v%i,%i:%i,%s:%i,%i,%i\010"]
local synctex = luatex.synctex or { }
luatex.synctex = synctex
+local getpos ; getpos = function() getpos = job.positions.getpos return getpos() end
+
-- status stuff
local enabled = false
@@ -268,6 +273,34 @@ function synctex.resetfilename()
end
end
+do
+
+ local nesting = 0
+ local ignored = false
+
+ function synctex.pushline()
+ nesting = nesting + 1
+ if nesting == 1 then
+ local l = get_synctex_line()
+ ignored = l and l > 0
+ if not ignored then
+ force_synctex_line(texget("inputlineno"))
+ end
+ end
+ end
+
+ function synctex.popline()
+ if nesting == 1 then
+ if not ignored then
+ force_synctex_line()
+ ignored = false
+ end
+ end
+ nesting = nesting - 1
+ end
+
+end
+
-- the node stuff
local filehandle = nil
@@ -324,6 +357,7 @@ end
function synctex.wrapup()
if tmpfile then
renamefile(tmpfile,logfile)
+ tmpfile = nil
end
end
@@ -340,9 +374,15 @@ local function flushpostamble()
enabled = false
end
+local getpagedimensions getpagedimensions = function()
+ getpagedimensions = backends.codeinjections.getpagedimensions
+ return getpagedimensions()
+end
+
-- local function doaction(action,t,l,w,h,d)
+-- local pagewidth, pageheight = getpagedimensions()
-- local x, y = getpos()
--- filehandle:write(action(t,l,x,tex.pageheight-y,w,h,d))
+-- filehandle:write(action(t,l,x,pageheight-y,w,h,d))
-- nofobjects = nofobjects + 1
-- end
--
@@ -378,24 +418,27 @@ end
-- generic
--
-- local function doaction(t,l,w,h,d)
+-- local pagewidth, pageheight = getpagedimensions()
-- local x, y = getpos()
--- filehandle:write(f_hlist_1(t,l,x,tex.pageheight-y,w,h,d))
+-- filehandle:write(f_hlist_1(t,l,x,pageheight-y,w,h,d))
-- nofobjects = nofobjects + 1
-- end
local x_hlist do
local function doaction_1(t,l,w,h,d)
+ local pagewidth, pageheight = getpagedimensions()
local x, y = getpos()
- filehandle:write(f_hlist_1(t,l,x,tex.pageheight-y,w,h,d))
+ filehandle:write(f_hlist_1(t,l,x,pageheight-y,w,h,d))
nofobjects = nofobjects + 1
end
-- local lastx, lasty, lastw, lasth, lastd
--
-- local function doaction_2(t,l,w,h,d)
+ -- local pagewidth, pageheight = getpagedimensions()
-- local x, y = getpos()
- -- y = tex.pageheight-y
+ -- y = pageheight-y
-- filehandle:write(f_hlist_2(t,l,
-- x == lastx and "=" or x,
-- y == lasty and "=" or y,
@@ -412,8 +455,9 @@ local x_hlist do
local lasty = false
local function doaction_2(t,l,w,h,d)
+ local pagewidth, pageheight = getpagedimensions()
local x, y = getpos()
- y = tex.pageheight - y
+ y = pageheight - y
filehandle:write(f_hlist_2(t,l,x,y == lasty and "=" or y,w,h,d))
lasty = y
nofobjects = nofobjects + 1
@@ -623,16 +667,10 @@ end
collect = collect_max
function synctex.collect(head,where)
- if enabled then
- if where == "object" then
- return head, false
- else
- local h = tonut(head)
- h = collect(h,h)
- return tonode(h), true
- end
+ if enabled and where ~= "object" then
+ return collect(head,head)
else
- return head, false
+ return head
end
end
@@ -645,10 +683,9 @@ function synctex.start()
writeanchor()
filehandle:write("{",nofsheets,eol)
-- this seems to work:
- local h = tex.pageheight
- local w = tex.pagewidth
+ local pagewidth, pageheight = getpagedimensions()
filehandle:write(z_hlist)
- filehandle:write(f_vlist_1(0,0,0,h,w,h,0))
+ filehandle:write(f_vlist_1(0,0,0,pageheight,pagewidth,pageheight,0))
end
end
end
@@ -678,7 +715,7 @@ function synctex.enable()
enabled = true
set_synctex_mode(3) -- we want details
if not used then
- nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect")
+ nodes.tasks.enableaction("shipouts","luatex.synctex.collect")
report_system("synctex functionality is enabled, expect 5-10 pct runtime overhead!")
used = true
end
@@ -786,11 +823,21 @@ implement {
}
implement {
- name = "synctexpause",
- actions = synctex.pause,
+ name = "synctexpause",
+ actions = synctex.pause,
}
implement {
- name = "synctexresume",
- actions = synctex.resume,
+ name = "synctexresume",
+ actions = synctex.resume,
+}
+
+interfaces.implement {
+ name = "synctexpushline",
+ actions = synctex.pushline,
+}
+interfaces.implement {
+ name = "synctexpopline",
+ actions = synctex.popline,
}
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-tex.lua b/Master/texmf-dist/tex/context/base/mkiv/node-tex.lua
index c9d3091df23..5857fd2e65b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-tex.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-tex.lua
@@ -6,33 +6,40 @@ if not modules then modules = { } end modules ['node-tex'] = {
license = "see context related readme files"
}
-builders = builders or { }
-local kernel = builders.kernel or { }
-builders.kernel = kernel
-
-local hyphenate = lang.hyphenate
-local ligaturing = node.ligaturing
-local kerning = node.kerning
-
-kernel.originals = {
- hyphenate = hyphenate,
- ligaturing = ligaturing,
- kerning = kerning,
-}
+builders = builders or { }
+local kernel = builders.kernel or { }
+builders.kernel = kernel
+
+local nuts = nodes.nuts
+
+local hyphenate = lang.hyphenate
+local hyphenating = nuts.hyphenating
+local ligaturing = nuts.ligaturing
+local kerning = nuts.kerning
+local cleanup = nuts.flush_components
function kernel.hyphenation(head)
- local done = hyphenate(head)
- return head, done
+ return (hyphenate(head)) -- nodes !
+end
+
+function kernel.hyphenating(head)
+ return (hyphenating(head))
end
function kernel.ligaturing(head)
- local head, tail, done = ligaturing(head) -- we return 3 values indeed
- return head, done
+ return (ligaturing(head))
end
function kernel.kerning(head)
- local head, tail, done = kerning(head) -- we return 3 values indeed
- return head, done
+ return (kerning(head))
+end
+
+if cleanup then
+
+ function kernel.cleanup(head)
+ return (cleanup(head))
+ end
+
end
callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-tra.lua b/Master/texmf-dist/tex/context/base/mkiv/node-tra.lua
index f1259986644..e1b6927fbce 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-tra.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-tra.lua
@@ -21,68 +21,67 @@ local report_nodes = logs.reporter("nodes","tracing")
local nodes, node, context = nodes, node, context
-local texgetattribute = tex.getattribute
-
-local tracers = nodes.tracers or { }
-nodes.tracers = tracers
-
-local tasks = nodes.tasks or { }
-nodes.tasks = tasks
-
-local handlers = nodes.handlers or {}
-nodes.handlers = handlers
-
-local injections = nodes.injections or { }
-nodes.injections = injections
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getchar = nuts.getchar
-local getsubtype = nuts.getsubtype
-local getlist = nuts.getlist
-local getdisc = nuts.getdisc
-local setattr = nuts.setattr
-local getglue = nuts.getglue
-local isglyph = nuts.isglyph
-local getcomponents = nuts.getcomponents
-local getdir = nuts.getdir
-local getwidth = nuts.getwidth
-
-local flush_list = nuts.flush_list
-local count_nodes = nuts.countall
-local used_nodes = nuts.usedlist
-
-local traverse_by_id = nuts.traverse_id
-local traverse_nodes = nuts.traverse
-local d_tostring = nuts.tostring
-
-local nutpool = nuts.pool
-local new_rule = nutpool.rule
-
-local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
-local skipcodes = nodes.skipcodes
-local fillcodes = nodes.fillcodes
-
-local glyph_code = nodecodes.glyph
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local disc_code = nodecodes.disc
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local rule_code = nodecodes.rule
-local dir_code = nodecodes.dir
-local localpar_code = nodecodes.localpar
-local whatsit_code = nodecodes.whatsit
-
-local dimenfactors = number.dimenfactors
-local fillorders = nodes.fillcodes
-local formatters = string.formatters
+local texgetattribute = tex.getattribute
+
+local tracers = nodes.tracers or { }
+nodes.tracers = tracers
+
+local tasks = nodes.tasks or { }
+nodes.tasks = tasks
+
+local handlers = nodes.handlers or {}
+nodes.handlers = handlers
+
+local injections = nodes.injections or { }
+nodes.injections = injections
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getlist = nuts.getlist
+local getdisc = nuts.getdisc
+local setattr = nuts.setattr
+local getglue = nuts.getglue
+local isglyph = nuts.isglyph
+local getdirection = nuts.getdirection
+local getwidth = nuts.getwidth
+
+local flush_list = nuts.flush_list
+local count_nodes = nuts.countall
+local used_nodes = nuts.usedlist
+
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
+
+local d_tostring = nuts.tostring
+
+local nutpool = nuts.pool
+local new_rule = nutpool.rule
+
+local nodecodes = nodes.nodecodes
+local whatsitcodes = nodes.whatsitcodes
+local fillcodes = nodes.fillcodes
+
+local subtypes = nodes.subtypes
+
+local glyph_code = nodecodes.glyph
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local disc_code = nodecodes.disc
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+local rule_code = nodecodes.rule
+local dir_code = nodecodes.dir
+local localpar_code = nodecodes.localpar
+local whatsit_code = nodecodes.whatsit
+
+local dimenfactors = number.dimenfactors
+local formatters = string.formatters
-- this will be reorganized:
@@ -90,23 +89,26 @@ function nodes.showlist(head, message)
if message then
report_nodes(message)
end
- for n in traverse_nodes(tonut(head)) do
+ for n in nextnode, tonut(head) do
report_nodes(d_tostring(n))
end
end
function nodes.handlers.checkglyphs(head,message)
- local h = tonut(head)
+ local h = tonut(head) -- tonut needed?
local t = { }
- for g in traverse_by_id(glyph_code,h) do
- t[#t+1] = formatters["%U:%s"](getchar(g),getsubtype(g))
+ local n = 0
+ local f = formatters["%U:%s"]
+ for g, char, font in nextglyph, h do
+ n = n + 1
+ t[n] = f(char,getsubtype(g))
end
- if #t > 0 then
- if message and message ~= "" then
- report_nodes("%s, %s glyphs: % t",message,#t,t)
- else
- report_nodes("%s glyphs: % t",#t,t)
- end
+ if n == 0 then
+ -- nothing to report
+ elseif message and message ~= "" then
+ report_nodes("%s, %s glyphs: % t",message,n,t)
+ else
+ report_nodes("%s glyphs: % t",n,t)
end
return false
end
@@ -114,8 +116,8 @@ end
function nodes.handlers.checkforleaks(sparse)
local l = { }
local q = used_nodes()
- for p in traverse_nodes(q) do
- local s = table.serialize(nodes.astable(p,sparse),nodecodes[getid(p)])
+ for p, id in nextnode, q do
+ local s = table.serialize(nodes.astable(p,sparse),nodecodes[id])
l[s] = (l[s] or 0) + 1
end
flush_list(q)
@@ -124,42 +126,51 @@ function nodes.handlers.checkforleaks(sparse)
end
end
-local f_sequence = formatters["U+%04X:%s"]
-local f_subrange = formatters["[[ %s ][ %s ][ %s ]]"]
+local fontcharacters -- = fonts.hashes.descriptions
local function tosequence(start,stop,compact)
if start then
+ if not fontcharacters then
+ fontcharacters = fonts.hashes.descriptions
+ if not fontcharacters then
+ return "[no char data]"
+ end
+ end
+ local f_sequence = formatters["U+%04X:%s"]
+ local f_subrange = formatters["[[ %s ][ %s ][ %s ]]"]
start = tonut(start)
stop = stop and tonut(stop)
local t = { }
+ local n = 0
while start do
local c, id = isglyph(start)
if c then
- if compact then
- local components = getcomponents(start)
- if components then
- t[#t+1] = tosequence(components,nil,compact)
- else
- t[#t+1] = utfchar(c)
+ local u = fontcharacters[id][c] -- id == font id
+ u = u and u.unicode or c
+ if type(u) == "table" then
+ local tt = { }
+ for i=1,#u do
+ local c = u[i]
+ tt[i] = compact and utfchar(c) or f_sequence(c,utfchar(c))
end
+ n = n + 1 ; t[n] = "(" .. concat(tt," ") .. ")"
else
- t[#t+1] = f_sequence(c,utfchar(c))
+ n = n + 1 ; t[n] = compact and utfchar(c) or f_sequence(c,utfchar(c))
end
elseif id == disc_code then
local pre, post, replace = getdisc(start)
t[#t+1] = f_subrange(pre and tosequence(pre),post and tosequence(post),replace and tosequence(replace))
elseif id == rule_code then
- if compact then
- t[#t+1] = "|"
- else
- t[#t+1] = nodecodes[id]
- end
- elseif id == dir_code or id == localpar_code then
- t[#t+1] = "[" .. getdir(start) .. "]"
+ n = n + 1 ; t[n] = compact and "|" or nodecodes[id] or "?"
+ elseif id == dir_code then
+ local d, p = getdirection(start)
+ n = n + 1 ; t[n] = "[<" .. (p and "-" or "+") .. d .. ">]" -- todo l2r etc
+ elseif id == localpar_code and getsubtype(start) == 0 then
+ n = n + 1 ; t[n] = "[<" .. getdirection(start) .. ">]" -- todo l2r etc
elseif compact then
- t[#t+1] = "[]"
+ n = n + 1 ; t[n] = "[]"
else
- t[#t+1] = nodecodes[id]
+ n = n + 1 ; t[n] = nodecodes[id]
end
if start == stop then
break
@@ -180,13 +191,13 @@ end
nodes.tosequence = tosequence
nuts .tosequence = tosequence
-function nodes.report(t,done)
- report_nodes("output %a, changed %a, %s nodes",status.output_active,done,count_nodes(tonut(t)))
+function nodes.report(t)
+ report_nodes("output %a, %s nodes",status.output_active,count_nodes(t))
end
function nodes.packlist(head)
local t = { }
- for n in traverse_nodes(tonut(head)) do
+ for n in nextnode, tonut(head) do
t[#t+1] = d_tostring(n)
end
return t
@@ -198,10 +209,11 @@ function nodes.idstostring(head,tail)
local t = { }
local last_id = nil
local last_n = 0
- for n in traverse_nodes(head,tail) do -- hm, does not stop at tail
- local id = getid(n)
+ local f_two = formatters["[%s*%s]"]
+ local f_one = formatters["[%s]"]
+ for n, id, subtype in nextnode, head do
if id == whatsit_code then
- id = whatcodes[getsubtype(n)]
+ id = whatsitcodes[subtype]
else
id = nodecodes[id]
end
@@ -212,9 +224,9 @@ function nodes.idstostring(head,tail)
last_n = last_n + 1
else
if last_n > 1 then
- t[#t+1] = formatters["[%s*%s]"](last_n,last_id)
+ t[#t+1] = f_two(last_n,last_id)
else
- t[#t+1] = formatters["[%s]"](last_id)
+ t[#t+1] = f_one(last_id)
end
last_id = id
last_n = 1
@@ -227,14 +239,29 @@ function nodes.idstostring(head,tail)
t[#t+1] = "no nodes"
else
if last_n > 1 then
- t[#t+1] = formatters["[%s*%s]"](last_n,last_id)
+ t[#t+1] = f_two(last_n,last_id)
else
- t[#t+1] = formatters["[%s]"](last_id)
+ t[#t+1] = f_one(last_id)
end
end
return concat(t," ")
end
+function nodes.idsandsubtypes(head)
+ local h = tonut(head)
+ local t = { }
+ local f = formatters["%s:%s"]
+ for n, id, subtype in nextnode, h do
+ local c = nodecodes[id]
+ if subtype then
+ t[#t+1] = f(c,subtypes[id][subtype])
+ else
+ t[#t+1] = c
+ end
+ end
+ return concat(t, " ")
+end
+
-- function nodes.xidstostring(head,tail) -- only for special tracing of backlinks
-- head = tonut(head)
-- tail = tonut(tail)
@@ -299,17 +326,19 @@ nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end
local function listtoutf(h,joiner,textonly,last,nodisc)
local w = { }
local n = 0
+ local g = formatters["<%i>"]
+ local d = formatters["[%s|%s|%s]"]
while h do
local c, id = isglyph(h)
if c then
- n = n + 1 ; w[n] = c >= 0 and utfchar(c) or formatters["<%i>"](c)
+ n = n + 1 ; w[n] = c >= 0 and utfchar(c) or g(c)
if joiner then
n = n + 1 ; w[n] = joiner
end
elseif id == disc_code then
local pre, pos, rep = getdisc(h)
if not nodisc then
- n = n + 1 ; w[n] = formatters["[%s|%s|%s]"] (
+ n = n + 1 ; w[n] = d(
pre and listtoutf(pre,joiner,textonly) or "",
pos and listtoutf(pos,joiner,textonly) or "",
rep and listtoutf(rep,joiner,textonly) or ""
@@ -354,11 +383,9 @@ local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" }
local function showboxes(n,symbol,depth)
depth = depth or 0
symbol = symbol or "."
- for n in traverse_nodes(tonut(n)) do
- local id = getid(n)
+ for n, id, subtype in nextnode, tonut(n) do
if id == hlist_code or id == vlist_code then
- local s = getsubtype(n)
- report_nodes(rep(symbol,depth) .. what[s] or s)
+ report_nodes(rep(symbol,depth) .. what[subtype] or subtype)
showboxes(getlist(n),symbol,depth+1)
end
end
@@ -401,17 +428,17 @@ local function nodetodimen(n)
width = width / 65536
if stretch_order ~= 0 then
if shrink_order ~= 0 then
- return f_f_f(width,stretch,fillorders[stretch_order],shrink,fillorders[shrink_order])
+ return f_f_f(width,stretch,fillcodes[stretch_order],shrink,fillcodes[shrink_order])
elseif shrink ~= 0 then
- return f_f_m(width,stretch,fillorders[stretch_order],shrink)
+ return f_f_m(width,stretch,fillcodes[stretch_order],shrink)
else
- return f_f_z(width,stretch,fillorders[stretch_order])
+ return f_f_z(width,stretch,fillcodes[stretch_order])
end
elseif shrink_order ~= 0 then
if stretch ~= 0 then
- return f_p_f(width,stretch,shrink,fillorders[shrink_order])
+ return f_p_f(width,stretch,shrink,fillcodes[shrink_order])
else
- return f_z_f(width,shrink,fillorders[shrink_order])
+ return f_z_f(width,shrink,fillcodes[shrink_order])
end
elseif stretch ~= 0 then
if shrink ~= 0 then
@@ -631,6 +658,9 @@ end
tracers.setproperties = setproperties
+-- setting attrlist entries instead of attr for successive entries doesn't
+-- speed up much (this function is only used in tracers anyway)
+
function tracers.setlist(n,c,s)
local nn = tonut(n)
local mc = m_color[c]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-tsk.lua b/Master/texmf-dist/tex/context/base/mkiv/node-tsk.lua
index 1ce7ab1dc85..0378c14c62a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-tsk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-tsk.lua
@@ -52,19 +52,21 @@ end
function tasks.new(specification) -- was: name,arguments,list
local name = specification.name
- local arguments = specification.arguments or 0
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,
- arguments = arguments,
- -- sequence = sequence,
frozen = { },
- processor = specification.processor or nodeprocessor
+ 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])
@@ -170,18 +172,26 @@ function tasks.disablegroup(name,group)
end
end
-function tasks.appendaction(name,group,action,where,kind)
+function tasks.appendaction(name,group,action,where,kind,state)
local data = validgroup(name,"append action")
if data then
- appendaction(data.list,group,action,where,kind)
+ 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)
+function tasks.prependaction(name,group,action,where,kind,state)
local data = validgroup(name,"prepend action")
if data then
- prependaction(data.list,group,action,where,kind)
+ 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
@@ -216,112 +226,29 @@ statistics.register("node list callback tasks", function()
end
end)
-function tasks.actions(name) -- we optimize for the number or arguments (no ...)
+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 n = data.arguments or 0
- if n == 0 then
- return function(head)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a",name)
- end
- runner = compile(data.list,data.processor,0)
- data.runner = runner
- end
- return runner(head)
- end
- elseif n == 1 then
- return function(head,one)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,1)
- end
- runner = compile(data.list,data.processor,1)
- data.runner = runner
- end
- return runner(head,one)
- end
- elseif n == 2 then
- return function(head,one,two)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,2)
- end
- runner = compile(data.list,data.processor,2)
- data.runner = runner
- end
- return runner(head,one,two)
- end
- elseif n == 3 then
- return function(head,one,two,three)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,3)
- end
- runner = compile(data.list,data.processor,3)
- data.runner = runner
- end
- return runner(head,one,two,three)
- end
- elseif n == 4 then
- return function(head,one,two,three,four)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,4)
- end
- runner = compile(data.list,data.processor,4)
- data.runner = runner
- end
- return runner(head,one,two,three,four)
- end
- elseif n == 5 then
- return function(head,one,two,three,four,five)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,5)
- end
- runner = compile(data.list,data.processor,5)
- data.runner = runner
- end
- return runner(head,one,two,three,four,five)
- end
- else
- return function(head,...)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,n)
- end
- runner = compile(data.list,data.processor,"n")
- data.runner = runner
- end
- return runner(head,...)
+ 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
- else
- return nil
end
+ return nil
end
function tasks.table(name) --maybe move this to task-deb.lua
@@ -351,12 +278,132 @@ function tasks.table(name) --maybe move this to task-deb.lua
end
end
--- this will move
+-- -- 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",
- arguments = 5, -- often only the first is used, and the last three are only passed in hpack filter
--- arguments = 2,
processor = nodeprocessor,
sequence = {
"before", -- for users
@@ -366,56 +413,297 @@ tasks.new {
"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",
- arguments = 1,
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
--- "characters",
--- "finishers",
"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 = "shipouts",
- arguments = 1,
- -- nostate = true, -- maybe but only for main ones so little gain
+ name = "mvlbuilders",
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
- "finishers",
"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 = "mvlbuilders",
- arguments = 1,
+ 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 = "vboxbuilders",
- arguments = 5,
+ 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%
+
+return function(head,groupcode,line)
+ local nuthead = tonut(head)
+ local nutline = tonut(line)
+
+%actions%
+ return tonode(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)
+]],
+
}
}
@@ -441,14 +729,69 @@ tasks.new {
-- }
-- }
-tasks.new {
- name = "contributers",
- arguments = 2, -- [head] where parent
- processor = nodeprocessor,
- sequence = {
- "before", -- for users
- "normalizers",
- "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/Master/texmf-dist/tex/context/base/mkiv/node-tst.lua b/Master/texmf-dist/tex/context/base/mkiv/node-tst.lua
index 7ad35bd711e..0dacff37532 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-tst.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-tst.lua
@@ -10,7 +10,7 @@ local nodes, node = nodes, node
local chardata = characters.data
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local glue_code = nodecodes.glue
local penalty_code = nodecodes.penalty
@@ -19,10 +19,10 @@ local glyph_code = nodecodes.glyph
local whatsit_code = nodecodes.whatsit
local hlist_code = nodecodes.hlist
-local leftskip_code = skipcodes.leftskip
-local rightskip_code = skipcodes.rightskip
-local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip
-local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip
+local leftskip_code = gluecodes.leftskip
+local rightskip_code = gluecodes.rightskip
+local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip
+local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip
local nuts = nodes.nuts
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-bar.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-bar.mkiv
index 06eeebd1411..b67d6f14b28 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-bar.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-bar.mkiv
@@ -72,16 +72,16 @@
\vskip\zeropoint\s!plus-\positionbarparameter\c!n \s!fill}}
\unexpanded\def\horizontalgrowingbar[#1]%
- {\hbox to \hsize
+ {\hpack to \hsize
{\setuppositionbar[#1]%
\usepositionbarstyleandcolor\c!style\c!color
- \leaders\vrule\hskip\zeropoint\s!plus \numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill
+ \leaders\vrule\hskip\zeropoint\s!plus\numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill
\vrule\s!width\zeropoint\s!height\positionbarparameter\c!height\s!depth\positionbarparameter\c!depth
\hskip\zeropoint\s!plus \positionbarparameter\c!max\s!fill
\hskip\zeropoint\s!plus-\positionbarparameter\c!n \s!fill}}
\unexpanded\def\verticalgrowingbar[#1]%
- {\vbox to \vsize
+ {\vpack to \vsize
{\setuppositionbar[#1]%
\usepositionbarstyleandcolor\c!style\c!color
\leaders\hrule\vskip\zeropoint\s!plus\numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-bck.mkvi b/Master/texmf-dist/tex/context/base/mkiv/pack-bck.mkvi
index 346e7df575e..9f9d843cef7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-bck.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-bck.mkvi
@@ -245,18 +245,42 @@
%D \macros
%D {backgroundline}
-\unexpanded\def\backgroundline[#color]%
- {\dontleavehmode
- \dowithnextbox{\pack_backgrounds_add_to_nextbox{#color}}\hbox}
+% \unexpanded\def\backgroundline[#color]%
+% {\dontleavehmode
+% \dowithnextbox{\pack_backgrounds_add_to_nextbox{#color}}\hbox}
+%
+% \unexpanded\def\pack_backgrounds_add_to_nextbox#color% handy helper
+% {\hpack
+% {\dousecolorparameter{#color}%
+% \vrule
+% \??width \nextboxwd
+% \??height\nextboxht
+% \??depth \nextboxdp
+% \hskip-\nextboxwd
+% \flushnextbox}}
+
+%D We implement this elsewhere avoiding the rule.
-\unexpanded\def\pack_backgrounds_add_to_nextbox#color% handy helper
- {\hbox
- {\dousecolorparameter{#color}%
- \vrule
- \!!width \nextboxwd
- \!!height\nextboxht
- \!!depth \nextboxdp
- \hskip-\nextboxwd
- \flushnextbox}}
+% \unexpanded\def\backgroundline
+% {\dontleavehmode
+% \pack_backgrounds_add_to_nextbox\hbox\hpack}
+%
+% \unexpanded\def\pack_backgrounds_add_to_nextbox#box#pack[#color]%
+% {\dontleavehmode
+% \dowithnextbox{\pack_backgrounds_add_to_nextbox_indeed#pack{#color}}#box}
+%
+% \unexpanded\def\pack_backgrounds_add_to_nextbox_indeed#pack#color% handy helper
+% {#pack%
+% {\dousecolorparameter{#color}%
+% \vrule
+% \??width \nextboxwd
+% \??height\nextboxht
+% \??depth \nextboxdp
+% \hskip-\nextboxwd
+% \flushnextbox}}
+%
+% \unexpanded\def\backgroundhbox{\pack_backgrounds_add_to_nextbox\hbox\hpack}
+% \unexpanded\def\backgroundvtop{\pack_backgrounds_add_to_nextbox\vtop\tpack}
+% \unexpanded\def\backgroundvbox{\pack_backgrounds_add_to_nextbox\vbox\vpack}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-box.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-box.mkiv
index c53b4520ce6..bf6d4662dac 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-box.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-box.mkiv
@@ -108,6 +108,7 @@
{\global\advance\c_pack_anchors_n\plusone
\pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]%
\putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors
+% \xtoksapp\t_pack_anchors_flush{\pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}}%
\doglobal\appendetoks
\pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}%
\to \t_pack_anchors_flush
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-com.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-com.mkiv
index 59354208e13..1c6f2de7361 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-com.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-com.mkiv
@@ -73,7 +73,7 @@
\newsystemmode{combination}
\appendtoks
- \global\resetsystemmode{combination}%
+ \globalresetsystemmode{combination}%
\to \everyinsidefloat
\newcount\c_pack_combinations_nesting % local
@@ -113,7 +113,7 @@
\setbox\b_pack_combinations_content_saved \box\b_pack_combinations_content
\setbox\b_pack_combinations_caption_saved \box\b_pack_combinations_caption
\else
- \global\setsystemmode{combination}% why global
+ \globalsetsystemmode{combination}% why global
\fi}
\def\pack_combinations_pop
@@ -126,7 +126,7 @@
\setbox\b_pack_combinations_content \box\b_pack_combinations_content_saved
\setbox\b_pack_combinations_caption \box\b_pack_combinations_caption_saved
\else
- \global\resetsystemmode{combination}% why global
+ \globalresetsystemmode{combination}% why global
\fi
\advance\c_pack_combinations_nesting\minusone}
@@ -205,7 +205,7 @@
% {\bgroup
% \scratchtoks{{}}%
% \dorecurse\c_pack_combinations_y
-% {\scratchtoks\expandafter{\the\scratchtoks{}{}}}%
+% {\toksapp{{}{}}}%
% \expandafter\egroup\the\scratchtoks
% \egroup
% \dostoptagged
@@ -290,7 +290,7 @@
\alignmark\alignmark
\m_pack_combinations_rightfiller
\aligntab
- \tabskip\zeropoint \s!plus 1fill
+ \tabskip\zeropoint \s!plus 1fill % \fillskip
\alignmark\alignmark
\cr
\pack_combinations_pickup}
@@ -437,10 +437,10 @@
\nointerlineskip % indeed
\combinationparameter\c!inbetween
\global\c_pack_combinations_x\c_pack_combinations_max
- \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes
+ \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes
\else
\global\setbox\b_pack_combinations_captions\emptybox
- \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop
+ \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop
\fi}%
\pack_combinations_flush_captions_indeed
\crcr}
@@ -656,7 +656,7 @@
\newsystemmode{pairedbox}
\appendtoks
- \global\resetsystemmode{pairedbox}%
+ \globalresetsystemmode{pairedbox}%
\to \everyinsidefloat
\installcorenamespace {pairedbox}
@@ -720,7 +720,7 @@
\let\startcaption\pack_common_caption_start
\let\stopcaption \pack_common_caption_stop
%
- \global\setsystemmode{pairedbox}%
+ \globalsetsystemmode{pairedbox}%
\pack_pairedboxes_before
\assumelongusagecs\pack_pairedboxes_first_pickup}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-cut.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-cut.mkiv
index ffd0251d5ae..84c14d648e5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-cut.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-cut.mkiv
@@ -65,85 +65,87 @@
\def\cutmarkrulethickness{\onepoint}
\unexpanded\def\horizontalcuts
- {\normalhbox to \d_pack_cutmarks_width
- {\dorecurse\horizontalcutmarks{\vrule\s!width\cutmarkrulethickness\s!height\cutmarklength\normalhfill}%
+ {\hpack to \d_pack_cutmarks_width
+ {\dorecurse\horizontalcutmarks{\vrule\s!width\cutmarkrulethickness\s!height\cutmarklength\hfill}%
\unskip}}
\unexpanded\def\verticalcuts
- {\normalvbox to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax
+ {\vpack to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax
{\hsize\cutmarklength
- \dorecurse\verticalcutmarks{\vrule\s!height\cutmarkrulethickness\s!width\hsize\normalvfill}%
+ \dorecurse\verticalcutmarks{\vrule\s!height\cutmarkrulethickness\s!width\hsize\vfill}%
\unskip}}
\unexpanded\def\baselinecuts
{\ifdim\d_pack_cutmarks_depth>\zeropoint
- \normalvbox to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax
+ \vpack to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax
{\hsize\dimexpr\cutmarklength/2\relax
- \normalvskip\zeropoint\s!plus\d_pack_cutmarks_height
+ \vskip\zeropoint\s!plus\d_pack_cutmarks_height
\vrule\s!height\cutmarkrulethickness\s!width\hsize
- \normalvskip\zeropoint\s!plus\d_pack_cutmarks_depth}%
+ \vskip\zeropoint\s!plus\d_pack_cutmarks_depth}%
\fi}
\unexpanded\def\cutmarksymbols#1%
- {\normalhbox to \d_pack_cutmarks_width
- {\setbox\scratchbox\normalhbox to \cutmarklength
- {\normalhss\infofont\cutmarksymbol\normalhss}%
- \normalhss
- \normalvbox to \cutmarklength
+ {\hpack to \d_pack_cutmarks_width
+ {\setbox\scratchbox\hbox to \cutmarklength
+ {\hss\infofont\cutmarksymbol\hss}%
+ \hss
+ \vpack to \cutmarklength
{\scratchdimen\dimexpr\cutmarklength/2\relax
\scratchskip \ifx\cutmarkhoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkhoffset\fi
- \normalvss
- \hpack to \d_pack_cutmarks_width
- {\llap{\copy\scratchbox\normalhskip\scratchskip}%
- \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen
- \rlap{\normalhskip\scratchskip\copy\scratchbox}}%
- \normalvss}%
- \normalhss}}
+ \vss
+ \hbox to \d_pack_cutmarks_width
+ {\llap{\copy\scratchbox\hskip\scratchskip}%
+ \hskip\scratchdimen\hss
+ \infofont#1%
+ \hss\hskip\scratchdimen
+ \rlap{\hskip\scratchskip\copy\scratchbox}}%
+ \vss}%
+ \hss}}
\unexpanded\def\makecutbox#1%
{\bgroup
\d_pack_cutmarks_height\ht#1%
\d_pack_cutmarks_depth \dp#1%
\d_pack_cutmarks_width \wd#1%
- \setbox#1\normalhbox
+ \setbox#1\hpack
{\dontcomplain
\forgetall
\boxmaxdepth\maxdimen
\offinterlineskip
\scratchdimen\dimexpr\cutmarklength/2\relax
\hsize\d_pack_cutmarks_width
- \setbox\scratchbox\normalvbox
- {\setbox\scratchbox\normalhbox{\horizontalcuts}%
+ \setbox\scratchbox\vpack
+ {\setbox\scratchbox\hpack{\horizontalcuts}%
\scratchskip\ifx\cutmarkvoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkvoffset\fi
- \tlap{\copy\scratchbox\normalvskip\scratchskip}%
+ \tlap{\copy\scratchbox\vskip\scratchskip}%
\hpack to \d_pack_cutmarks_width
{\scratchskip\ifx\cutmarkhoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkhoffset\fi
- \setbox\scratchbox\normalhbox{\verticalcuts}%
- \llap{\copy\scratchbox\normalhskip\scratchskip}%
+ \setbox\scratchbox\hpack{\verticalcuts}%
+ \llap{\copy\scratchbox\hskip\scratchskip}%
\ifdim\d_pack_cutmarks_depth=\zeropoint
- \normalhfill
+ \hfill
\else
\bgroup
- \setbox\scratchbox\normalhbox{\baselinecuts}%
- \llap{\copy\scratchbox\normalhskip\scratchskip}%
- \normalhfill
- \rlap{\normalhskip\scratchskip\copy\scratchbox}%
+ \setbox\scratchbox\hpack{\baselinecuts}%
+ \llap{\copy\scratchbox\hskip\scratchskip}%
+ \hfill
+ \rlap{\hskip\scratchskip\copy\scratchbox}%
\egroup
\fi
- \rlap{\normalhskip\scratchskip\copy\scratchbox}}%
- \blap{\normalvskip\scratchskip\copy\scratchbox}}%
+ \rlap{\hskip\scratchskip\copy\scratchbox}}%
+ \blap{\vskip\scratchskip\copy\scratchbox}}%
\ht\scratchbox\d_pack_cutmarks_height
\dp\scratchbox\d_pack_cutmarks_depth
\wd\scratchbox\zeropoint
\startcolor[\defaulttextcolor]%
\box\scratchbox
\ifx\cutmarksymbol\relax \else
- \setbox\scratchbox\normalvbox
+ \setbox\scratchbox\vpack
{\scratchskip\ifx\cutmarkvoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkvoffset\fi
\vskip-\dimexpr\scratchskip+\cutmarklength\relax
- \normalhbox{\cutmarksymbols\cutmarktoptext}%
+ \hpack{\cutmarksymbols\cutmarktoptext}%
\vskip\dimexpr\scratchskip+\d_pack_cutmarks_height+\d_pack_cutmarks_depth+\scratchskip\relax
- \normalhbox{\cutmarksymbols\cutmarkbottomtext}}%
+ \hpack{\cutmarksymbols\cutmarkbottomtext}}%
\ht\scratchbox\d_pack_cutmarks_height
\dp\scratchbox\d_pack_cutmarks_depth
\wd\scratchbox\zeropoint
@@ -156,8 +158,8 @@
\dp#1\d_pack_cutmarks_depth
\egroup}
-\unexpanded\def\cuthbox{\normalhbox\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox}
-\unexpanded\def\cutvbox{\normalvbox\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox}
-\unexpanded\def\cutvtop{\normalvtop\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop}
+\unexpanded\def\cuthbox{\hpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\hbox}
+\unexpanded\def\cutvbox{\vpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\vbox}
+\unexpanded\def\cutvtop{\tpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\vtop}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv
index 8661fe57a5e..e7070cfdec1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv
@@ -293,8 +293,8 @@
{\setbox\b_layers\emptybox
\d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax
\d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax
- \globallet\lastlayerxpos\!!zeropoint
- \globallet\lastlayerypos\!!zeropoint
+ \glet\lastlayerxpos\!!zeropoint
+ \glet\lastlayerypos\!!zeropoint
\doifinset\v!bottom\p_pack_layers_corner\pack_layers_set_bottom_positions
\doifinset\v!right \p_pack_layers_corner\pack_layers_set_right_positions
\doifinset\v!middle\p_pack_layers_corner\pack_layers_set_middle_positions
@@ -540,24 +540,85 @@
% todo: pass the layer with \lastnamedcs
+% \def\pack_layers_flush_single
+% {\startoverlay
+% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
+% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}%
+% \stopoverlay}
+%
+% \def\pack_layers_flush_double#1%
+% {\startoverlay
+% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
+% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}%
+% {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}%
+% {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}%
+% \stopoverlay}
+
+% optimized:
+
\def\pack_layers_flush_single
- {\startoverlay
- {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
- {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}%
- \stopoverlay}
+ {\ifcsname\??layerbox\currentlayer\endcsname
+ \ifvoid\lastnamedcs
+ \ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname
+ \ifvoid\lastnamedcs\else
+ \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two
+ \fi
+ \fi
+ \else
+ \chardef\b_layer_one\lastnamedcs
+ \ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname
+ \ifvoid\lastnamedcs\else
+ \chardef\b_layer_two\lastnamedcs
+ \startoverlay
+ {\pack_layers_flush_indeed\plusone \currentlayer \b_layer_one}%
+ {\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two}%
+ \stopoverlay
+ \fi
+ \else
+ \pack_layers_flush_indeed\plusone\currentlayer\b_layer_one
+ \fi
+ \fi
+ \else\ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname
+ \ifvoid\lastnamedcs
+ % nothing
+ \else
+ \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two
+ \fi
+ \fi\fi}
+
+% less optimized:
\def\pack_layers_flush_double#1%
{\startoverlay
- {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
- {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}%
- {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}%
- {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}%
+ {\ifcsname\??layerbox\currentlayer\endcsname
+ \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\plusone\currentlayer\b_layer_two
+ \fi
+ \fi}%
+ {\ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname
+ \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two
+ \fi
+ \fi}%
+ {\ifcsname\??layerbox#1\currentlayer\endcsname
+ \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\plusone{#1\currentlayer}\b_layer_two
+ \fi
+ \fi}%
+ {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname
+ \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs
+ \pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\b_layer_two
+ \fi
+ \fi}%
\stopoverlay}
\let\pack_layers_top_fill \relax
\let\pack_layers_bottom_fill\vss
-\def\pack_layers_flush_indeed#1#2% quite core, so optimized
+%def\pack_layers_flush_indeed#1#2%
+\def\pack_layers_flush_indeed#1#2#3%
{\begingroup % already grouped
\offinterlineskip
\edef\p_pack_layers_preset{\layerparameter\c!preset}%
@@ -587,7 +648,8 @@
\fi\fi
\fi
\fi
- \chardef\b_layers\csname\??layerbox#2\endcsname % trick
+ %chardef\b_layers\csname\??layerbox#2\endcsname % trick
+ \let\b_layers#3%
% we need to copy in order to retain the negative offsets for a next
% stage of additions, i.e. llx/lly accumulate in repeat mode and the
% compensation may differ each flush depending on added content
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-mrl.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-mrl.mkiv
index 85aa3ad04ed..665d245b346 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-mrl.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-mrl.mkiv
@@ -39,7 +39,7 @@
\installsimplecommandhandler \??blackrules {blackrules}
\unexpanded\def\blackrule
- {\hbox\bgroup
+ {\hpack\bgroup
\doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed}
\def\pack_black_rule_pickup[#1]%
@@ -99,7 +99,7 @@
%D would probably have taken more tokens.
\unexpanded\def\blackrules % probably never used
- {\hbox\bgroup
+ {\hpack\bgroup
\doifelsenextoptionalcs\pack_black_rules_pickup\pack_black_rules_indeed}
\def\pack_black_rules_pickup[#1]%
@@ -121,23 +121,25 @@
\fi
\fi
\useblackrulesstyleandcolor\c!style\c!color
- \edef\brule
- {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
- \lastnamedcs
- \else
- \vrule
- \fi}%
- \dorecurse\scratchcounter % a typical case of where we can use a simple loop
- {\brule
- \s!width \scratchwidth
- \s!height\scratchheight
- \s!depth \scratchdepth
- \ifzeropt\scratchdistance\else
- \hskip\scratchdistance
- \fi}%
+ % a typical case of where we can use a simple loop or even a leaders
+ \dorecurse\scratchcounter\pack_black_rules_step
\unskip
\egroup}
+\def\pack_black_rules_step
+ {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
+ \lastnamedcs
+ \else
+ \vrule
+ \fi
+ \s!width \scratchwidth
+ \s!height\scratchheight
+ \s!depth \scratchdepth
+ \relax
+ \ifzeropt\scratchdistance\else
+ \hskip\scratchdistance
+ \fi}
+
\installcorenamespace{blackruletype}
\setvalue{\??blackruletype mp}%
@@ -578,7 +580,7 @@
{\page[\v!preference] % interferes
\directtextrulesparameter\c!before\relax
\blank[\v!samepage,\v!nowhite]%
- \pack_textrule_with_text{#1}%
+ \pack_textrule_with_text_yes{#1}%
\blank[\v!samepage,\v!nowhite]%
\directtextrulesparameter\c!inbetween\relax
\endgraf}
@@ -598,9 +600,10 @@
\directtextrulesparameter\c!inbetween\relax
\page[\v!preference]}
-\def\pack_textrule_with_text#1%
- {\bgroup
- \setbox\scratchbox\hbox to \availablehsize
+\def\pack_textrule_with_text_yes#1%
+ {\noindent % this will force side floats to be calculated
+ \bgroup
+ \setbox\scratchbox\hpack to \availablehsize
{\scratchwidth \directtextrulesparameter\c!rulethickness\relax
\scratchheight\dimexpr .5\exheight+.5\scratchwidth\relax
\scratchdepth \dimexpr-.5\exheight+.5\scratchwidth\relax
@@ -611,19 +614,41 @@
#1%
\hskip\leftmargindistance}}
{\color[\directtextrulesparameter\c!rulecolor]
- {\vrule\s!height\scratchheight\s!depth\scratchdepth\s!width\directtextrulesparameter\c!width}%
+ {\vrule
+ \s!height\scratchheight
+ \s!depth \scratchdepth
+ \s!width \directtextrulesparameter\c!width}%
\hbox spread 2\dimexpr\directtextrulesparameter\c!distance\relax
{\hss
\usetextrulesstyleandcolor\c!style\c!color
\strut#1%
\hss}}}%
\color[\directtextrulesparameter\c!rulecolor]
- {\leaders\hrule\s!height\scratchheight\s!depth\scratchdepth\hfill}}%
+ {\leaders\hrule
+ \s!height\scratchheight
+ \s!depth \scratchdepth
+ \hfill}}%
\ht\scratchbox\strutht
\dp\scratchbox\strutdp
- \noindent\box\scratchbox
+ \box\scratchbox
+ %\carryoverpar
\egroup}
+\def\pack_textrule_with_text_nop#1%
+ {\ifhmode
+ \endgraf
+ \fi
+ \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on
+ \pack_textrule_correct_depth_yes
+ \pack_textrule_correct_depth_nop
+ \nointerlineskip
+ \noindent\vpack % was \dontleavehmode
+ {\color[\directtextrulesparameter\c!rulecolor]
+ {\hrule
+ \s!depth \directtextrulesparameter\c!rulethickness
+ \s!height\zeropoint
+ \s!width \availablehsize}}}
+
\def\pack_textrule_correct_depth_yes
{\vskip\dimexpr
\strutdp +.5\exheight
@@ -643,15 +668,9 @@
\def\pack_textrule_following#1%
{\doifelsenothing{#1}
- {\ifhmode
- \endgraf
- \fi
- \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on\pack_textrule_correct_depth_yes\pack_textrule_correct_depth_nop
- \nointerlineskip
- \noindent\vbox % was \dontleavehmode
- {\color[\directtextrulesparameter\c!rulecolor]
- {\hrule\s!depth\directtextrulesparameter\c!rulethickness\s!height\zeropoint\s!width\availablehsize}}}
- {\pack_textrule_with_text{#1}}%
+ \pack_textrule_with_text_nop
+ \pack_textrule_with_text_yes
+ {#1}%
\ifvmode
\prevdepth\zeropoint
\fi}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-obj.lua b/Master/texmf-dist/tex/context/base/mkiv/pack-obj.lua
index 3f2b2edfeff..ea36b10de7a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-obj.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-obj.lua
@@ -13,9 +13,11 @@ reusable components.
local context = context
local codeinjections = backends.codeinjections
-
local ctx_doifelse = commands.doifelse
+local report = logs.reporter("objects")
+local trace = false trackers.register("objects",function(v) trace = v end)
+
local nuts = nodes.nuts
local setlink = nuts.setlink
@@ -26,10 +28,7 @@ local new_latelua = nuts.pool.latelua
local settexdimen = tokens.setters.dimen
-local gettexbox = tokens.getters.box
-local settexbox = tokens.setters.box
-local gettexdimen = tokens.getters.dimen
-local gettexcount = tokens.getters.count
+local getcount = tex.getcount
local implement = interfaces.implement
local setmacro = interfaces.setmacro
@@ -54,8 +53,16 @@ end
job.register('job.objects.collected', tobesaved, initializer, nil)
local function saveobject(tag,number,page)
- local t = { number, page }
- tobesaved[tag], collected[tag] = t, t
+ local data = { number, page }
+ tobesaved[tag] = data
+ collected[tag] = data
+end
+
+local function saveobjectspec(specification)
+ local tag = specification.tag
+ local data = { specification.number, specification.page }
+ tobesaved[tag] = data
+ collected[tag] = data
end
local function setobject(tag,number,page)
@@ -128,8 +135,9 @@ objects = {
local objects = objects
function objects.register(ns,id,b,referenced,offset,mode)
- objects.n = objects.n + 1
- nodes.handlers.finalize(gettexbox(b),"object")
+ local n = objects.n + 1
+ objects.n = n
+ nodes.handlers.finalizebox(b)
if mode == 0 then
-- tex
data[ns][id] = {
@@ -147,6 +155,9 @@ function objects.register(ns,id,b,referenced,offset,mode)
mode,
}
end
+ if trace then
+ report("registering object %a (n=%i)",id,n)
+ end
end
function objects.restore(ns,id) -- why not just pass a box number here too (ok, we also set offset)
@@ -159,9 +170,12 @@ function objects.restore(ns,id) -- why not just pass a box number here too (ok,
local hbox = codeinjections.restoreboxresource(index) -- a nut !
if status then
local list = getlist(hbox)
- local page = new_latelua(function()
- saveobject(ns .. "::" .. id,index,gettexcount("realpageno"))
- end)
+ local page = new_latelua {
+ action = saveobjectspec,
+ tag = ns .. "::" .. id,
+ number = index,
+ page = getcount("realpageno"),
+ }
setlink(list,page)
end
setbox("objectbox",hbox)
@@ -170,6 +184,9 @@ function objects.restore(ns,id) -- why not just pass a box number here too (ok,
setbox("objectbox",nil)
settexdimen("objectoff",0) -- for good old times
end
+ if trace then
+ report("restoring object %a",id)
+ end
end
function objects.dimensions(index)
@@ -191,7 +208,7 @@ function objects.reference(ns,id)
end
function objects.page(ns,id)
- return getobjectpage(ns .."::" .. id,gettexcount("realpageno"))
+ return getobjectpage(ns .."::" .. id,getcount("realpageno"))
end
function objects.found(ns,id)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-obj.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-obj.mkiv
index aeb5cb4f412..d08c664944f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-obj.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-obj.mkiv
@@ -51,7 +51,8 @@
\newdimen\objectht \def\objectheight{\the\objectht}
\newdimen\objectdp \def\objectdepth {\the\objectdp}
-%D If I have time I will use the unreferenced variant for e.g. mp reuse.
+%D If I have time I will use the unreferenced variant for e.g. mp reuse. This can be
+%D rewritten in \LUA\ anyway.
\unexpanded\def\setreferencedobject #1#2{\begingroup\synctexpause\objectoff\objectoffset\inobjecttrue\dowithnextbox{\pack_objects_set_yes{#1}{#2}}}
\unexpanded\def\settightreferencedobject #1#2{\begingroup\synctexpause\objectoff\zeropoint \inobjecttrue\dowithnextbox{\pack_objects_set_yes{#1}{#2}}}
@@ -65,14 +66,8 @@
\newconstant\c_pack_objects_offset_mode % 0=tex 1=box
-\unexpanded\def\pack_objects_temp_check % this will go away
- {\ifnum\texenginefunctionality<6401\relax
- \c_pack_objects_offset_mode\zerocount
- \fi}
-
\unexpanded\def\pack_objects_set_yes#1#2%
- {\pack_objects_temp_check % this will go away
- \ifcase\c_pack_objects_offset_mode
+ {\ifcase\c_pack_objects_offset_mode
\ifzeropt\objectoff
\pack_objects_package_nop\nextbox
\else
@@ -86,8 +81,7 @@
\endgroup}
\unexpanded\def\pack_objects_set_nop#1#2%
- {\pack_objects_temp_check % this will go away
- \ifcase\c_pack_objects_offset_mode
+ {\ifcase\c_pack_objects_offset_mode
\ifzeropt\objectoff
\pack_objects_package_nop\nextbox
\else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua
index c9771546c9b..455d0bff832 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua
@@ -20,42 +20,50 @@ if not modules then modules = { } end modules ['pack-rul'] = {
local type = type
-local context = context
-
-local hlist_code = nodes.nodecodes.hlist
-local vlist_code = nodes.nodecodes.vlist
-local box_code = nodes.listcodes.box
-local line_code = nodes.listcodes.line
-local equation_code = nodes.listcodes.equation
-
-local texsetdimen = tex.setdimen
-local texsetcount = tex.setcount
-
-local implement = interfaces.implement
-
-local nuts = nodes.nuts
-
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getlist = nuts.getlist
-local setlist = nuts.setlist
-local getwhd = nuts.getwhd
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getbox = nuts.getbox
-local getdir = nuts.getdir
-local setshift = nuts.setshift
-local setwidth = nuts.setwidth
-local getwidth = nuts.getwidth
-local setboxglue = nuts.setboxglue
-local getboxglue = nuts.getboxglue
-
-local hpack = nuts.hpack
-local traverse_id = nuts.traverse_id
-local list_dimensions = nuts.dimensions
-local flush_node = nuts.flush
-
-local checkformath = false
+local context = context
+
+local nodecodes = nodes.nodecodes
+local listcodes = nodes.listcodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+
+local boxlist_code = listcodes.box
+local linelist_code = listcodes.line
+local equationlist_code = listcodes.equation
+
+local texsetdimen = tex.setdimen
+local texsetcount = tex.setcount
+
+local implement = interfaces.implement
+
+local nuts = nodes.nuts
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getlist = nuts.getlist
+local setlist = nuts.setlist
+local getwhd = nuts.getwhd
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getbox = nuts.getbox
+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 hpack = nuts.hpack
+local getdimensions = nuts.dimensions
+local flush_node = nuts.flush
+
+local traversers = nuts.traversers
+local nexthlist = traversers.hlist
+local nextvlist = traversers.vlist
+local nextlist = traversers.list
+
+local checkformath = false
directives.register("framed.checkmath",function(v) checkformath = v end) -- experiment
@@ -76,24 +84,25 @@ local function doreshapeframedbox(n)
if boxwidth ~= 0 then -- and h.subtype == vlist_code
local list = getlist(box)
if list then
- local function check(n,repack)
+ local hdone = false
+ for n, id, subtype, list in nextlist, list do -- no dir etc needed
local width, height, depth = getwhd(n)
if not firstheight then
firstheight = height
end
lastdepth = depth
noflines = noflines + 1
- local l = getlist(n)
- if l then
- if repack then
- local subtype = getsubtype(n)
- if subtype == box_code or subtype == line_code then
- lastlinelength = list_dimensions(l,getdir(n))
+ if list then
+ if id == hlist_code then
+ if subtype == boxlist_code or subtype == linelist_code then
+ lastlinelength = getdimensions(list)
else
lastlinelength = width
end
+ hdone = true
else
lastlinelength = width
+ -- vdone = true
end
if lastlinelength > maxwidth then
maxwidth = lastlinelength
@@ -107,31 +116,19 @@ local function doreshapeframedbox(n)
totalwidth = totalwidth + lastlinelength
end
end
- local hdone = false
- for h in traverse_id(hlist_code,list) do -- no dir etc needed
- check(h,true)
- hdone = true
- end
- -- local vdone = false
- for v in traverse_id(vlist_code,list) do -- no dir etc needed
- check(v,false)
- -- vdone = true
- end
if not firstheight then
-- done)
elseif maxwidth ~= 0 then
if hdone then
- for h in traverse_id(hlist_code,list) do
- local l = getlist(h)
- if l then
- local subtype = getsubtype(h)
- if subtype == box_code or subtype == line_code then
- local p = hpack(l,maxwidth,'exactly',getdir(h)) -- multiple return value
+ for h, id, subtype, list in nextlist, list do
+ if list and id == hlist_code then
+ if subtype == boxlist_code or subtype == linelist_code then
+ local p = hpack(list,maxwidth,'exactly',getdirection(h)) -- multiple return value
local set, order, sign = getboxglue(p)
setboxglue(h,set,order,sign)
setlist(p)
flush_node(p)
- elseif checkformath and subtype == equation_code then
+ elseif checkformath and subtype == equationlist_code then
-- display formulas use a shift
if nofnonzero == 1 then
setshift(h,0)
@@ -142,7 +139,7 @@ local function doreshapeframedbox(n)
end
end
-- if vdone then
- -- for v in traverse_id(vlist_code,list) do
+ -- for v in nextvlist, list do
-- local width = getwidth(n)
-- if width > maxwidth then
-- setwidth(v,maxwidth)
@@ -164,7 +161,7 @@ local function doreshapeframedbox(n)
texsetdimen("global","framedaveragewidth",averagewidth)
end
-local function doanalyzeframedbox(n)
+local function doanalyzeframedbox(n) -- traverse_list
local box = getbox(n)
local noflines = 0
local firstheight = nil
@@ -172,7 +169,7 @@ local function doanalyzeframedbox(n)
if getwidth(box) ~= 0 then
local list = getlist(box)
if list then
- local function check(n)
+ for n in nexthlist, list do
local width, height, depth = getwhd(n)
if not firstheight then
firstheight = height
@@ -180,11 +177,13 @@ local function doanalyzeframedbox(n)
lastdepth = depth
noflines = noflines + 1
end
- for h in traverse_id(hlist_code,list) do
- check(h)
- end
- for v in traverse_id(vlist_code,list) do
- check(v)
+ for n in nextvlist, list do
+ local width, height, depth = getwhd(n)
+ if not firstheight then
+ firstheight = height
+ end
+ lastdepth = depth
+ noflines = noflines + 1
end
end
end
@@ -210,16 +209,11 @@ local function maxboxwidth(box)
end
local lastlinelength = 0
local maxwidth = 0
- local function check(n,repack)
+ for n, subtype in nexthlist, list do -- no dir etc needed
local l = getlist(n)
if l then
- if repack then
- local subtype = getsubtype(n)
- if subtype == box_code or subtype == line_code then
- lastlinelength = list_dimensions(l,getdir(n))
- else
- lastlinelength = getwidth(n)
- end
+ if subtype == boxlist_code or subtype == linelist_code then
+ lastlinelength = getdimensions(l)
else
lastlinelength = getwidth(n)
end
@@ -228,11 +222,14 @@ local function maxboxwidth(box)
end
end
end
- for h in traverse_id(hlist_code,list) do -- no dir etc needed
- check(h,true)
- end
- for v in traverse_id(vlist_code,list) do -- no dir etc needed
- check(v,false)
+ for n, subtype in nextvlist, list do -- no dir etc needed
+ local l = getlist(n)
+ if l then
+ lastlinelength = getwidth(n)
+ if lastlinelength > maxwidth then
+ maxwidth = lastlinelength
+ end
+ end
end
return maxwidth
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-rul.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.mkiv
index c208baaf014..3d03942aab2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/pack-rul.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.mkiv
@@ -18,7 +18,7 @@
%D packaging and expansion we also keep tracing reasonable. For instance, multiple
%D stacked backgrounds can slow down a run if not optimized this way.
-\registerctxluafile{pack-rul}{}
+\registerctxluafile{pack-rul}{optimize}
\unprotect
@@ -141,6 +141,7 @@
\setupframed
[\c!width=\v!fit,
\c!height=\v!broad,
+ %\c!minheight=\zeropoint,
%\c!lines=,
\c!offset=.25\exheight, % \defaultframeoffset
\c!empty=\v!no,
@@ -239,7 +240,6 @@
\let\p_framed_backgroundcolor \empty
\let\p_framed_framecolor \empty
\let\p_framed_component \empty
-\let\p_framed_region \empty
\let\p_framed_background \empty
\let\p_framed_rulethickness \empty
\let\p_framed_foregroundcolor \empty
@@ -443,6 +443,8 @@
\newdimen\d_overlay_offset
\newdimen\d_overlay_linewidth
+\let\m_overlay_region\empty
+
% expandable ... in a future version the space will go (in my one can use Overlay*)
\def\overlaywidth {\the\d_overlay_width \space} % We preset the variables
@@ -450,6 +452,7 @@
\def\overlaydepth {\the\d_overlay_depth \space} % values.
\def\overlayoffset {\the\d_overlay_offset \space} % of the frame can be (are)
\def\overlaylinewidth {\the\d_overlay_linewidth\space} % set somewhere else.
+\def\overlayregion {\m_overlay_region}
% public but kind of protected
@@ -553,40 +556,36 @@
\def\pack_framed_process_background_indeed_internal#1% % : in name
{\bgroup
- \setbox\b_framed_extra\hbox{%\bgroup
- \ifzeropt\framedbackgroundoffset
- %\csname\??overlaybuiltin\m_framed_background\endcsname
- #1
- \else
+ \setbox\b_framed_extra\hpack\bgroup
+ \ifzeropt\framedbackgroundoffset\else
\kern-\framedbackgroundoffset
- %\hbox{\csname\??overlaybuiltin\m_framed_background\endcsname}%
- \hbox{#1}%
\fi
- }%\egroup
+ \hbox\bgroup#1\egroup
+ \egroup
\wd\b_framed_extra\zeropoint
\ht\b_framed_extra\framedbackgroundheight
\dp\b_framed_extra\framedbackgrounddepth
\box\b_framed_extra
\egroup}
-\def\pack_framed_process_background_indeed_external#1%
+% \def\pack_framed_process_background_indeed_external#1%
+% {\pack_framed_overlay_initialize
+% \bgroup
+% \setbox\b_framed_extra\hpack\bgroup
+% \ifzeropt\framedbackgroundoffset\else
+% \kern-\framedbackgroundoffset
+% \fi
+% \hbox\bgroup#1\egroup
+% \egroup
+% \wd\b_framed_extra\zeropoint
+% \ht\b_framed_extra\framedbackgroundheight
+% \dp\b_framed_extra\framedbackgrounddepth
+% \box\b_framed_extra
+% \egroup}
+
+\def\pack_framed_process_background_indeed_external
{\pack_framed_overlay_initialize
- \bgroup
- \setbox\b_framed_extra\hbox{%\bgroup
- \ifzeropt\framedbackgroundoffset
- %\csname\??overlay\m_framed_background\endcsname
- #1%
- \else
- \kern-\framedbackgroundoffset
- %\hbox{\csname\??overlay\m_framed_background\endcsname}%
- \hbox{#1}%
- \fi
- }%\egroup
- \wd\b_framed_extra\zeropoint
- \ht\b_framed_extra\framedbackgroundheight
- \dp\b_framed_extra\framedbackgrounddepth
- \box\b_framed_extra
- \egroup}
+ \pack_framed_process_background_indeed_internal}
\def\pack_framed_process_backgrounds#1,#2% #2 gobbles spaces (we could avoid one catch if we have nextbackground)
{\edef\m_framed_background{#1}%
@@ -606,15 +605,23 @@
\def\pack_framed_background_box_content% fuzzy but needed hack, this \vss, otherwise
{\vpack to \framedbackgroundheight{\vss\box\b_framed_normal\vss}} % vertical shift \backgroundheight
-\def\pack_framed_add_region % experiment
- {\ifx\p_framed_region\v!yes
- \anch_mark_region_box\b_framed_normal
- \else
- \anch_mark_tagged_box\b_framed_normal\p_framed_region
+\def\pack_framed_set_region % experiment
+ {\ifx\m_overlay_region\v!yes
+ \edef\m_overlay_region{\reservedautoregiontag}%
\fi}
+% \def\pack_framed_add_region % experiment
+% {\ifx\m_overlay_region\v!yes
+% \anch_mark_region_box\b_framed_normal
+% \else
+% \anch_mark_tagged_box\b_framed_normal\m_overlay_region
+% \fi}
+
+\def\pack_framed_add_region % experiment
+ {\anch_mark_tagged_box\b_framed_normal\m_overlay_region}
+
\def\pack_framed_add_background
- {\setbox\b_framed_normal\hbox % was vbox % see also *1*
+ {\setbox\b_framed_normal\hpack % was vbox % see also *1*
{%\pack_framed_forgetall % can be relaxed
\boxmaxdepth\maxdimen
\framedbackgroundoffset\d_framed_backgroundoffset
@@ -631,7 +638,7 @@
\setlayoutcomponentattribute{\v!background:\p_framed_component}%
\fi
\let\foregroundbox\pack_framed_background_box_content
- \hbox \layoutcomponentboxattribute to \framedbackgroundwidth\bgroup % width in case 'foreground' is used as overlay
+ \hpack \layoutcomponentboxattribute to \framedbackgroundwidth\bgroup % width in case 'foreground' is used as overlay
\the\everybackgroundbox % moved
\expandafter\pack_framed_process_backgrounds\p_framed_background,\s!unknown,\relax % hm, messy .. look into it
\box\b_framed_normal
@@ -692,10 +699,10 @@
\scratchdimen\zeropoint
\fi
\edef\overlaylinecolor{\framedparameter\c!framecolor}% twice, also in background
- \setbox\b_framed_extra\hbox
+ \setbox\b_framed_extra\hpack
{\kern-\d_framed_frameoffset
\raise\scratchdimen
- \hbox{\ifx\overlaylinecolor\empty\else\dousecolorparameter\overlaylinecolor\fi\pack_framed_stroked_box}}%
+ \hpack{\ifx\overlaylinecolor\empty\else\dousecolorparameter\overlaylinecolor\fi\pack_framed_stroked_box}}%
\wd\b_framed_extra\wd\b_framed_normal
\ht\b_framed_extra\ht\b_framed_normal
\dp\b_framed_extra\dp\b_framed_normal
@@ -724,26 +731,45 @@
% \dp\scratchbox\d_framed_target_dp
% \box\scratchbox}
-\def\pack_framed_stroked_box_normal
+\def\pack_framed_stroked_box_normal_opened
{\setbox\scratchbox\vpack \bgroup
- \csname \??framedtop\p_framed_frame\framedparameter\c!topframe \endcsname
+ \csname\??framedtop\p_framed_frame\framedparameter\c!topframe\endcsname
\nointerlineskip % new (needed for fences)
- \hbox \bgroup
- \csname \??framedleft\p_framed_frame\framedparameter\c!leftframe \endcsname
+ \hpack \bgroup
+ \csname\??framedleft\p_framed_frame\framedparameter\c!leftframe\endcsname
\novrule
\s!width \d_framed_target_wd
\s!height\d_framed_target_ht
\s!depth \d_framed_target_dp
- \csname \??framedright\p_framed_frame\framedparameter\c!rightframe \endcsname
+ \csname\??framedright\p_framed_frame\framedparameter\c!rightframe\endcsname
\egroup
\nointerlineskip % new (needed for fences)
- \csname \??framedbottom\p_framed_frame\framedparameter\c!bottomframe\endcsname
+ \csname\??framedbottom\p_framed_frame\framedparameter\c!bottomframe\endcsname
\egroup
\wd\scratchbox\d_framed_target_wd
\ht\scratchbox\d_framed_target_ht
\dp\scratchbox\d_framed_target_dp
\box\scratchbox}
+\def\pack_framed_stroked_box_normal_closed
+ {\hpack\bgroup
+ \scratchdimen.5\d_framed_linewidth
+ \hskip\scratchdimen
+ \clf_framedoutline
+ \dimexpr\d_framed_target_wd-\d_framed_linewidth\relax
+ \dimexpr\d_framed_target_ht-\scratchdimen\relax
+ \dimexpr\d_framed_target_dp-\scratchdimen\relax
+ \d_framed_linewidth
+ \relax
+ \egroup}
+
+\def\pack_framed_stroked_box_normal
+ {\ifx\p_framed_frame\v!closed
+ \pack_framed_stroked_box_normal_closed
+ \else
+ \pack_framed_stroked_box_normal_opened
+ \fi}
+
\def\pack_framed_t_rule{\hrule\s!height\d_framed_linewidth\kern-\d_framed_linewidth}
\def\pack_framed_b_rule{\kern-\d_framed_linewidth\hrule\s!height\d_framed_linewidth}
\def\pack_framed_r_rule{\kern-\d_framed_linewidth\vrule\s!width\d_framed_linewidth}
@@ -836,7 +862,7 @@
%D for passing this identifier between brackets lays in the mere fact that this way
%D we can use the optional argument grabbers.
-\def\defaultframeoffset{.25ex}
+\def\defaultframeoffset{.25\exheight}
\installcorenamespace{regularframedlevel}
@@ -999,9 +1025,11 @@
\edef\currentframed{#1}%
\pack_framed_initialize
\setbox\b_framed_normal\hbox{#4}%
- \edef\p_framed_region{\framedparameter\c!region}%
- \ifx\p_framed_region\v!yes % maybe later named
- \pack_framed_add_region
+ \iftrialtypesetting \else
+ \edef\m_overlay_region{\framedparameter\c!region}%
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_set_region
+ \fi
\fi
\setupcurrentframed[#3]%
\edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds
@@ -1028,6 +1056,11 @@
\pack_framed_add_background
\fi
\pack_framed_restore_depth
+ \iftrialtypesetting \else
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_add_region
+ \fi
+ \fi
\box\b_framed_normal
\egroup}
@@ -1036,9 +1069,9 @@
\unexpanded\def\pack_framed_process_box_indeed#1#2% component box (assumes parameters set and grouped usage)
{\setbox\b_framed_normal\box#2% could actually be \let\b_framed_normal#2
- \edef\p_framed_region{\framedparameter\c!region}%
- \ifx\p_framed_region\empty\else
- \pack_framed_add_region
+ \edef\m_overlay_region{\framedparameter\c!region}%
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_set_region
\fi
\edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds
\d_framed_frameoffset\framedparameter\c!frameoffset\relax % also used in backgrounds
@@ -1061,6 +1094,9 @@
\edef\p_framed_component{#1}%
\pack_framed_add_background
\fi
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_add_region
+ \fi
\box\b_framed_normal
\egroup}
@@ -1602,6 +1638,13 @@
\fi
\ifconditional\c_framed_has_height
\ht\b_framed_normal\d_framed_height
+ \else
+ \edef\p_framed_minheight{\framedparameter\c!minheight}%
+ \ifx\p_framed_minheight\empty \else
+ \ifdim\ht\b_framed_normal<\p_framed_minheight
+ \ht\b_framed_normal\p_framed_minheight
+ \fi
+ \fi
\fi
\edef\p_framed_empty{\framedparameter\c!empty}%
\ifx\p_framed_empty\v!yes
@@ -1609,9 +1652,9 @@
\fi
\pack_framed_stop_orientation % moved here at 2014-05-25
\iftrialtypesetting \else
- \edef\p_framed_region{\framedparameter\c!region}%
- \ifx\p_framed_region\empty\else
- \pack_framed_add_region
+ \edef\m_overlay_region{\framedparameter\c!region}%
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_set_region
\fi
\fi
\d_framed_applied_offset
@@ -1649,6 +1692,11 @@
\fi
\fi
\pack_framed_locator_after\p_framed_location
+ \iftrialtypesetting \else
+ \ifx\m_overlay_region\empty\else
+ \pack_framed_add_region
+ \fi
+ \fi
\box\b_framed_normal
\global\frameddimensionstate % global so to be used directly afterwards !
\ifconditional\c_framed_has_width
@@ -2203,7 +2251,7 @@
\ignorespaces}
\def\dododoformatonelinerbox
- {\hbox to \hsize % maybe \hpack
+ {\hpack to \hsize % was \hbox
{\ifcase\raggedstatus\or\hss\or\hss \fi
\unhbox\nextbox \removeunwantedspaces
\ifcase\raggedstatus\or \or\hss\or\hss\fi}%
@@ -2324,7 +2372,7 @@
\doformatonelinerbox}
\def\pack_framed_format_format_vsize
- {\vbox to \d_framed_height
+ {\vbox to \d_framed_height % no vpack .. maybe grid
\bgroup
\let\postprocessframebox\relax
% \pack_framed_forgetall
@@ -2551,9 +2599,9 @@
\par
\kern-\d_framed_linewidth
\dontleavehmode
- \hpack to \zeropoint{\normalhss\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth}%
+ \hpack to \zeropoint{\hss\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth}%
\hfill
- \hpack to \zeropoint{\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth\normalhss}%
+ \hpack to \zeropoint{\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth\hss}%
\par
\nointerlineskip
\kern\scratchoffset
@@ -2792,7 +2840,7 @@
\csname\??framedtextlocation\framedtextparameter\c!location\endcsname
\resetframedtextparameter\c!location
\pack_framed_text_check
- \setbox\b_framed_normal\vbox
+ \setbox\b_framed_normal\vbox % \vpack
\startboxedcontent
\hsize\localhsize
% \insidefloattrue % ? better
@@ -3069,7 +3117,7 @@
\fi}
\def\pack_framed_start_content_indeed
- {\setbox\b_framed_normal\hbox\bgroup % maybe \hpack
+ {\setbox\b_framed_normal\hpack\bgroup
\setlocalhsize
\hsize\localhsize
\scratchleftoffset \framedcontentparameter\c!leftoffset \relax
@@ -3079,16 +3127,16 @@
\advance\hsize\dimexpr-\scratchleftoffset-\scratchrightoffset \relax
\advance\vsize\dimexpr-\scratchtopoffset -\scratchbottomoffset\relax
\kern\scratchleftoffset
- \vbox\bgroup
+ \vpack\bgroup
\vskip\scratchtopoffset
- \vbox\bgroup
- \forgetall
- \blank[\v!disable]}
+ \vbox\bgroup
+ \forgetall
+ \blank[\v!disable]}
\def\pack_framed_stop_content_indeed
- {\removelastskip
- \egroup
- \vskip\scratchbottomoffset
+ {\removelastskip
+ \egroup
+ \vskip\scratchbottomoffset
\egroup
\kern\scratchrightoffset
\egroup
@@ -3132,4 +3180,16 @@
\let\themaxboxwidth\clf_themaxboxwidth
+%D New: slow but ok for most cases:
+
+\unexpanded\def\doifelseframed#1%
+ {\ifcase\numexpr\zerocount
+ \immediateassignment\edef\tempstring{#1\c!frame }\ifx\tempstring\v!on +\plusone\fi
+ \immediateassignment\edef\tempstring{#1\c!topframe }\ifx\tempstring\v!on +\plusone\fi
+ \immediateassignment\edef\tempstring{#1\c!bottomframe}\ifx\tempstring\v!on +\plusone\fi
+ \immediateassignment\edef\tempstring{#1\c!leftframe }\ifx\tempstring\v!on +\plusone\fi
+ \immediateassignment\edef\tempstring{#1\c!rightframe }\ifx\tempstring\v!on +\plusone\fi
+ \immediateassignment\edef\tempstring{#1\c!background }\ifx\tempstring\empty\else+\plusone\fi
+ \relax\expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments\fi}
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-bck.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-bck.mkiv
index b44910bbe6c..1ec7cdbb86e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-bck.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-bck.mkiv
@@ -52,7 +52,7 @@
\let\currentotrbackground\empty
-%D This is the only spot where we hav ea low level dependency on the way
+%D This is the only spot where we have a low level dependency on the way
%D parent chains are defined but we want the speed.
\unexpanded\def\page_backgrounds_check_background
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-box.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-box.mkvi
index 083a94390e5..10d5916319f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-box.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-box.mkvi
@@ -15,7 +15,7 @@
\unprotect
-%D The often two step approach (_indeed) saves skippign tokens
+%D The often two step approach (_indeed) saves skipping tokens
%D which is nicer for tracing.
%D Centering the paper area on the print area is determined
@@ -251,14 +251,25 @@
\def\page_boxes_apply_offsets#1%
{\setbox#1\vpack to \paperheight
{\hsize\paperwidth
- \vskip\topspace
- \doifbothsides
- {\hskip\backspace}
- {\hskip\backspace}
- {\hskip\dimexpr\paperwidth-\backspace-\makeupwidth\relax}%
+ \vkern\topspace
+% \parfillskip\zeropoint
+ \hkern\doifbothsides\backspace\backspace{\dimexpr\paperwidth-\backspace-\makeupwidth\relax}%
\box#1}%
\dp#1\zeropoint}
+% \def\page_boxes_apply_offset#box%
+% {\scratchwidth \wd#box%
+% \scratchheight\ht#box%
+% \scratchdepth \dp#box%
+% \setbox#box\vpack
+% {\offinterlineskip
+% \vkern\topoffset
+% \hkern\doifbothsides\backoffset\backoffset{-\backoffset}%
+% \box#box}%
+% \wd#box\scratchwidth
+% \ht#box\scratchheight
+% \dp#box\scratchdepth}
+
% \let\page_boxes_apply_clip_paper \gobbleoneargument
% \let\page_boxes_apply_clip_print_left \gobbleoneargument
% \let\page_boxes_apply_clip_print_right\gobbleoneargument
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-cst.lua b/Master/texmf-dist/tex/context/base/mkiv/page-cst.lua
index 155d6e8b0d1..1c2f5fc0b48 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-cst.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-cst.lua
@@ -19,87 +19,86 @@ local trace_cells = false trackers.register("columnsets.cells", function(v) t
local report = logs.reporter("column sets")
-local setmetatableindex = table.setmetatableindex
-
-local properties = nodes.properties
-
-local nodecodes = nodes.nodecodes
-local rulecodes = nodes.rulecodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local kern_code = nodecodes.kern
-local glue_code = nodecodes.glue
-local penalty_code = nodecodes.penalty
-local rule_code = nodecodes.rule
-
-local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
-local hpack = nuts.hpack
-local vpack = nuts.vpack
-local flushlist = nuts.flush_list
------ removenode = nuts.remove
-
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setnext = nuts.setnext
-local setprev = nuts.setprev
-local setsubtype = nuts.setsubtype
-local setbox = nuts.setbox
-local getwhd = nuts.getwhd
-local setwhd = nuts.setwhd
-local getkern = nuts.getkern
-local getpenalty = nuts.getpenalty
-local getwidth = nuts.getwidth
-local getheight = nuts.getheight
-
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getsubtype = nuts.getsubtype
-local takebox = nuts.takebox
-local takelist = nuts.takelist
-local splitbox = nuts.splitbox
-local getattribute = nuts.getattribute
-local copylist = nuts.copy_list
-
-local getbox = nuts.getbox
-local getcount = tex.getcount
-local getdimen = tex.getdimen
-
-local texsetbox = tex.setbox
-local texsetcount = tex.setcount
-local texsetdimen = tex.setdimen
-
-local theprop = nuts.theprop
-
-local nodepool = nuts.pool
-
-local new_vlist = nodepool.vlist
-local new_trace_rule = nodepool.rule
-local new_empty_rule = nodepool.emptyrule
-
-local context = context
-local implement = interfaces.implement
-
-local variables = interfaces.variables
-local v_here = variables.here
-local v_fixed = variables.fixed
-local v_top = variables.top
-local v_bottom = variables.bottom
-local v_repeat = variables["repeat"]
-local v_yes = variables.yes
-local v_page = variables.page
-local v_first = variables.first
-local v_last = variables.last
------ v_wide = variables.wide
-
-pagebuilders = pagebuilders or { } -- todo: pages.builders
-pagebuilders.columnsets = pagebuilders.columnsets or { }
-local columnsets = pagebuilders.columnsets
+local setmetatableindex = table.setmetatableindex
+
+local properties = nodes.properties
+
+local nodecodes = nodes.nodecodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local rule_code = nodecodes.rule
+
+local nuts = nodes.nuts
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+
+local hpack = nuts.hpack
+local vpack = nuts.vpack
+local flushlist = nuts.flush_list
+----- removenode = nuts.remove
+
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setsubtype = nuts.setsubtype
+local setbox = nuts.setbox
+local getwhd = nuts.getwhd
+local setwhd = nuts.setwhd
+local getkern = nuts.getkern
+local getpenalty = nuts.getpenalty
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getsubtype = nuts.getsubtype
+local takebox = nuts.takebox
+local takelist = nuts.takelist
+local splitbox = nuts.splitbox
+local getattribute = nuts.getattribute
+local copylist = nuts.copy_list
+
+local getbox = nuts.getbox
+local getcount = tex.getcount
+local getdimen = tex.getdimen
+
+local texsetbox = tex.setbox
+local texsetcount = tex.setcount
+local texsetdimen = tex.setdimen
+
+local theprop = nuts.theprop
+
+local nodepool = nuts.pool
+
+local new_vlist = nodepool.vlist
+local new_trace_rule = nodepool.rule
+local new_empty_rule = nodepool.emptyrule
+
+local context = context
+local implement = interfaces.implement
+
+local variables = interfaces.variables
+local v_here = variables.here
+local v_fixed = variables.fixed
+local v_top = variables.top
+local v_bottom = variables.bottom
+local v_repeat = variables["repeat"]
+local v_yes = variables.yes
+local v_page = variables.page
+local v_first = variables.first
+local v_last = variables.last
+----- v_wide = variables.wide
+
+pagebuilders = pagebuilders or { } -- todo: pages.builders
+pagebuilders.columnsets = pagebuilders.columnsets or { }
+local columnsets = pagebuilders.columnsets
local data = { [""] = { } }
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-cst.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-cst.mkiv
index f6eede68a52..37df4e8b17c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-cst.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-cst.mkiv
@@ -765,7 +765,7 @@
% state start | repeat
-% for now (transition)
+%D The old one:
\let\definecolumnset \definepagegrid
\let\setupcolumnset \setuppagegrid
@@ -782,5 +782,6 @@
\let\setupcolumnsetarea \setuppagegridarea
\let\setupcolumnsetareatext\setuppagegridareatext
-\protect
+%D It ends here.
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-ffl.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-ffl.mkiv
index 5536371a79e..414cae4ac11 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-ffl.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-ffl.mkiv
@@ -84,26 +84,29 @@
\def\strc_floats_facing_flush
{\ifnum\c_strc_floats_flushed<\c_strc_floats_saved
- \global\advance\c_strc_floats_flushed\plusone
- \floatingpenalty\zerocount
- \insert\namedinsertionnumber\s!topfloat\bgroup
- \forgetall
- \ifconditional\c_page_one_top_of_insert
- \ifconditional\c_page_one_correct_top_insert
- \topskipcorrection % [xx] new: see icare topbleed
- \kern-\lineskip
- \par
- \prevdepth\maxdimen
- \fi
+ \strc_floats_facing_flush_indeed % less tracing
+ \fi}
+
+\def\strc_floats_facing_flush_indeed
+ {\global\advance\c_strc_floats_flushed\plusone
+ \floatingpenalty\zerocount
+ \insert\namedinsertionnumber\s!topfloat\bgroup
+ \forgetall
+ \ifconditional\c_page_one_top_of_insert
+ \ifconditional\c_page_one_correct_top_insert
+ \topskipcorrection % [xx] new: see icare topbleed
+ \kern-\lineskip
+ \par
+ \prevdepth\maxdimen
\fi
- \directboxfromcache{\currentfacingfloat}{\number\c_strc_floats_flushed}%
- \vskip\s_page_one_between_top_insert
- \egroup
- \ifnum\c_strc_floats_saved=\c_strc_floats_flushed
- \global\c_strc_floats_saved \zerocount
- \global\c_strc_floats_flushed\zerocount
- \resetboxesincache{\currentfacingfloat}%
\fi
+ \directboxfromcache{\currentfacingfloat}{\number\c_strc_floats_flushed}%
+ \vkern\s_page_one_between_top_insert
+ \egroup
+ \ifnum\c_strc_floats_saved=\c_strc_floats_flushed
+ \global\c_strc_floats_saved \zerocount
+ \global\c_strc_floats_flushed\zerocount
+ \resetboxesincache{\currentfacingfloat}%
\fi}
\unexpanded\def\strc_floats_facing_setup
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-flt.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-flt.mkiv
index a06c90ec12c..83e2b49547a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-flt.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-flt.mkiv
@@ -284,16 +284,16 @@
\doifnotinset\v!low\floatspecification\vfill}%
\page_otr_fill_and_eject_page}
-\let\m_page_otf_checked_page_float\relax
+\let\m_page_otr_checked_page_float\relax
\unexpanded\def\page_floats_flush_page_floats % used in postpone
- {\edef\m_page_otf_checked_page_float{\clf_checkedpagefloat}%
- \ifx\m_page_otf_checked_page_float\empty
+ {\edef\m_page_otr_checked_page_float{\clf_checkedpagefloat}%
+ \ifx\m_page_otr_checked_page_float\empty
% nothing
- \else\ifx\m_page_otf_checked_page_float\v!empty
+ \else\ifx\m_page_otr_checked_page_float\v!empty
\emptyhbox \page_otr_fill_and_eject_page % why not dummy_page
\else
- \page_floats_flush_page_floats_indeed\m_page_otf_checked_page_float
+ \page_floats_flush_page_floats_indeed\m_page_otr_checked_page_float
\fi\fi}
% temp hack, needed to prevent floatbox being forgotten during
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-imp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-imp.mkiv
index c08f9856fa7..838ad742188 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-imp.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-imp.mkiv
@@ -26,7 +26,7 @@
\newtoks\t_page_text_data
\unexpanded\def\starttextdata#1\stoptextdata
- {\global\let\page_shipouts_flush_text_data\page_shipouts_flush_text_data_indeed
+ {\glet\page_shipouts_flush_text_data\page_shipouts_flush_text_data_indeed
\globaladdtotoks\t_page_text_data{#1}}
\let\stoptextdata\relax
@@ -34,7 +34,7 @@
\def\page_shipouts_flush_text_data_indeed
{\vsmashed{\the\t_page_text_data}%
\global\t_page_text_data\emptytoks
- \global\let\page_shipouts_flush_text_data\relax}
+ \glet\page_shipouts_flush_text_data\relax}
\let\page_shipouts_flush_text_data\relax
@@ -63,9 +63,21 @@
\newbox \shipoutscratchbox
-\setnewconstant\shipoutfinalizemethod\plusone % this will be default (we will have two finalizers)
+\setnewconstant\shipoutfinalizemethod\plusone
-\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed
+\unexpanded\def\shipoutrange#1#2%
+ {\begingroup
+ \scratchtoks\emptytoks
+ \dostepwiserecurse{#1}{\numexpr#2-\plusone\relax}\plusone{\etoksapp\scratchtoks{##1,}}%
+ \xdef\pagestoshipout{\the\scratchtoks,\number#2}%
+ \doglobal\appendtoks
+ \ifnum\realpageno>\numexpr#2+\plusone\relax
+ \global\everypar{\normalend}%
+ \fi
+ \to\everyaftershipout
+ \endgroup}
+
+\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed
{\setgvalue{\??shipoutmethod#1}##1{#2{##1}}} % and shipped out (don't depend on the exact package)
\let\installpagehandler\installshipoutmethod % will go
@@ -73,13 +85,6 @@
\unexpanded\def\invokepagehandler#1%
{\expandnamespacevalue\??shipoutmethod{#1}\v!normal}
-% \def\page_shipouts_handle
-% {\csname\??shipoutmethod\ifcsname\??shipoutmethod\v_page_target_method\endcsname
-% \v_page_target_method
-% \else
-% \v!none
-% \fi\endcsname}
-
\def\page_shipouts_handle
{\ifcsname\??shipoutmethod\v_page_target_method\endcsname
\expandafter\lastnamedcs
@@ -112,12 +117,14 @@
\page_boxes_flush_before
\fi
\the\everybeforeshipout
- \ifcase\shipoutfinalizemethod
+ \ifcase\shipoutfinalizemethod % not nice ... needs thinking
\page_shipouts_handle{#1}%
\else
- \setbox\shipoutscratchbox\hpack{#1}% just in case there are objects there, hook for testing (will go away)
- \finalizeshipoutbox\shipoutscratchbox
- \page_shipouts_handle{\box\shipoutscratchbox}%
+ \setbox\shipoutscratchbox\hpack
+ {#1}% just in case there are objects there, hook for testing (will go away)
+ \page_shipouts_handle
+ {\finalizeshipoutbox\shipoutscratchbox
+ \box\shipoutscratchbox}%
\fi
\setnextrealpageno % so this comes before \everyaftershipout so in fact:
\the\everyaftershipout % at this point we're already on the next realpage
@@ -127,11 +134,12 @@
\def\page_shipouts_ignore#1%
{\begingroup
- \message
- {[\ifarrangingpages arranged \fi page
+ \writestatus\m!system
+ {\ifarrangingpages arranged \fi page
\ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace
- not flushed]}%
- \setbox\scratchbox\hpack{#1}%
+ not flushed}%
+ % \setbox\scratchbox\hpack
+ % {#1}% no finalize
\deadcycles\zerocount
\endgroup}
@@ -154,7 +162,11 @@
\box\scratchbox
\endgroup}
-\newdimen\d_page_shipouts_offset \d_page_shipouts_offset=-1in
+\ifdefined \page_shipout_box \else
+
+ \def\page_shipout_box#1{\normalshipout\box#1\relax} % takes a number
+
+\fi
\def\page_shipouts_normal#1%
{\global\advance\shippedoutpages\plusone
@@ -173,30 +185,36 @@
\normalexpanded{\doifelseinset{\the\shippedoutpages}{\pagestoshipout}}\donetrue\donefalse
\fi
\ifdone
- \setbox\shipoutscratchbox\hpack{#1}%
+ \setbox\shipoutscratchbox\hpack
+ {#1}% finalizes
\ifcase\shipoutfinalizemethod
\finalizeshipoutbox\shipoutscratchbox
\fi
- \normalshipout\vpack
- {\offinterlineskip
- \vskip\d_page_shipouts_offset
- \hskip\d_page_shipouts_offset
+ \setbox\shipoutscratchbox\vpack
+ {\scratchdimen\clf_shipoutoffset\relax
+ \ifdim\scratchdimen=\zeropoint\else
+ \offinterlineskip
+ \vkern\scratchdimen
+ \hkern\scratchdimen
+ \fi
\hpack
{\page_otr_flush_every_stuff
\page_otr_flush_special_content
\box\shipoutscratchbox}}%
+ \page_shipout_box\shipoutscratchbox % takes a box number!
\else
\page_shipouts_ignore{#1}%
\fi}
\def\page_shipouts_arrange#1%
- {% \global\advance\shippedoutpages\plusone
- \begingroup
- \setbox\scratchbox\hpack
+ {\begingroup
+ \setbox\shipoutscratchbox\hpack
+ {#1}% finalizes
+ \setbox\shipoutscratchbox\hpack
{\page_otr_flush_every_stuff
\page_otr_flush_special_content
\box\shipoutscratchbox}%
- \pusharrangedpage\scratchbox
+ \pusharrangedpage\shipoutscratchbox
\deadcycles\zerocount
\endgroup}
@@ -310,14 +328,14 @@
\let\pusharrangedpage\relax
\def\dosetuparrangement#1#2#3#4#5#6#7#8%
- {\global\arrangedpageX #1%
- \global\arrangedpageY #2%
- \global\arrangedpageT #3%
- \global\c_page_marks_nx #4%
- \global\c_page_marks_ny #5%
- \global\let\pusharrangedpage #6%
- \global\let\poparrangedpages #7%
- \global\let\handlearrangedpage#8}
+ {\global\arrangedpageX #1%
+ \global\arrangedpageY #2%
+ \global\arrangedpageT #3%
+ \global\c_page_marks_nx #4%
+ \global\c_page_marks_ny #5%
+ \glet \pusharrangedpage #6%
+ \glet \poparrangedpages #7%
+ \glet \handlearrangedpage#8}
\installpagearrangement {\v!normal}
{\global\arrangingpagesfalse}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-inf.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-inf.mkiv
index 2064f9f25be..4519083bf19 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-inf.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-inf.mkiv
@@ -112,14 +112,16 @@
{\vfill
\settexthoffset
\hsize\dimexpr\scratchdimen-2\texthoffset\relax
- \hskip\texthoffset % brrrr
+ \hkern\texthoffset % brrrr
\vbox to \zeropoint{\vss\page_info_place_info}%
- \vskip\bodyfontsize}%
+ \vkern\bodyfontsize}%
\dp\b_page_versions\zeropoint
\wd\b_page_versions\scratchdimen
- \setbox#1\hpack{\box#1\hskip-\scratchdimen\box\b_page_versions}}
+ \setbox#1\hpack{\box#1\hkern-\scratchdimen\box\b_page_versions}}
\setupversion % resets
[\v!final]
+\let\page_info_add_to_box\gobbleoneargument
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/page-ini.lua
index 5b73c972903..3d553412815 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-ini.lua
@@ -41,23 +41,39 @@ function pages.mark(name,list)
local page = list[i]
local sign = false
if type(page) == "string" then
- local s, p = match(page,"([%+%-])(%d+)")
- if s then
- sign, page = s, p
+ local f, t = match(page,"(%d+)[:%-](%d+)")
+ if f and t then
+ f, t = tonumber(f), tonumber(t)
+ if f and t and f <= t then
+ if trace then
+ report("marking page %i upto %i as %a",f,t,name)
+ end
+ for page=f,t do
+ data[page][name] = true
+ end
+ end
+ page = false
+ else
+ local s, p = match(page,"([%+%-])(%d+)")
+ if s then
+ sign, page = s, p
+ end
end
end
- page = tonumber(page)
if page then
- if sign == "+" then
- page = realpage + page
- end
- if sign == "-" then
- report("negative page numbers are not supported")
- else
- if trace then
- report("marking page %i as %a",page,name)
+ page = tonumber(page)
+ if page then
+ if sign == "+" then
+ page = realpage + page
+ end
+ if sign == "-" then
+ report("negative page numbers are not supported")
+ else
+ if trace then
+ report("marking page %i as %a",page,name)
+ end
+ data[page][name] = true
end
- data[page][name] = true
end
end
end
@@ -75,7 +91,6 @@ local function marked(name)
rawset(data,i,nil)
end
local pagedata = rawget(data,realpage)
- print(pagedata and pagedata[name] and true or false)
return pagedata and pagedata[name] and true or false
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-ini.mkiv
index dc94edf7638..38477dc2747 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-ini.mkiv
@@ -80,7 +80,7 @@
\fi}
\def\page_otr_flush_pending_content
- {\vskip\zeropoint\relax
+ {\vkern\zeropoint\relax
\ifvoid\normalpagebox \else
\unvbox\normalpagebox
\penalty\outputpenalty
@@ -256,7 +256,10 @@
\box\pagebox
\egroup \ifconditional\c_page_boxes_save_page_body \copy\b_page_boxes_saved_page_body \fi}
-\appendtoks \restoreglobalbodyfont \to \everybeforepagebody
+\appendtoks
+ \restoreglobalbodyfont
+ \pickupattributes
+\to \everybeforepagebody
\ifdefined\nestednewbox \else \newbox\nestednextbox \fi % hm, still needed?
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-inj.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-inj.mkvi
index cabd07bac14..5f48ffd13dd 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-inj.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-inj.mkvi
@@ -124,7 +124,7 @@
\ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output
\forgetparindent
\dontcomplain
- \setconstant\shipoutfinalizemethod\zerocount
+ \setconstant\shipoutfinalizemethod\zerocount % this is messy
\page_injections_flush_indeed
\fi}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-lay.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-lay.mkiv
index 7b80dadb98b..02cc5aa17f2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-lay.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-lay.mkiv
@@ -13,19 +13,16 @@
\writestatus{loading}{ConTeXt Page Macros / Layout Specification}
-%D Before you start wondering why some of the page related
-%D modules skip upward or left in order to place elements, you
-%D must realize that the reference point is the top left
-%D corner of the main typesetting area. One reason for this
-%D choice is that it suited some viewers that displayed page
-%D areas. Another reason is that margins, edges and top and
-%D bottom areas are kind of virtual, while the header, text
-%D and footer areas normally determine the text flow.
+%D Before you start wondering why some of the page related modules skip upward or
+%D left in order to place elements, you must realize that the reference point is the
+%D top left corner of the main typesetting area. One reason for this choice is that
+%D it suited some viewers that displayed page areas. Another reason is that margins,
+%D edges and top and bottom areas are kind of virtual, while the header, text and
+%D footer areas normally determine the text flow.
\unprotect
-%D The dimensions related to layout areas are represented by
-%D real dimensions.
+%D The dimensions related to layout areas are represented by real dimensions.
\newdimen\paperheight \paperheight = 297mm
\newdimen\paperwidth \paperwidth = 210mm
@@ -69,17 +66,15 @@
\newdimen\totaltextwidth
-%D The next series of dimensions are complemented by left
-%D and rights ones.
+%D The next series of dimensions are complemented by left and rights ones.
\newdimen\margindistance
\newdimen\edgedistance
\newdimen\marginwidth
\newdimen\edgewidth
-%D Because a distance does not really makes sense when there
-%D is no area, we use a zero distance in case there is no
-%D area.
+%D Because a distance does not really makes sense when there is no area, we use a
+%D zero distance in case there is no area.
%D The horizontal distances are:
@@ -149,12 +144,12 @@
\let\currentlayout\empty
\fi
\letlayoutparameter\c!state\v!normal % global ? still needed ?
- \global\let\currentlayout\currentlayout % global
+ \glet\currentlayout\currentlayout % global
\page_layouts_synchronize
\page_layouts_check_next
\or % \setuplayout (reverts to main layout)
\letlayoutparameter\c!state\v!normal % global ? still needed ?
- \global\let\currentlayout\empty % global
+ \glet\currentlayout\empty % global
\page_layouts_synchronize
\page_layouts_check_next
\fi
@@ -244,16 +239,15 @@
\swapmacros\innersidetotal \outersidetotal
\to \everyswapmargins
-%D The papersize macros have a long history and we don't want
-%D to change the commands so they keep looking a bit complex.
+%D The papersize macros have a long history and we don't want to change the commands
+%D so they keep looking a bit complex.
%D \macros
%D {definepapersize}
%D
-%D Before we start calculating layout dimensions, we will
-%D first take care of paper sizes. The first argument can be
-%D either an assignment (for defaults) or an identifier, in
-%D which case the second argument is an assignment.
+%D Before we start calculating layout dimensions, we will first take care of paper
+%D sizes. The first argument can be either an assignment (for defaults) or an
+%D identifier, in which case the second argument is an assignment.
%D
%D \showsetup{definepapersize}
%D
@@ -281,8 +275,8 @@
%D \macros
%D {setuppaper,setuppapersize}
%D
-%D When setting up the papersize on which to typeset and
-%D print, we can also determine some more characteristics.
+%D When setting up the papersize on which to typeset and print, we can also
+%D determine some more characteristics.
%D
%D \showsetup{setuppapersize}
%D
@@ -335,9 +329,8 @@
\def\v_page_target_xy {\numexpr\v_page_target_nx*\v_page_target_ny\relax}
-% Normally we will not use this command directly but for now it
-% works out okay. In the future we might use more of the related
-% commands.
+%D Normally we will not use this command directly but for now it works out okay. In
+%D the future we might use more of the related commands.
\setuplayouttarget
[% these are rather special
@@ -462,7 +455,7 @@
\appendtoks
\page_paper_reinstate
- \global\let\page_paper_reinstate\relax
+ \glet\page_paper_reinstate\relax
\to \everyaftershipout
\unexpanded\def\page_paper_set_restore#1#2%
@@ -538,7 +531,7 @@
\ifx\currentlayouttarget\empty
\let\currentlayouttarget\currentpage
\fi
- \global\let\papersize\currentlayouttarget
+ \glet\papersize\currentlayouttarget
\page_paper_reset_paper
\processcommacommand[\m_page_asked_paper]\page_paper_handle_page_option
\global\paperwidth \layouttargetparameter\c!width \relax
@@ -561,7 +554,7 @@
% locate paper target
\page_paper_reset_print
\processcommacommand[\m_page_asked_print]\page_paper_identify_target
- \global\let\printpapersize\currentlayouttarget
+ \glet\printpapersize\currentlayouttarget
\page_paper_reset_print
\processcommacommand[\m_page_asked_print]\page_paper_handle_print_option
\global\printpaperwidth \layouttargetparameter\c!width \relax
@@ -814,18 +807,18 @@
{\edef\m_page_check{#1}
\edef\m_page_state{\namedlayoutparameter\m_page_check\c!state}%
\ifx\m_page_state\v!start
- \global\let\v_page_layouts_pre_check\currentlayout
- \global\let\currentlayout\m_page_check
+ \glet\v_page_layouts_pre_check\currentlayout
+ \glet\currentlayout\m_page_check
\page_layouts_synchronize
\else\ifx\m_page_state\v!repeat
- \global\let\v_page_layouts_pre_check\relax
- \global\let\currentlayout\m_page_check
+ \glet\v_page_layouts_pre_check\relax
+ \glet\currentlayout\m_page_check
\page_layouts_synchronize
\fi\fi}
\def\page_layouts_check_revert
- {\global\let\currentlayout\v_page_layouts_pre_check
- \global\let\v_page_layouts_pre_check\relax
+ {\glet\currentlayout\v_page_layouts_pre_check
+ \glet\v_page_layouts_pre_check\relax
\page_layouts_synchronize}
\def\page_layouts_check_default
@@ -996,6 +989,7 @@
\newdimen\d_page_adepts_pushed_text_height
\newdimen\d_page_adepts_pushed_footer_height
\newdimen\d_page_adepts_height
+\newdimen\d_page_adapts_delta
\unexpanded\def\adaptlayout
{\dodoubleempty\page_adapts_layout}
@@ -1040,8 +1034,8 @@
\page_otr_command_set_vsize
%
\page_backgrounds_recalculate
- \global\let\page_adepts_push\relax
- \global\let\page_adepts_pop\page_adepts_pop_indeed}
+ \glet\page_adepts_push\relax
+ \glet\page_adepts_pop\page_adepts_pop_indeed}
% \def\page_adapts_check
% {\csname\??pageadaptations\the\ifcsname\??pageadaptations\the\realpageno\endcsname\realpageno\else\zerocount\fi\endcsname}
@@ -1067,8 +1061,8 @@
{\global\textheight \d_page_adepts_pushed_text_height
\global\footerheight\d_page_adepts_pushed_footer_height
\page_layouts_synchronize
- \global\let\page_adepts_push\page_adepts_push_indeed
- \global\let\page_adepts_pop\relax}
+ \glet\page_adepts_push\page_adepts_push_indeed
+ \glet\page_adepts_pop\relax}
\appendtoks \page_adapts_check \to \everystarttext
\appendtoks \page_adapts_reset \to \everyshipout
@@ -1153,8 +1147,8 @@
\def\compensatedinnermakeupmargin
{\dimexpr\ifconditional\innermakeupcompensation+\innermakeupmargin\else\zeropoint\fi\relax}
-\unexpanded\def\freezetextwidth % name will change % \makeupwidth may be set to \textwidth
- {\textwidth\makeupwidth % which is a tricky but valid value
+\unexpanded\def\freezetextwidth % name will change % \makeupwidth may be set to \textwidth
+ {\textwidth\makeupwidth % which is a tricky but valid value
\edef\m_currentlayout_text_width {\layoutparameter\c!textwidth }%
\edef\m_currentlayout_text_margin{\layoutparameter\c!textmargin}%
\ifx\m_currentlayout_text_width\empty \else
@@ -1174,15 +1168,9 @@
{\freezetextwidth
\page_otr_command_set_hsize}
-% The next few are better off in page-ini.mkiv
-
-%D When we start at an even page, we need to swap the layout
-%D differently. We cannot adapt the real page number, since
-%D it is used in cross referencing. The next switch is set
-%D when we start at an even page.
-
-% We could use nested if here plus some \@EAEAEA's but but the
-% next variant has less expansion which is nicer in tracing.
+%D When we start at an even page, we need to swap the layout differently. We cannot
+%D adapt the real page number, since it is used in cross referencing. The next
+%D switch is set when we start at an even page.
% #single #left #right
@@ -1262,7 +1250,7 @@
% \to \everybeforeshipout
\def\goleftonpage % name will change (we could cache)
- {\hskip-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax}
+ {\hkern-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax}
\def\doifelsemarginswap#1#2%
{\doifbothsides{#1}{#1}{#2}}
@@ -1327,12 +1315,9 @@
%D \macros
%D {startlocallayout}
%D
-%D These macros should be used with care. They permit local
-%D layouts (as used in fitting pages, see \type {page-app.tex}).
-
-%D This is kind of obsolete now that we have \type
-%D {\definelayout}, so this hack will disappear in future
-%D versions.
+%D These macros should be used with care. They permit local layouts (as used in
+%D fitting pages, see \type {page-app.tex}). This is kind of obsolete now that we
+%D have \type {\definelayout}, so this hack will disappear in future versions.
\unexpanded\def\startlocallayout
{\globalpushmacro\page_paper_restore
@@ -1367,19 +1352,16 @@
\glet\page_grids_add_to_one\gobbleoneargument
\glet\page_grids_add_to_mix\gobbleoneargument
-%D The default dimensions are quite old and will not change.
-%D The funny fractions were introduced when we went from fixed
-%D dimensions to relative ones. Since \CONTEXT\ is a dutch
-%D package, the dimensions are based on the metric system. The
-%D asymmetrical layout is kind of handy for short
-%D quick||and||dirty stapled documents.
+%D The default dimensions are quite old and will not change. The funny fractions
+%D were introduced when we went from fixed dimensions to relative ones. Since
+%D \CONTEXT\ is a dutch package, the dimensions are based on the metric system. The
+%D asymmetrical layout is kind of handy for short quick||and||dirty stapled
+%D documents.
%D
-%D Although valid, it is not a real good idea to use
-%D dimensions based on the \type {em} unit. First of all,
-%D since there are no fonts loaded yet, this dimension makes
-%D no sense, and second, you would loose track of values,
-%D since they could change while going to a new page,
-%D depending on the current font setting.
+%D Although valid, it is not a real good idea to use dimensions based on the \type
+%D {em} unit. First of all, since there are no fonts loaded yet, this dimension
+%D makes no sense, and second, you would loose track of values, since they could
+%D change while going to a new page, depending on the current font setting.
\setuplayout
[ \c!topspace=.08417508418\paperheight, % 2.5cm
@@ -1435,8 +1417,8 @@
\c!columns=\plusone,
\c!columndistance=\zeropoint]
-%D First we define a whole range of (DIN) papersizes,
-%D of which the A-series makes most sense. We enable checking.
+%D First we define a whole range of (DIN) papersizes, of which the A-series makes
+%D most sense. We enable checking.
\definepapersize [A0] [\c!width=841mm,\c!height=1189mm]
\definepapersize [A1] [\c!width=594mm,\c!height=841mm]
@@ -1477,18 +1459,17 @@
\definepapersize [C9] [\c!width=40mm,\c!height=57mm]
\definepapersize [C10] [\c!width=28mm,\c!height=40mm]
-%D Per August 2004 the rounding of some (seldom used) sizes
-%D were corrected top the latest DIN specifications. Peter
-%D Rolf came up with these and a few more missing sizes.
-%D Watch out: spaces and slashes!
+%D Per August 2004 the rounding of some (seldom used) sizes were corrected top the
+%D latest DIN specifications. Peter Rolf came up with these and a few more missing
+%D sizes. Watch out: spaces and slashes!
\definepapersize [4 A0] [\c!width=1682mm,\c!height=2378mm]
\definepapersize [2 A0] [\c!width=1189mm,\c!height=1682mm]
\definepapersize [C6/C5] [\c!width=114mm,\c!height=229mm]
-%D Because there are no standardized screen sizes, we define
-%D a bunch of sizes with $4:3$ ratios. The \type {S6} size is
-%D nearly as wide as a sheet of \type {A4} paper.
+%D Because there are no standardized screen sizes, we define a bunch of sizes with
+%D $4:3$ ratios. The \type {S6} size is nearly as wide as a sheet of \type {A4}
+%D paper.
\definepapersize [S3] [\c!width=300pt,\c!height=225pt]
\definepapersize [S4] [\c!width=400pt,\c!height=300pt]
@@ -1509,15 +1490,13 @@
\definepapersize [S55] [\c!width=500pt,\c!height=500pt]
\definepapersize [S66] [\c!width=600pt,\c!height=600pt]
-%D One may wonder if \TEX\ should be used for typesetting
-%D \CDROM\ covers, but it does not hurt to have the paper size
-%D ready.
+%D One may wonder if \TEX\ should be used for typesetting \CDROM\ covers, but it
+%D does not hurt to have the paper size ready.
\definepapersize [CD] [\c!width=120mm,\c!height=120mm]
-%D The next series is for our English speaking friends who
-%D decided to stick to non metric values. Thanks to Nelson
-%D Beebe for completing the inch based list.
+%D The next series is for our English speaking friends who decided to stick to non
+%D metric values. Thanks to Nelson Beebe for completing the inch based list.
\definepapersize [letter] [\c!width=8.5in,\c!height=11in]
\definepapersize [ledger] [\c!width=11in,\c!height=17in]
@@ -1573,9 +1552,9 @@
\definepapersize [business] [\c!width=85mm,\c!height=55mm]
\definepapersize [businessUS] [\c!width=3.5in,\c!height=2in]
-%D We can now default to a reasonable size. We match the print
-%D paper size with the typeset paper size. This setting should
-%D come after the first layout specification (already done).
+%D We can now default to a reasonable size. We match the print paper size with the
+%D typeset paper size. This setting should come after the first layout specification
+%D (already done).
% \definepapersize
% [\v!default]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-lin.lua b/Master/texmf-dist/tex/context/base/mkiv/page-lin.lua
index a6b6a12c400..3689c7f8d1d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-lin.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-lin.lua
@@ -43,15 +43,14 @@ local v_no = variables.no
local properties = nodes.properties
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
-local whatcodes = nodes.whatcodes
local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local whatsit_code = nodecodes.whatsit
local glyph_code = nodecodes.glyph
-local line_code = listcodes.line
+
+local linelist_code = listcodes.line
local a_displaymath = attributes.private('displaymath')
local a_linenumber = attributes.private('linenumber')
@@ -71,7 +70,7 @@ local getattr = nuts.getattr
local setattr = nuts.setattr
local getlist = nuts.getlist
local getbox = nuts.getbox
------ getdir = nuts.getdir
+----- getdirection = nuts.getdirection
----- getwidth = nuts.getwidth
local getheight = nuts.getheight
local getdepth = nuts.getdepth
@@ -79,8 +78,9 @@ local getdepth = nuts.getdepth
local setprop = nuts.setprop
local getprop = nuts.getprop
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
+local nexthlist = nuts.traversers.hlist
+local nextvlist = nuts.traversers.vlist
+
local copy_node = nuts.copy
----- hpack_nodes = nuts.hpack
local is_display_math = nuts.is_display_math
@@ -224,7 +224,9 @@ implement {
local function check_number(n,a,skip,sameline)
local d = data[a]
if d then
- local tag, skipflag, s = d.tag or "", 0, d.start or 1
+ local tag = d.tag or ""
+ local skipflag = 0
+ local s = d.start or 1
current_list[#current_list+1] = { n, s }
if sameline then
skipflag = 0
@@ -244,7 +246,7 @@ local function check_number(n,a,skip,sameline)
end
local p = checkline(n)
if p then
- ctx_makelinenumber(tag,skipflag,s,p.hsize,p.reverse and "TRT" or "TLT")
+ ctx_makelinenumber(tag,skipflag,s,p.hsize,p.reverse and 1 or 0)
else
report_lines("needs checking")
end
@@ -283,8 +285,8 @@ end
local function listisnumbered(list)
if list then
- for n in traverse_id(hlist_code,list) do
- if getsubtype(n) == line_code then
+ for n, subtype in nexthlist, list do
+ if subtype == linelist_code then
local a = getattr(n,a_linenumber)
if a then
-- a quick test for lines (only valid when \par before \stoplinenumbering)
@@ -306,7 +308,7 @@ local function findnumberedlist(list)
while n do
local id = getid(n)
if id == hlist_code then
- if getsubtype(n) == line_code then
+ if getsubtype(n) == linelist_code then
local a = getattr(n,a_linenumber)
if a then
return a > 0 and list
@@ -383,9 +385,8 @@ function boxed.stage_one(n,nested)
local skip = false
local function check()
- for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
- local subtype = getsubtype(n)
- if subtype ~= line_code then
+ for n, subtype in nexthlist, list do
+ if subtype ~= linelist_code then
-- go on
elseif getheight(n) == 0 and getdepth(n) == 0 then
-- skip funny hlists -- todo: check line subtype
@@ -450,7 +451,7 @@ function boxed.stage_one(n,nested)
if not list then
return
end
- for n in traverse_id(vlist_code,list) do
+ for n in nextvlist, list do
local p = properties[n]
if p and p.columngap then
if trace_numbers then
@@ -472,18 +473,21 @@ end
function boxed.stage_two(n,m)
if #current_list > 0 then
m = m or lines.scratchbox
- local t, tn = { }, 0
- for l in traverse_id(hlist_code,getlist(getbox(m))) do
+ local t = { }
+ local tn = 0
+ for l in nexthlist, getlist(getbox(m)) do
tn = tn + 1
t[tn] = copy_node(l) -- use take_box instead
end
for i=1,#current_list do
local li = current_list[i]
- local n, m, ti = li[1], li[2], t[i]
+ local n = li[1]
+ local m = li[2]
+ local ti = t[i]
if ti then
- -- local d = getdir(n)
+ -- local d = getdirection(n)
-- local l = getlist(n)
- -- if d == "TRT" then
+ -- if d == 1 then
-- local w = getwidth(n)
-- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w)))
-- end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-lin.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-lin.mkvi
index 4348d677065..a27ba5736c5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-lin.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-lin.mkvi
@@ -46,6 +46,10 @@
\attribute\linenumberattribute\attributeunsetvalue
\to \everyforgetall
+\appendtoks
+ \attribute\linenumberattribute \attributeunsetvalue
+\to \everyinsidefloat
+
\newcount \linenumber % not used
\newbox \b_page_lines_scratch
\newcount \c_page_lines_reference
@@ -275,8 +279,8 @@
\fi\fi\fi
\fi
\the\beforeeverylinenumbering
- \globallet\page_postprocessors_page \page_postprocessors_linenumbers_page
- \globallet\page_postprocessors_column\page_postprocessors_linenumbers_column
+ \glet\page_postprocessors_page \page_postprocessors_linenumbers_page
+ \glet\page_postprocessors_column\page_postprocessors_linenumbers_column
\global\settrue\page_postprocessors_needed_box % see core-rul.mkiv
\ifcase\c_page_lines_mode\relax
\page_lines_start_update % continue
@@ -349,7 +353,7 @@
\d_page_lines_distance\linenumberingparameter\c!distance\relax
\edef\p_align{\linenumberingparameter\c!align}%
\edef\p_location{\linenumberingparameter\c!location}%
- \ifcase\istltdir#dir\relax
+ \ifcase#dir\relax
\settrue \c_page_lines_dir_left_to_right
\else
\setfalse\c_page_lines_dir_left_to_right
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-mix.lua b/Master/texmf-dist/tex/context/base/mkiv/page-mix.lua
index 107ac14102c..192b8a30aa6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-mix.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-mix.lua
@@ -69,8 +69,6 @@ local getpenalty = nuts.getpenalty
local getwidth = nuts.getwidth
local getheight = nuts.getheight
local getdepth = nuts.getdepth
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
local theprop = nuts.theprop
@@ -829,23 +827,6 @@ local function report_deltas(result,str)
report_state("%s, cycles %s, deltas % | t",str,result.cycle or 1,t)
end
--- local function xxcollectinserts(h)
--- local skips, total, order = 0, 0, 0
--- print(h)
--- if h then
--- h = getlist(h)
--- for n in traverse(h) do
--- print(tonode(n))
--- end
--- for n in traverse_id(insert_code,h) do
--- order = order + 1
--- total = total + getheight(n)
--- skips = skips + structures.notes.check_spacing(getsubtype(n),order)
--- end
--- end
--- return skips, total
--- end
-
local function setsplit(specification)
splitruns = splitruns + 1
if trace_state then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-mix.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-mix.mkiv
index 684ebc5854a..436c4a1dcf6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-mix.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-mix.mkiv
@@ -371,6 +371,9 @@
\let\currentmixedcolumnsmethod\empty
+\installmacrostack\currentmixedcolumns
+\installmacrostack\currentmixedcolumnsmethod
+
\unexpanded\def\startmixedcolumns
{\dodoubleempty\page_mix_start_columns}
@@ -385,8 +388,8 @@
\fi\fi}
\unexpanded\def\page_mix_start_columns
- {\pushmacro\currentmixedcolumns
- \pushmacro\currentmixedcolumnsmethod
+ {\push_macro_currentmixedcolumns
+ \push_macro_currentmixedcolumnsmethod
\ifsecondargument
\singleexpandafter\page_mix_start_columns_a
\else\iffirstargument
@@ -462,8 +465,8 @@
\let\stopmixedcolumns\page_mix_columns_stop_nop}
\unexpanded\def\page_mix_fast_columns_start#1%
- {\pushmacro\currentmixedcolumns
- \pushmacro\currentmixedcolumnsmethod
+ {\push_macro_currentmixedcolumns
+ \push_macro_currentmixedcolumnsmethod
\edef\currentmixedcolumns{#1}%
\edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}%
\mixedcolumnsparameter\c!before\relax % so, it doesn't listen to local settings !
@@ -492,15 +495,15 @@
\endgroup
\begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax
\mixedcolumnsparameter\c!after\relax
- \popmacro\currentmixedcolumnsmethod
- \popmacro\currentmixedcolumns
+ \pop_macro_currentmixedcolumnsmethod
+ \pop_macro_currentmixedcolumns
\the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks}
\unexpanded\def\page_mix_columns_stop_nop
{\page_mix_finalize_columns
\endgroup
- \popmacro\currentmixedcolumnsmethod
- \popmacro\currentmixedcolumns
+ \pop_macro_currentmixedcolumnsmethod
+ \pop_macro_currentmixedcolumns
\the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks}
% \unexpanded\def\page_mix_columns_stop_yes
@@ -509,12 +512,12 @@
% \begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax
% \mixedcolumnsparameter\c!after\relax
% \ifx\currentmixedcolumnsmethod\s!otr
-% \popmacro\currentmixedcolumnsmethod
-% \popmacro\currentmixedcolumns
+% \pop_macro_currentmixedcolumnsmethod
+% \pop_macro_currentmixedcolumns
% \synchronizeoutput % brrr, otherwise sometimes issues in itemize
% \else
-% \popmacro\currentmixedcolumnsmethod
-% \popmacro\currentmixedcolumns
+% \pop_macro_currentmixedcolumnsmethod
+% \pop_macro_currentmixedcolumns
% \fi
% }
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-mul.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-mul.mkiv
index 51af24b6a86..957981703e4 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-mul.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-mul.mkiv
@@ -471,7 +471,7 @@
\page_mul_postprocess_lines
\page_mul_postprocess_columns
\dohandleallcolumns
- {\global\setbox\currentcolumnbox\hbox to \d_page_mul_used_width
+ {\global\setbox\currentcolumnbox\hpack to \d_page_mul_used_width
{\box\currentcolumnbox}%
\wd\currentcolumnbox\d_page_mul_used_width
\ifheightencolumns
@@ -479,12 +479,12 @@
\fi}%
\page_mul_calculate_column_result_dimensions
\overlaycolumnfootnotes
- \setbox\columnpagebox\vbox
- {\hbox \ifconditional\c_page_mul_reverse dir TRT \fi to \makeupwidth
+ \setbox\columnpagebox\vpack % \vbox
+ {\ifconditional\c_page_mul_reverse\reversehpack\else\naturalhpack\fi to \makeupwidth
{\hskip\ifconditional\c_page_mul_reverse\d_page_mul_rightskip\else\d_page_mul_leftskip\fi\relax
\dohandleallcolumns
{\finishcolumnbox
- {\setbox\scratchbox\hbox
+ {\setbox\scratchbox\hpack
{\ifx\finishcolumnbox\relax\else\strut\fi
\box\currentcolumnbox}% hm, why strut
\anch_mark_column_box\scratchbox
@@ -499,13 +499,13 @@
\fi
\global\setbox\currenttopcolumnbox\emptybox}%
\advance\scratchdimen \ht\columnpagebox
- \setbox\scratchbox\hbox to \makeupwidth
+ \setbox\scratchbox\hbox to \makeupwidth % between can be something so no \hpack
{\vrule
\s!width \zeropoint
\s!height\scratchdimen
\s!depth \dp\columnpagebox
\dostepwiserecurse\plustwo\nofcolumns\plusone{\hfil\page_mul_between_columns}\hfil}%
- \setbox\columnpagebox\hbox
+ \setbox\columnpagebox\hpack
{\box\columnpagebox
\hskip-\makeupwidth
\box\scratchbox}%
@@ -761,7 +761,7 @@
\page_mul_set_n_of_lines
\advance\c_page_mul_n_of_lines \minustwo
\scratchdimen\dimexpr\c_page_mul_n_of_lines\lineheight+\topskip\relax
- \setbox\b_page_mul_notes\hbox{\lower\scratchdimen\box\b_page_mul_notes}%
+ \setbox\b_page_mul_notes\hpack{\lower\scratchdimen\box\b_page_mul_notes}%
\ht\b_page_mul_notes\openstrutheight
\dp\b_page_mul_notes\openstrutdepth
\wd\b_page_mul_notes\zeropoint
@@ -784,7 +784,7 @@
\getnoflines\scratchdimen
\advance\noflines \minustwo
\scratchdimen\dimexpr\noflines\lineheight+\topskip\relax
- \setbox\b_page_mul_notes\hbox{\lower\scratchdimen\box\b_page_mul_notes}%
+ \setbox\b_page_mul_notes\hpack{\lower\scratchdimen\box\b_page_mul_notes}%
\ht\b_page_mul_notes\openstrutheight
\dp\b_page_mul_notes\openstrutdepth
\wd\b_page_mul_notes\zeropoint
@@ -890,6 +890,7 @@
\def\page_mul_routine_balance
{\bgroup
+ % why no \forgetall here
\page_mul_initialize_variables
\widowpenalty\zerocount
\setbox\b_page_mul_balance_content\vbox{\unvbox\normalpagebox}%
@@ -1135,7 +1136,7 @@
% \global\savednoffloats\zerocount
% \global\setfalse\c_page_floats_some_waiting
% \else
-% \global\let\page_floats_column_pop_saved\relax
+% \glet\page_floats_column_pop_saved\relax
% \fi}
%
% \let\page_floats_column_pop_saved\relax
@@ -1249,7 +1250,7 @@
\xdef\insertionheight{\the\dimen0}%
\egroup
\else
- \global\let\insertionheight\zeropoint
+ \glet\insertionheight\zeropoint
\fi}
\def\docolumnroomfloat
@@ -1364,7 +1365,7 @@
\global\setbox\currenttopcolumnbox\vbox
{\snaptogrid\vbox
{\copy\currenttopcolumnbox
- \hbox{\vphantom{\vskip\floatheight}}}% known from previous
+ \hpack{\vphantom{\vskip\floatheight}}}% known from previous
\whitespace % nodig ?
\blank[\rootfloatparameter\c!spaceafter]}%
\else
@@ -1848,4 +1849,17 @@
\s!page_otr_command_test_column =\page_mul_command_test_column
]
+\installfloatmethod \s!multicolumn \v!here \page_mul_place_float_here
+\installfloatmethod \s!multicolumn \v!force \page_mul_place_float_force
+\installfloatmethod \s!multicolumn \v!top \page_mul_place_float_top
+\installfloatmethod \s!multicolumn \v!bottom \page_mul_place_float_bottom
+
+\appendtoks
+ \flushingcolumnfloatsfalse
+\to \everybeforesectionheadhandle
+
+\appendtoks
+ \flushingcolumnfloatstrue
+\to \everyaftersectionheadhandle
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-one.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-one.mkiv
index 348c301fc2c..64c4a713498 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-one.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-one.mkiv
@@ -73,6 +73,7 @@
\else
\global\vsize\textheight
\fi
+ \global\advance\vsize\d_page_adapts_delta
% alternatively we could set it in builders.buildpage_filter
% \ifdim\pagegoal<\maxdimen .. \fi
\global\pagegoal\dimexpr\vsize-\d_page_floats_inserted_top-\d_page_floats_inserted_bottom\relax}
@@ -141,16 +142,17 @@
{\page_otr_command_flush_top_insertions
% this is messy ... we will provide a more tight area (no big deal as we can
% do that at the lua end)
+% \parfillskip\zeropoint
\page_one_registered_text_area_a#1#2% \unvbox
%
\ifgridsnapping
- \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
+ \vkern\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
\prevdepth\openstrutdepth
\page_otr_command_flush_bottom_insertions
\vfil
\else\ifcase\bottomraggednessmode
% ragged (default)
- \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
+ \vkern\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
\prevdepth\openstrutdepth
\page_otr_command_flush_bottom_insertions
\vfil
@@ -159,7 +161,7 @@
\page_otr_command_flush_bottom_insertions
\or
% baseline
- \kern\dimexpr\maxdepth-\d_page_one_natural_depth\relax
+ \vkern\dimexpr\maxdepth-\d_page_one_natural_depth\relax
\page_otr_command_flush_bottom_insertions
\fi\fi
\fakepagenotes}%
@@ -228,6 +230,9 @@
\vskip\s_page_one_between_top_insert
\egroup}
+\let\totaltopinserted\!!zeropoint
+\let\totalbotinserted\!!zeropoint
+
\unexpanded\def\page_one_command_set_top_insertions
{\bgroup
\ifconditional\c_page_floats_some_waiting
@@ -312,38 +317,44 @@
\unexpanded\def\page_one_command_flush_top_insertions
{\ifvoid\namedinsertionnumber\s!topfloat\else
- \ifgridsnapping
- \box\namedinsertionnumber\s!topfloat
- \vskip-\topskip
- \vskip\strutheight % [xx] new: see icare topbleed
- \else
- \ifcase\c_page_floats_insertions_topskip_mode
- % 0: default, do nothing
- \or
- % 1: no topskip (crossed fingers)
- \vskip-\topskip
- \vskip\strutheight
- \fi
- \unvbox\namedinsertionnumber\s!topfloat
- \fi
+ \page_one_command_flush_top_insertions_indeed % less tracing
\fi
\global\d_page_floats_inserted_top\zeropoint}
+\def\page_one_command_flush_top_insertions_indeed
+ {\ifgridsnapping
+ \box\namedinsertionnumber\s!topfloat
+ \vkern-\topskip
+ \vkern\strutheight % [xx] new: see icare topbleed
+ \else
+ \ifcase\c_page_floats_insertions_topskip_mode
+ % 0: default, do nothing
+ \or
+ % 1: no topskip (crossed fingers)
+ \vskip-\topskip % skip !
+ \vkern\strutheight
+ \fi
+ \unvbox\namedinsertionnumber\s!topfloat
+ \fi}
+
\unexpanded\def\page_one_command_flush_bottom_insertions
{\ifvoid\namedinsertionnumber\s!bottomfloat\else
- \ifgridsnapping
- % \floatparameter\c!bottombefore
- \snaptogrid\hbox{\box\namedinsertionnumber\s!bottomfloat}%
- % \floatparameter\c!bottomafter
- \else
- \floatparameter\c!bottombefore
- \unvbox\namedinsertionnumber\s!bottomfloat
- \floatparameter\c!bottomafter
- \fi
+ \page_one_command_flush_bottom_insertions_indeed
\fi
\global\d_page_floats_inserted_bottom\zeropoint
\global\setfalse\c_page_floats_not_permitted}
+\def\page_one_command_flush_bottom_insertions_indeed
+ {\ifgridsnapping
+ % \floatparameter\c!bottombefore
+ \snaptogrid\hbox{\box\namedinsertionnumber\s!bottomfloat}%
+ % \floatparameter\c!bottomafter
+ \else
+ \floatparameter\c!bottombefore
+ \unvbox\namedinsertionnumber\s!bottomfloat
+ \floatparameter\c!bottomafter
+ \fi}
+
\unexpanded\def\page_one_command_flush_floats
{\global\settrue\c_page_floats_flushing
\ifconditional\c_page_floats_some_waiting
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-otr.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-otr.mkvi
index ebaf17ebc6d..909f5cd4d1e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-otr.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-otr.mkvi
@@ -97,7 +97,7 @@
\newconstant\c_page_otr_eject_penalty \c_page_otr_eject_penalty -\plustenthousand
\newconstant\c_page_otr_super_penalty \c_page_otr_super_penalty -\plustwentythousand
-\newcount \c_page_otf_trigger_penalty \c_page_otf_trigger_penalty -100010
+\newcount \c_page_otr_trigger_penalty \c_page_otr_trigger_penalty -100010
\newif \ifinotr % we keep this (name) for old times sake
@@ -127,9 +127,9 @@
\endgroup}
\unexpanded\def\installoutputroutine#invoke#action% \invoke \action
- {\global\advance\c_page_otf_trigger_penalty\minusone
- \edef#invoke{\page_otr_trigger{\number\c_page_otf_trigger_penalty}}%
- \setvalue{\??otrtriggers\number\c_page_otf_trigger_penalty}{#action}}
+ {\global\advance\c_page_otr_trigger_penalty\minusone
+ \edef#invoke{\page_otr_trigger{\number\c_page_otr_trigger_penalty}}%
+ \setvalue{\??otrtriggers\number\c_page_otr_trigger_penalty}{#action}}
\unexpanded\def\page_otr_triggered_output_routine_traced
{\ifcsname\??otrtriggers\the\outputpenalty\endcsname
@@ -160,7 +160,7 @@
\ifdefined\everybeforeoutput \else \newtoks\everybeforeoutput \fi
\ifdefined\everyafteroutput \else \newtoks\everyafteroutput \fi
-\def\page_otf_set_engine_output_routine#content%
+\def\page_otr_set_engine_output_routine#content%
{\global\output
{\inotrtrue
\the\everybeforeoutput
@@ -172,7 +172,7 @@
% \ifdefined\everybeforeoutputgroup \else \newtoks\everybeforeoutputgroup \fi
% \ifdefined\everyafteroutputgroup \else \newtoks\everyafteroutputgroup \fi
%
-% \def\page_otf_set_engine_output_routine#content%
+% \def\page_otr_set_engine_output_routine#content%
% {\the\everybeforeoutputgroup
% \global\output
% {\inotrtrue
@@ -187,7 +187,7 @@
% \fi
% \to \everyafteroutputgroup
-\page_otf_set_engine_output_routine\page_otr_triggered_output_routine
+\page_otr_set_engine_output_routine\page_otr_triggered_output_routine
\installoutputroutine\synchronizeoutput % use \triggerpagebuilder instead
{\ifvoid\normalpagebox\else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-pcl.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-pcl.mkiv
index 53d9f781dbf..140444fc27b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-pcl.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-pcl.mkiv
@@ -30,19 +30,18 @@
\definemeasure[threecolumns][\dimexpr\plusthree\columnwidth+\plustwo \columndistance\relax]
\definemeasure[fourcolumns] [\dimexpr\plusfour \columnwidth+\plusthree\columndistance\relax]
-\newcount\c_page_col_n_of_columns \c_page_col_n_of_columns\plusone
-\newcount\c_page_col_current \c_page_col_current \plusone
-\newdimen\d_page_col_distance
-\newdimen\d_page_col_max_height
-\newdimen\d_page_col_max_width
-%newdimen\d_page_col_balance_step
-\newdimen\d_page_col_column_width
-
-\newdimen\d_page_col_top_height
-\newdimen\d_page_col_top_width
-
-\newdimen\d_page_col_available
-\newdimen\d_page_col_sofar
+\newcount \c_page_col_n_of_columns \c_page_col_n_of_columns\plusone
+\newcount \c_page_col_current \c_page_col_current \plusone
+\newdimen \d_page_col_distance
+\newdimen \d_page_col_max_height
+\newdimen \d_page_col_max_width
+%newdimen \d_page_col_balance_step
+\newdimen \d_page_col_column_width
+\newdimen \d_page_col_top_height
+\newdimen \d_page_col_top_width
+\newdimen \d_page_col_available
+\newdimen \d_page_col_sofar
+\newconditional\c_page_col_page
%D We need to step over empty columns.
@@ -700,6 +699,7 @@
\setuppagecolumns
[\c!distance=1.5\bodyfontsize,
\c!n=\plustwo,
+ \c!page=\v!yes,
%\c!align=, % inherit (also replaces tolerance)
%\c!before=,
%\c!after=,
@@ -727,9 +727,39 @@
\ifdefined \columnwidth \else \newdimen\columnwidth \fi
\ifdefined \columndistance \else \newdimen\columndistance \fi
+\def\page_col_pickup_preceding
+ {\begingroup
+ \setupoutputroutine[\s!mixedcolumn]%
+ \c_page_mix_routine\c_page_mix_routine_intercept
+ \page_otr_trigger_output_routine
+ \ifvoid\b_page_mix_preceding \else
+ % moved here, before the packaging
+ \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding
+ % we need to avoid unvboxing with successive balanced on one page
+ \global\setbox\b_page_mix_preceding\vbox\bgroup
+ % yes or no: \forcestrutdepth
+ \unvbox\b_page_mix_preceding
+ \forcestrutdepth
+ \egroup
+ \wd\b_page_mix_preceding\makeupwidth
+ \global\d_page_mix_preceding_height\ht\b_page_mix_preceding
+ \fi
+ \endgroup}
+
+\def\page_col_flush_preceding
+ {\ifvoid\b_page_mix_preceding \else
+ % this is just one method but ok for now
+ \begingroup
+ % we might need more but for now this is ok
+ \setupfloat[\c!spacebefore=,\c!spaceafter=]%
+ \startplacefigure[\c!location={\v!top,\v!none}]%
+ \box\b_page_mix_preceding
+ \stopplacefigure
+ \endgroup
+ \fi}
+
\unexpanded\def\startpagecolumns
- {\page
- \begingroup
+ {\begingroup
\begingroup
\dosingleempty\page_col_start}
@@ -738,6 +768,15 @@
{\let\currentpagecolumns\empty
\setuppagecolumns[#1]}%
{\edef\currentpagecolumns{#1}}%
+ \edef\p_page{\pagecolumnsparameter\c!page}%
+ \ifx\p_page\empty
+ \setfalse\c_page_col_page
+ \else\ifx\p_page\v!no
+ \setfalse\c_page_col_page
+ \else
+ \settrue\c_page_col_page
+ \page[\p_page]%
+ \fi\fi
\c_page_col_n_of_columns\pagecolumnsparameter\c!n\relax
\ifnum\c_page_col_n_of_columns>\plusone
\expandafter\page_col_start_yes
@@ -769,13 +808,21 @@
\useblankparameter \pagecolumnsparameter
% \useprofileparameter\pagecolumnsparameter
%
- \usemixedcolumnscolorparameter\c!color
+ \usepagecolumnscolorparameter\c!color
%
\setupnotes[\c!width=\textwidth]%
%
\usesetupsparameter\pagecolumnsparameter
%
+ % This will become a method but for now it's good enough
+ %
+ \ifconditional\c_page_col_page\else
+ \page_col_pickup_preceding
+ \fi
\setupoutputroutine[\s!pagecolumn]%
+ \ifconditional\c_page_col_page\else
+ \page_col_flush_preceding
+ \fi
%
\setupfloats[\c!ntop=\plusthousand]%
% \setupfloats[\c!nbottom=\plusthousand]%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-run.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-run.mkiv
index 19adfaa9c17..85da8d9e5fb 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-run.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-run.mkiv
@@ -153,6 +153,7 @@
\v!right=>\c_page_grids_lineno_mode \plusone,
\v!left=>\c_page_grids_lineno_mode \plustwo,
\v!outer=>\c_page_grids_lineno_mode \plusthree,
+ \v!inner=>\c_page_grids_lineno_mode \plusfour,
\v!columns=>\c_page_grids_columns_mode\plusone]% new option
\ifcase\c_page_grids_location
\let\page_grids_add_to_box\gobbleoneargument
@@ -179,13 +180,13 @@
\gridboxlinemode \c_page_grids_line_mode
\gridboxlinenomode\c_page_grids_lineno_mode
\setgridbox\scratchbox\makeupwidth\textheight % todo: check color
- \global\setbox#1\hbox % global ?
+ \global\setbox#1\hpack % global ?
{\ifcase\c_page_grids_location\or\or\box#1\hskip-\makeupwidth\fi
\begingroup % color
\ifcase\layoutcolumns\else
\gray
\setlayoutcomponentattribute{\v!grid:\v!columns}%
- \hbox \layoutcomponentboxattribute to \makeupwidth
+ \hpack \layoutcomponentboxattribute to \makeupwidth
{\dorecurse\layoutcolumns
{\hskip\layoutcolumnwidth
\ifnum\recurselevel<\layoutcolumns
@@ -197,7 +198,7 @@
\hskip-\makeupwidth
\fi
\setlayoutcomponentattribute{\v!grid:\v!lines}%
- \hbox \layoutcomponentboxattribute{\box\scratchbox}%
+ \hpack \layoutcomponentboxattribute{\box\scratchbox}%
\endgroup
\ifcase\c_page_grids_location\or\hskip-\makeupwidth\box#1\fi}%
\stopcolor}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-sel.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-sel.mkvi
index 335d0118734..e11a50f5b33 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-sel.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-sel.mkvi
@@ -342,7 +342,7 @@
\def\page_selectors_slice_indeed[#filename][#oddsettings][#evensettings]%
{\bgroup
\dontcomplain
- \global\let\slicedpagenumber\!!zerocount
+ \glet\slicedpagenumber\!!zerocount
\getfiguredimensions[#filename]%
\setupcurrentwithpages
[\c!offset=\zeropoint,%
@@ -366,7 +366,7 @@
\c!header=\zeropoint,\c!footer=\zeropoint]%
\fi
\dorecurse\noffigurepages
- {\global\let\slicedpagenumber\recurselevel
+ {\glet\slicedpagenumber\recurselevel
\ifnum\c_page_selectors_n>\plusone
\dorecurse\c_page_selectors_n
{\let\slicedpagestepx\recurselevel
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-set.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-set.mkiv
index 3579e3b4849..dd145b3228c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-set.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-set.mkiv
@@ -248,8 +248,8 @@
\!!counta#1\relax
\fi
\fi
- \relax % needed ! ! ! ! else lookahead over \fi and \@EA
- \@EA\egroup\@EA\scratchcounter\the\!!counta\relax}
+ \relax % needed ! ! ! ! else lookahead over \fi and \expandafter
+ \expandafter\egroup\expandafter\scratchcounter\the\!!counta\relax}
\def\OTRSETsetcorrectcellht
{\bgroup
@@ -260,8 +260,8 @@
\restoreglobalbodyfont
\fi
\advance\!!dimena\strutht
- \relax % needed ! ! ! ! else lookahead over \fi and \@EA
- \@EA\egroup\@EA\scratchdimen\the\!!dimena\relax}
+ \relax % needed ! ! ! ! else lookahead over \fi and \expandafter
+ \expandafter\egroup\expandafter\scratchdimen\the\!!dimena\relax}
\def\doOTRSETsetgridcells#1#2#3#4#5#6% placeholder col row wid hei {data}
{\!!countd#2\advance\!!countd#4\advance\!!countd\minusone
@@ -487,7 +487,7 @@
\let\OTRSETbalht\zeropoint
\def\OTRSETreducegridbox % for the moment no difference between methods
- {\globallet\OTRSETbalht\zeropoint
+ {\glet\OTRSETbalht\zeropoint
\ifcase\OTRSETbalancemethod
% no balancing
\else
@@ -578,7 +578,7 @@
\else
\page_otr_construct_and_shipout\box\OTRfinalpagebox\zerocount % three arguments
\fi \fi
- \globallet\OTRSETbalht\zeropoint
+ \glet\OTRSETbalht\zeropoint
\egroup
\fi}
@@ -642,7 +642,7 @@
{\page_set_command_set_vsize}
\def\doOTRSETcolumnseparator
- {\hbox to \zeropoint{\hss\red\vl\hss}}
+ {\hpack to \zeropoint{\hss\red\vl\hss}}
\let\OTRSETcolumnseparator\relax
@@ -754,7 +754,7 @@
\fi}%
\ifdim\lastskipinotr>\zeropoint
\scratchskip\ht\scratchbox
- \setbox\scratchbox\hbox
+ \setbox\scratchbox\hpack
{\lower\strutdepth\box\scratchbox}%
\dp\scratchbox\scratchdimen
\ht\scratchbox\scratchskip
@@ -942,7 +942,7 @@
\fi
\ifenoughcolumncells
\OTRSETsetgridcells\mofcolumns\columnfirstcell\columnhcells\columnvcells
- {\hbox{\copy#1}}%
+ {\hpack{\copy#1}}%
\page_set_command_set_vsize
\else
\OTRSETsavebox{#1}%
@@ -1155,7 +1155,7 @@
%OTRSETprepareforcolumnslot3{#1}%
%ruledvskip\columnslotspacing\lineheight
\blank[\number\columnslotspacing*\v!line]%
- \snaptogrid\hbox to \hsize{\hss\box#1\hss}% strange, why the centering
+ \snaptogrid\hpack to \hsize{\hss\box#1\hss}% strange, why the centering
\blank[\number\columnslotspacing*\v!line]%
\else
\OTRSETstoreincolumnslotSOMEWHERE2{#1}%
@@ -1336,7 +1336,7 @@
% a quick hack ... will be redone
%
\ifdim\wd\floatbox<\floatwidth \ifhbox\floatbox
- \global\setbox\floatbox\hbox{\unhbox\floatbox}%
+ \global\setbox\floatbox\hpack{\unhbox\floatbox}%
\fi \fi
%
\dp\floatbox\zeropoint
@@ -1417,7 +1417,7 @@
{\advance\totalcolumnspace \OTRSETlocalwidth\recurselevel
\advance\totalcolumnspace \namedcolumnsetparameter{\currentcolumnset:\recurselevel}\c!distance}%
\ifdim\totalcolumnspace>\wd\scratchbox
- \setbox\scratchbox\hbox to \totalcolumnspace{\hss\box\scratchbox\hss}%
+ \setbox\scratchbox\hpack to \totalcolumnspace{\hss\box\scratchbox\hss}%
\fi
\page_set_cell_set\currenthcell\currentvcell\box\scratchbox
\egroup
@@ -1619,17 +1619,17 @@
\def\dostartcolumnset[#1][#2]%
{\increment\columnsetlevel\relax
- \global\let\localcolumnmaxcells\!!zerocount
+ \glet\localcolumnmaxcells\!!zerocount
\global\setfalse\OTRSETfinish
\ifnum\columnsetlevel=\plusone
\bgroup
\saveinterlinespace
- \globallet\columnsetpage\!!plusone
+ \glet\columnsetpage\!!plusone
\def\currentcolumnset{#2}%
\insidecolumnstrue % will be different flag in addition
\setupoutputroutine[\s!columnset]%
\doifelsenothing{#1}
- {\globallet\OTRSETlist\s!default}
+ {\glet\OTRSETlist\s!default}
{\xdef\OTRSETlist{#1}}%
\OTRSETstartnextpage
\OTRSETassignwidths
@@ -1659,7 +1659,7 @@
\global\setbox\OTRfinalpagebox\OTRSETmakegridbox
\ht\OTRfinalpagebox\textheight % signals output that there is content
\OTRSETdofinaloutput
- \globallet\OTRSETbalht\zeropoint
+ \glet\OTRSETbalht\zeropoint
\egroup}
{}}
@@ -1678,7 +1678,7 @@
\ifvoid\OTRfinalpagebox\else
% probably balanced
\ifdim\ht\OTRfinalpagebox<\textheight
- \snaptogrid[\v!page]\hbox{\box\OTRfinalpagebox}%
+ \snaptogrid[\v!page]\hpack{\box\OTRfinalpagebox}%
\else
\box\OTRfinalpagebox
\fi
@@ -1765,7 +1765,7 @@
\def\OTRSETstartnextpage
{\doifsomething\OTRSETlist
{\getfromcommacommand[\OTRSETlist][1]%
- \global\let\OTRSETidentifier\commalistelement
+ \glet\OTRSETidentifier\commalistelement
\xdef\currentcolumnset{\commalistelement}%
\checkcolumnsetparent
\let\newcommalistelement\empty
@@ -1848,7 +1848,7 @@
{\unvbox\normalpagebox
\global\lastskipinotr\lastskip}%
\ifdim\lastskipinotr>\zeropoint
- \global\setbox\b_page_set_preceding\hbox
+ \global\setbox\b_page_set_preceding\hpack
{\lower\strutdepth\box\b_page_set_preceding}%
\fi
\dp\b_page_set_preceding\strutdepth
@@ -1970,7 +1970,7 @@
\def\columnplaceholder#1#2%
{\hbox
- {\setbox\scratchbox\hbox to \hsize
+ {\setbox\scratchbox\hpack to \hsize
{\iftracecolumnset
\hskip-.5ex%
\startcolor[columnset:#2]\vrule\s!width\exheight\s!height.5\exheight\s!depth.5\exheight\stopcolor
@@ -2032,7 +2032,7 @@
\def\page_set_place_float_slot
{\setbox\floatbox\vbox{\page_otr_command_flush_float_box}%
\dp\floatbox\strutdp
- \@EA\uppercasestring\floatmethod\to\floatmethod
+ \expandafter\uppercasestring\floatmethod\to\floatmethod
\OTRSETstoreincolumnslot\floatmethod\floatbox
\page_floats_report_total}
@@ -2337,11 +2337,11 @@
\advance\!!countb \minusone
% new (*)
\doif{\columntextareaparameter\c!location}\v!depth
- {\setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}%
+ {\setbox\scratchbox\hpack{\lower\strutdepth\box\scratchbox}%
\dp\scratchbox\zeropoint
\ht\scratchbox\!!heighta}%
%
- \setbox0\hbox
+ \setbox0\hpack
{\ifcase\!!countc
\copy\scratchbox % \box
\else
@@ -2360,7 +2360,7 @@
\advance\!!counta \columntextareaparameter\c!nx
\advance\!!counta -\!!countc
\advance\!!widtha -\!!widthb
- \setbox0\hbox
+ \setbox0\hpack
% {\hskip-\namedlayoutparameter\v!odd\c!backspace
{\hskip-\layoutparameter\c!backspace
\clip
@@ -2560,7 +2560,7 @@
% todo: nboven/onder
%\OTRSETstoreincolumnslotHERE\scratchbox
\edef\floatmethod{\namedframedtextparameter{\??columnsetspan#1}\c!default}%
- \@EA\uppercasestring\floatmethod\to\floatmethod
+ \expandafter\uppercasestring\floatmethod\to\floatmethod
% todo : \v!here -> here enzovoorts
\OTRSETstoreincolumnslot\floatmethod\scratchbox
\checknextindentation[\namedframedtextparameter{\??columnsetspan#1}\c!indentnext]%
@@ -2626,6 +2626,23 @@
% \s!page_otr_command_flush_margin_blocks =\page_set_command_flush_margin_blocks, % not used
]
+\installfloatmethod \s!columnset \v!here \page_set_place_float_here
+\installfloatmethod \s!columnset \v!force \page_set_place_float_force
+\installfloatmethod \s!columnset \v!top \page_set_place_float_top
+\installfloatmethod \s!columnset \v!bottom \page_set_place_float_bottom
+\installfloatmethod \s!columnset \v!page \page_set_place_float_page
+\installfloatmethod \s!columnset \s!tblr \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!lrtb \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!tbrl \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!rltb \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!fxtb \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!btlr \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!lrbt \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!btrl \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!rlbt \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!fxbt \page_set_place_float_slot
+\installfloatmethod \s!columnset \s!fixd \page_set_place_float_force
+
\protect \endinput
% extreme examples (1)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-sid.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-sid.mkiv
index 6f5d9f3571f..8033812447b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-sid.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-sid.mkiv
@@ -41,6 +41,9 @@
\newdimen \d_page_sides_progress
\newdimen \d_page_sides_page_total
+\newdimen \d_page_sides_leftoffset
+\newdimen \d_page_sides_rightoffset
+
%newbox \b_page_sides_bottom
\newcount \c_page_sides_lines_done
@@ -48,6 +51,7 @@
\newcount \c_page_sides_n_of_lines
\newcount \c_page_sides_n_of_hang
\newconstant \c_page_sides_float_type
+\newcount \c_page_sides_hangafter
\newconditional \c_page_sides_short
\newconditional \c_page_sides_flag
@@ -77,6 +81,9 @@
\newdimen \d_page_sides_progression
+\newcount \c_page_sides_m_of_lines
+\newconditional \c_page_sides_delayed
+
\newif \iftracesidefloats % public (might change)
%D Defaults:
@@ -216,6 +223,8 @@
+\compensatedinnermakeupmargin
\relax
\fi
+ \global\d_page_sides_leftoffset \d_page_sides_rightskip
+ \global\d_page_sides_rightoffset\d_page_sides_leftskip
\ifdim\d_page_sides_rightskip>\zeropoint
\global\advance\d_page_sides_rightskip\rightskip
\fi
@@ -394,7 +403,8 @@
\endgroup
\else
\forcestrutdepth
- \fi}
+ \fi
+ \page_otr_command_set_vsize} % new
\def\page_sides_flush_floats
{\par
@@ -541,30 +551,43 @@
\def\page_sides_inject_dummy_lines
{\par
\nointerlineskip
+ % \ifnum\lastpenalty>\zerocount
+ % \penalty\plustenthousand
+ % \fi
\dontleavehmode
\iftracesidefloats
\page_sides_inject_dummy_line_traced
\else
\page_sides_inject_dummy_line_normal
\fi
- \vskip-\dimexpr\lineheight+\strutdp\relax
+ \par
+ % on an empty page we have topskip, say 12pt
+ \ignoreparskip
+ % this can be 18.5pt
+ \kern-\dimexpr\lineheight+\strutdp\relax
+ % so we can actually have a -2.5pt skip on top
\ignoreparskip
\blank[\v!samepage]
- \blank[\v!disable]}
+ \blank[\v!disable]
+ % now say we are negative now
+ \ifdim\pagetotal<\zeropoint
+ % then we're at the top of the page ... quite messy .. i really need to
+ % make the page builder a bit more flexible .. should we do something now?
+ \fi}
%D Checkers:
\def\page_sides_check_floats_after_par
{\page_sides_check_floats_indeed
\ifdim\d_page_sides_pagetotal=\pagetotal \else
- \global\let\page_sides_check_floats\page_sides_check_floats_indeed
+ \glet\page_sides_check_floats\page_sides_check_floats_indeed
\page_sides_flush_floats
\global\c_page_sides_n_of_lines\zerocount % here !
\fi}
\unexpanded\def\page_sides_flush_floats_after_par
{\global\d_page_sides_pagetotal\pagetotal
- \global\let\page_sides_check_floats\page_sides_check_floats_after_par}
+ \glet\page_sides_check_floats\page_sides_check_floats_after_par}
\unexpanded\def\page_sides_forget_floats
{\global\d_page_sides_vsize\d_page_sides_vsize_reset
@@ -651,18 +674,49 @@
\fi
\endgroup}
+% \def\page_sides_analyse_progress
+% {\d_page_sides_progress\d_page_sides_vsize
+% \ifconditional\c_page_sides_flag
+% \advance\d_page_sides_progress-\d_page_sides_page_total
+% \global\setfalse\c_page_sides_flag
+% \else
+% \advance\d_page_sides_progress-\pagetotal
+% \fi}
+
+% test case
+%
+% \usemodule[art-01]
+% \starttext
+% \dorecurse{40}{\line{#1}}
+% \placefigure[left]{}{}
+% \input ward
+% \startitemize
+% \item word \item word \item word \item word
+% \stopitemize
+% \input ward
+% \page
+% \stoptext
+
\def\page_sides_analyse_progress
- {\d_page_sides_progress\d_page_sides_vsize
+ {%\page_otr_command_set_vsize % this is new, otherwise topfloats are not taken into account
+ \d_page_sides_progress\d_page_sides_vsize
\ifconditional\c_page_sides_flag
\advance\d_page_sides_progress-\d_page_sides_page_total
\global\setfalse\c_page_sides_flag
\else
+ \ifdim\dimexpr\d_page_sides_progress+\d_page_sides_bottomtotal\relax>\pagegoal
+ % we adapt pagegoal because we can already have placed something with
+ % everypar and we hope that it triggers a flush, see test above
+ \pagegoal\dimexpr\pagegoal-\d_page_sides_bottomtotal\relax
+ \fi
\advance\d_page_sides_progress-\pagetotal
\fi}
\def\page_sides_analyse_space
{\global\settrue\c_page_sides_flag
- \page_sides_force_depth
+% \ifdim\pagegoal=\maxdimen
+% \pagegoal\textheight % maybe
+% \fi
\global\d_page_sides_page_total \pagetotal % global
\ifnum\c_page_sides_float_type<\plusfour
\global\d_page_sides_width \zeropoint
@@ -716,8 +770,18 @@
%D As we have no clear end of one or more paragraphs we only have pre float
%D skips.
-\def\page_sides_handle_float#1% grid (4) is rather experimental
- {\page_sides_check_horizontal_skips
+\newconstant\c_page_sides_page_method % will be: \c_page_sides_page_method\plusone
+
+\def\page_otr_force_new_page_one
+ {\vskip\d_page_sides_height
+ \penalty\outputpenalty
+ \vskip-\dimexpr\d_page_sides_height-\strutdp\relax
+ \prevdepth\strutdp}
+ %\ignoreparskip}
+
+\def\page_sides_handle_float#1%
+ {\page_sides_initialize_checker
+ \page_sides_check_horizontal_skips
\page_sides_check_vertical_skips
\page_sides_apply_horizontal_shift
\page_sides_check_previous_float
@@ -726,13 +790,26 @@
\page_sides_relocate_float{#1}%
\page_sides_apply_vertical_shift
\page_sides_analyse_space
- \ifconditional\c_page_floats_room \else
- \page_otr_fill_and_eject_page
+ \ifconditional\c_page_floats_room
+ \global\setfalse\c_page_sides_delayed
+ % we're ok
+ \else
+ \global\settrue\c_page_sides_delayed
+ \global\c_page_sides_m_of_lines\c_page_sides_n_of_lines
+ \ifcase\c_page_sides_page_method
+ \page_otr_fill_and_eject_page
+ \or
+ \page_otr_force_new_page_one
+ \else
+ \page_otr_fill_and_eject_page
+ \fi
+ \global\c_page_sides_n_of_lines\c_page_sides_m_of_lines
\page_sides_analyse_space
%\page_sides_inject_before
\page_sides_inject_dummy_lines
\fi
\page_sides_place_float
+ \global\setfalse\c_page_sides_delayed
\page_sides_check_floats_reset
\page_sides_wrapup}
@@ -740,8 +817,7 @@
{% we need to do this aftergroup
\aftergroup\par
\aftergroup\ignoreparskip
- \aftergroup\ignorespaces
- }
+ \aftergroup\ignorespaces}
\def\page_sides_check_floats_indeed
{\page_sides_analyse_progress
@@ -752,7 +828,16 @@
\fi
\parskip\s_spac_whitespace_parskip} % not needed
-\let\page_sides_check_floats\page_sides_check_floats_indeed
+% \let\page_sides_check_floats\page_sides_check_floats_indeed
+
+\let\page_sides_check_floats\relax
+
+\def\page_sides_initialize_checker
+ {\ifx\page_sides_check_floats\relax
+ \glet\page_sides_check_floats\page_sides_check_floats_indeed
+ \clf_enablesidefloatchecker
+ \glet\page_sides_initialize_checker\relax
+ \fi}
\unexpanded\def\page_sides_check_floats_tracer
{\begingroup
@@ -771,8 +856,30 @@
\fi
\endgroup}
+% tricky test:
+
+% \starttext
+% \dorecurse{33}{\line{#1}}
+% \placefigure[left]{}{}
+% \input ward
+% \startitemize
+% \item word \item word \item word \item word
+% \stopitemize
+% \input ward
+% \page
+% \placefigure[left]{}{}
+% \dontleavehmode \begingroup \input ward \par \endgroup
+% \dontleavehmode \begingroup \input ward \par \endgroup
+% \dontleavehmode \begingroup \input ward \par \endgroup
+% \input ward
+% \stoptext
+
\unexpanded\def\page_sides_check_floats_set
{\edef\p_sidethreshold{\floatparameter\c!sidethreshold}%
+ \ifconditional\c_page_sides_delayed
+ % For Alan's hanging right float that moved to the next page.
+ \d_page_sides_progress\zeropoint
+ \fi
\ifx\p_sidethreshold\v!old
\d_page_sides_progression\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax
\c_page_sides_n_of_hang\d_page_sides_progression
@@ -785,8 +892,14 @@
\dimexpr\d_page_sides_progress-\p_sidethreshold\relax
\fi
\getnoflines\d_page_sides_progression
+ % this can be an option
+ \ifdim\dimexpr\noflines\lineheight>\dimexpr\pagegoal-\pagetotal\relax
+ \getrawnoflines\d_page_sides_progression
+ \fi
+ %
\c_page_sides_n_of_hang\noflines
\fi
+ \global\c_page_sides_hangafter\zerocount
\ifnum\c_page_sides_n_of_hang>\zerocount
\ifcase\c_page_sides_n_of_lines
\else
@@ -822,6 +935,7 @@
\else
\hangindent \ifnum\c_page_sides_float_type>\plusfour -\fi\d_page_sides_width
\hangafter-\c_page_sides_n_of_hang
+ \global\c_page_sides_hangafter\hangafter
\fi
\fi
\global\advance\c_page_sides_checks_done \plusone
@@ -830,7 +944,16 @@
\fi}
\unexpanded\def\page_sides_check_floats_reset
- {\global\c_page_sides_checks_done\zerocount}
+ {\ifcase\c_page_sides_checks_done\else
+ \ifcase\c_page_sides_hangafter\else
+ % we need to deal with par's ending in a group which would restore
+ % hang parameters
+ \global\c_page_sides_hangafter\zerocount
+ \hangindent\zeropoint
+ \fi
+ % \global % no, otherwise a next hangindent won't work
+ \c_page_sides_checks_done\zerocount
+ \fi}
\unexpanded\def\page_sides_synchronize_floats
{\ifinner \else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-smp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-smp.mkiv
new file mode 100644
index 00000000000..2711c9944f7
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-smp.mkiv
@@ -0,0 +1,59 @@
+%D \module
+%D [ file=page-smp, % was: core-mul, page-mul
+%D version=1998.03.15,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Simple Multi Column Output,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D The old one:
+
+\definemixedcolumns
+ [\v!columns]
+ % compatible with columns default :
+ [\c!balance=\v!yes,
+ \c!blank={\v!line,\v!fixed}]
+
+\unexpanded\def\setupcolumns
+ {\setupmixedcolumns[\v!columns]}
+
+%D This will be replaced by mixed box.
+
+\unexpanded\def\startsimplecolumns
+ {\dosingleempty\page_simple_start}
+
+\def\page_simple_start[#1]%
+ {\bgroup
+ \setsimplecolumnshsize[#1]%
+ \nopenalties
+ \setbox\scratchbox\vbox\bgroup
+ \forgetall} % \blank[\v!disable]
+
+\unexpanded\def\stopsimplecolumns
+ {\removebottomthings
+ \egroup
+ \rigidcolumnbalance\scratchbox
+ \egroup}
+
+\unexpanded\def\setsimplecolumnshsize[#1]%
+ {\getdummyparameters
+ [\c!width=\hsize,
+ \c!distance=1.5\bodyfontsize,
+ \c!n=2,
+ \c!lines=0,
+ #1]%
+ \edef\rigidcolumnlines
+ {\directdummyparameter\c!lines}%
+ \setrigidcolumnhsize
+ {\directdummyparameter\c!width}%
+ {\directdummyparameter\c!distance}%
+ {\directdummyparameter\c!n}}
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-spr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-spr.mkiv
index dc1e013d50d..bb95ee467b1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-spr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-spr.mkiv
@@ -23,15 +23,32 @@
% beware, ugly overload, to be redone
+% \def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear
+% {\setbox#1\hbox
+% {\setlayoutcomponentattribute{\v!page:\v!text}%
+% \vbox \layoutcomponentboxattribute to \textheight
+% {\offinterlineskip
+% \freezetextwidth
+% \hsize\textwidth % local variant of \sethsize
+% \boxmaxdepth\maxdepth
+% \noindent % content can be < \hsize
+% \page_otr_command_package_contents#2#3}}%
+% \dp#1\zeropoint
+% \ifconditional\c_page_spread_busy
+% \normalsettextpagecontent_spread{#1}%
+% \else
+% \normalsettextpagecontent_normal{#1}%
+% \fi}
+
\def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear
- {\setbox#1\hbox
+ {\setbox#1\hpack
{\setlayoutcomponentattribute{\v!page:\v!text}%
- \vbox \layoutcomponentboxattribute to \textheight
+ \vpack \layoutcomponentboxattribute to \textheight
{\offinterlineskip
\freezetextwidth
\hsize\textwidth % local variant of \sethsize
\boxmaxdepth\maxdepth
- \noindent % content can be < \hsize
+ \noindent % content can be < \hsize
\page_otr_command_package_contents#2#3}}%
\dp#1\zeropoint
\ifconditional\c_page_spread_busy
@@ -40,12 +57,18 @@
\normalsettextpagecontent_normal{#1}%
\fi}
+% \def\normalsettextpagecontent_normal#1%
+% {\setbox#1\hbox to \makeupwidth
+% {\hss\box#1\hss}} % never change the \hss's
+
\def\normalsettextpagecontent_normal#1%
- {\setbox#1\hbox to \makeupwidth
- {\hss\box#1\hss}} % never change the \hss's
+ {\ifdim\wd#1=\makeupwidth\else
+ \setbox#1\hpack to \makeupwidth
+ {\hss\box#1\hss}% never change the \hss's
+ \fi}
\def\normalsettextpagecontent_spread#1%
- {\setbox#1\hbox to \makeupwidth
+ {\setbox#1\hpack to \makeupwidth
{\ifvoid\b_page_spread_content
\ifconditional\c_page_spread_once
\box#1%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-str.lua b/Master/texmf-dist/tex/context/base/mkiv/page-str.lua
index 4aeffffd80d..ebb49a918c2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-str.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-str.lua
@@ -20,18 +20,27 @@ local implement = interfaces.implement
local nodecodes = nodes.nodecodes
-local slide_node_list = nodes.slide
-local write_node = nodes.write
-local flush_node = nodes.flush
-local copy_node_list = nodes.copy_list
-local vpack_node_list = nodes.vpack
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+local slide_node_list = nuts.slide
+local write_node = nuts.write
+local flush_node = nuts.flush
+local copy_node_list = nuts.copy_list
+local vpack_node_list = nuts.vpack
+
+local getbox = nuts.getbox
+local setlink = nuts.setlink
+local getlist = nuts.getlist
+local setlist = nuts.setlist
+local getwhd = nuts.getwhd
+local setwhd = nuts.setwhd
local settings_to_array = utilities.parsers.settings_to_array
local enableaction = nodes.tasks.enableaction
local texgetdimen = tex.getdimen
-local texgetbox = tex.getbox
+----- texgetbox = tex.getbox
local trace_collecting = false trackers.register("streams.collecting", function(v) trace_collecting = v end)
local trace_flushing = false trackers.register("streams.flushing", function(v) trace_flushing = v end)
@@ -41,7 +50,11 @@ local report_streams = logs.reporter("streams")
streams = streams or { } -- might move to the builders namespace
local streams = streams
-local data, name, stack = { }, nil, { }
+-- maybe store head and tail ... first we need usage
+
+local data = { }
+local name = nil
+local stack = { }
function streams.enable(newname)
if newname == "default" then
@@ -66,7 +79,7 @@ end
function streams.collect(head,where)
if name and head and name ~= "default" then
- local tail = node.slide(head)
+ local head = tonut(head)
local dana = data[name]
if not dana then
dana = { }
@@ -75,7 +88,7 @@ function streams.collect(head,where)
local last = dana[#dana]
if last then
local tail = slide_node_list(last)
- tail.next, head.prev = head, tail
+ setlink(tail,head)
elseif last == false then
dana[#dana] = head
else
@@ -84,9 +97,9 @@ function streams.collect(head,where)
if trace_collecting then
report_streams("appending snippet %a to slot %s",name,#dana)
end
- return nil, true
+ return nil
else
- return head, false
+ return head
end
end
@@ -118,7 +131,7 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards
for i=1,dn do
local di = dana[i]
if di then
- write_node(copy_node_list(di.list)) -- list, will be option
+ write_node(copy_node_list(getlist(di))) -- list, will be option
end
end
if copy then
@@ -131,8 +144,8 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards
for i=1,dn do
local di = dana[i]
if di then
- write_node(di.list) -- list, will be option
- di.list = nil
+ write_node(getlist(di)) -- list, will be option
+ setlist(di)
flush_node(di)
end
end
@@ -167,7 +180,7 @@ function streams.synchronize(list) -- this is an experiment !
local slot = dana[m]
if slot then
local vbox = vpack_node_list(slot)
- local ht, dp = vbox.height, vbox.depth
+ local wd, ht, dp = getwhd(vbox)
if ht > height then
height = ht
end
@@ -191,32 +204,36 @@ function streams.synchronize(list) -- this is an experiment !
local dana = data[name]
local vbox = dana[m]
if vbox then
- local delta_height = height - vbox.height
- local delta_depth = depth - vbox.depth
+ local wd, ht, dp = getwhd(vbox)
+ local delta_height = height - ht
+ local delta_depth = depth - dp
if delta_height > 0 or delta_depth > 0 then
if false then
-- actually we need to add glue and repack
- vbox.height, vbox.depth = height, depth
+ setwhd(vbox,false,height,depth)
if trace_flushing then
report_streams("slot %s of %a with delta (%p,%p) is compensated",m,i,delta_height,delta_depth)
end
else
-- this is not yet ok as we also need to keep an eye on vertical spacing
-- so we might need to do some splitting or whatever
- local tail = vbox.list and slide_node_list(vbox.list)
- local n, delta = 0, delta_height -- for tracing
+ local list = getlist(vbox)
+ local tail = list and slide_node_list(list)
+ local n = 0
+ local delta = delta_height -- for tracing
while delta > 0 do
-- we need to add some interline penalties
- local line = copy_node_list(texgetbox("strutbox"))
- line.height, line.depth = strutht, strutdp
+ local line = copy_node_list(getbox("strutbox"))
+ setwhd(line,false,strutht,strutdp)
if tail then
- tail.next, line.prev = line, tail
+ setlink(tail,line)
end
- tail = line
- n, delta = n +1, delta - struthtdp
+ tail = line
+ n = n + 1
+ delta = delta - struthtdp
end
- dana[m] = vpack_node_list(vbox.list)
- vbox.list = nil
+ dana[m] = vpack_node_list(getlist(vbox))
+ setlist(vbox)
flush_node(vbox)
if trace_flushing then
report_streams("slot %s:%s with delta (%p,%p) is compensated by %s lines",m,i,delta_height,delta_depth,n)
@@ -230,6 +247,8 @@ function streams.synchronize(list) -- this is an experiment !
end
end
+-- hm, nut or node
+
tasks.appendaction("mvlbuilders", "normalizers", "streams.collect")
tasks.disableaction("mvlbuilders", "streams.collect")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-str.mkiv b/Master/texmf-dist/tex/context/base/mkiv/page-str.mkiv
index 57a465603b5..354c1f3c3ee 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-str.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-str.mkiv
@@ -56,7 +56,7 @@
\unexpanded\def\disableoutputstream
{\inoutputstreamfalse
- \global\let\currentoutputstream\s!default
+ \glet\currentoutputstream\s!default
\clf_disablestream}
\unexpanded\def\startoutputstream[#1]%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/page-txt.mkvi b/Master/texmf-dist/tex/context/base/mkiv/page-txt.mkvi
index b043b60c7ba..97668c14377 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/page-txt.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/page-txt.mkvi
@@ -98,8 +98,8 @@
{\expandafter\normalgdef\csname\??layouttextsreset#vertical\endcsname{\page_layouts_set_element_status_normal#vertical}}
\def\page_layouts_set_element_status_normal#vertical%
- {\global\expandafter\let\csname\namedlayoutelementhash#vertical\c!state\endcsname\v!normal
- \global\expandafter\let\csname\??layouttextsreset#vertical\endcsname\relax
+ {\expandafter\glet\csname\namedlayoutelementhash#vertical\c!state\endcsname\v!normal
+ \expandafter\glet\csname\??layouttextsreset#vertical\endcsname\relax
\page_layouts_synchronize_element{#vertical}}
\def\page_layouts_synchronize_element#vertical%
@@ -527,10 +527,10 @@
\page_layouts_place_text_line_right
\page_layouts_place_text_line_left
\namedlayoutelementparameter\currentlayouttextline\c!after
- \kern\zeropoint}% keep the \dp, beware of \vtops, never change this!
+ \vkern\zeropoint}% keep the \dp, beware of \vtops, never change this!
\dp\b_page_layouts_element\zeropoint
\box\b_page_layouts_element
- \vskip-#height\relax}
+ \vkern-#height\relax}
\let\page_layouts_extra_at_margin_left \plusone
\let\page_layouts_extra_at_margin_right\plustwo
@@ -831,21 +831,21 @@
\calculatereducedvsizes
\swapmargins
\offinterlineskip
- \vskip\dimexpr-\topheight-\topdistance\relax
+ \vkern\dimexpr-\topheight-\topdistance\relax
\the\toptextcontent
- \vskip\dimexpr\topheight+\topdistance\relax
+ \vkern\dimexpr\topheight+\topdistance\relax
\the\headertextcontent
- \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax
+ \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax
\anch_positions_place_anchors
- \vskip\dimexpr-\textdistance-\textheight\relax
+ \vkern\dimexpr-\textdistance-\textheight\relax
\the\texttextcontent
- \vskip\textheight
+ \vkern\textheight
\the\everyendoftextbody
- \vskip\footerdistance
+ \vkern\footerdistance
\the\footertextcontent
- \vskip\dimexpr\footerheight+\bottomdistance\relax
+ \vkern\dimexpr\footerheight+\bottomdistance\relax
\the\bottomtextcontent
- \vskip\bottomheight
+ \vkern\bottomheight
\vfilll}%
\smashbox\b_page_layouts_element
\box\b_page_layouts_element}
@@ -854,16 +854,20 @@
% \let\page_prepare_backgrounds\gobbleoneargument
% \fi
+% only for very special controlled cases or experiments:
+
+\let\page_scale_text_box\gobbleoneargument
+
\def\page_insert_body#1#2%
{\setbox\b_page_layouts_element\vpack
{\offinterlineskip
\calculatereducedvsizes
\calculatehsizes
\swapmargins
- \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax
+ \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax
\dontleavehmode
%\page_prepare_backgrounds{#2}%
- \hbox to \makeupwidth
+ \hpack to \makeupwidth
{\begingroup
\swapmargins
\goleftonpage
@@ -880,6 +884,7 @@
\settextpagecontent\b_page_layouts_element{#1}{#2}%
\page_backgrounds_add_to_text\b_page_layouts_element
\page_grids_add_to_box\b_page_layouts_element
+ \page_scale_text_box\b_page_layouts_element
\box\b_page_layouts_element
\begingroup
\ifdim\rightmarginwidth>\zeropoint
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-aut.lua b/Master/texmf-dist/tex/context/base/mkiv/publ-aut.lua
index be0c771a3e4..e74c7ee18b5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-aut.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-aut.lua
@@ -16,6 +16,7 @@ local lpeg = lpeg
local type, next, tostring, tonumber = type, next, tostring, tonumber
local concat, sortedhash = table.concat, table.sortedhash
local utfsub = utf.sub
+local find = string.find
local formatters = string.formatters
local P, S, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.S, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc
@@ -38,6 +39,8 @@ local chardata = characters.data
local trace_hashing = false trackers.register("publications.authorhash", function(v) trace_hashing = v end)
+local expand_authors = false directives.register("publications.prerollauthor", function(v) expand_authors = v end)
+
local report = logs.reporter("publications","authors")
local report_cite = logs.reporter("publications","cite")
@@ -61,8 +64,8 @@ local v_last = interfaces.variables.last
local space = lpegpatterns.whitespace
local comma = P(",")
-local period = P(".")
-local dash = P("-")
+local period = P(".") + P("{.}")
+local dash = P("-") + P("{-}")
local firstcharacter = lpegpatterns.utf8byte
local utf8character = lpegpatterns.utf8character
local p_and = space^1 * (P("and") + P("&&") + P("++")) * space^1
@@ -123,6 +126,8 @@ end
local authormap = allocate()
publications.authormap = authormap
+local prerollcmdstring = publications.prerollcmdstring
+
local function splitauthor(author,justsplit)
local detail, remapped
if not justsplit then
@@ -142,6 +147,9 @@ local function splitauthor(author,justsplit)
end
local author = remapped or author
local firstnames, vons, surnames, initials, juniors, options
+ if expand_authors and find(author,"\\btxcmd") then
+ author = prerollcmdstring(author)
+ end
local split = lpegmatch(commasplitter,author)
local n = #split
detail = {
@@ -151,8 +159,11 @@ local function splitauthor(author,justsplit)
if n == 1 then
-- {First Middle von Last}
local words = lpegmatch(spacesplitter,author)
- firstnames, vons, surnames = { }, { }, { }
- local i, n = 1, #words
+ local i = 1
+ local n = #words
+ firstnames = { }
+ vons = { }
+ surnames = { }
while i <= n do
local w = words[i]
if is_upper(w) then
@@ -190,9 +201,12 @@ local function splitauthor(author,justsplit)
elseif n == 2 then
-- {Last, First}
-- {von Last, First}
- firstnames, vons, surnames = { }, { }, { }
local words = lpegmatch(spacesplitter,split[1])
- local i, n = 1, #words
+ local i = 1
+ local n = #words
+ firstnames = { }
+ vons = { }
+ surnames = { }
while i <= n do
local w = words[i]
if is_upper(w) then
@@ -202,21 +216,25 @@ local function splitauthor(author,justsplit)
end
end
while i <= n do
- surnames[#surnames+1], i = words[i], i + 1
+ surnames[#surnames+1] = words[i]
+ i = i + 1
end
--
local words = lpegmatch(spacesplitter,split[2])
- local i, n = 1, #words
+ local i = 1
+ local n = #words
while i <= n do
local w = words[i]
if is_upper(w) then
- firstnames[#firstnames+1], i = w, i + 1
+ firstnames[#firstnames+1] = w
+ i = i + 1
else
break
end
end
while i <= n do
- vons[#vons+1], i = words[i], i + 1
+ vons[#vons+1] = words[i]
+ i = i + 1
end
if surnames and firstnames and #surnames == 0 then
-- safeguard
@@ -308,12 +326,14 @@ local function the_initials(initials,symbol,connector)
if not connector then
connector = "-"
end
- local result, r = { }, 0
+ local result = { }
+ local r = 0
for i=1,#initials do
local initial = initials[i]
if type(initial) == "table" then
-- J.-J.
- local set, s = { }, 0
+ local set = { }
+ local s = 0
for i=1,#initial do
if i > 1 then
s = s + 1 ; set[s] = connector
@@ -825,8 +845,10 @@ local p_clean = Cs ( (
+ lpeg.patterns.utf8character
)^1)
+-- Probabbly more robust is a two pass approach.
+
authorhashers.short = function(authors)
- -- a short is a real dumb hardcodes kind of tag and we only support
+ -- a short is a real dumb hardcoded kind of tag and we only support
-- this one because some users might expect it, not because it makes
-- sense
if type(authors) == "table" then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-dat.lua b/Master/texmf-dist/tex/context/base/mkiv/publ-dat.lua
index 310df82f38a..f09e97a8d9f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-dat.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-dat.lua
@@ -22,6 +22,10 @@ if not characters then
dofile(resolvers.findfile("char-tex.lua"))
end
+if not utilities.sequencers then
+ dofile(resolvers.findfile("util-seq.lua"))
+end
+
local lower, find, sub = string.lower, string.find, string.sub
local concat, copy, tohash = table.concat, table.copy, table.tohash
local next, type, rawget, tonumber = next, type, rawget, tonumber
@@ -30,7 +34,7 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local textoutf = characters and characters.tex.toutf
local settings_to_hash, settings_to_array = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array
local formatters = string.formatters
-local sortedkeys, sortedhash, keys = table.sortedkeys, table.sortedhash, table.keys
+local sortedkeys, sortedhash, keys, sort = table.sortedkeys, table.sortedhash, table.keys, table.sort
local xmlcollected, xmltext, xmlconvert = xml.collected, xml.text, xml.convert
local setmetatableindex = table.setmetatableindex
@@ -439,7 +443,7 @@ do
----- command = P("\\") * (Carg(1) * C(R("az","AZ")^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end)
local command = P("\\") * (Carg(1) * C(csletter^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end)
local whatever = P("\\") * P(" ")^1 / " "
- + P("\\") * ( P("hbox") + P("raise") ) -- bah
+ ----- + P("\\") * ( P("hbox") + P("raise") ) -- bah -- no longer
local somemath = P("$") * ((1-P("$"))^1) * P("$") -- let's not assume nested math
----- character = lpegpatterns.utf8character
local any = P(1)
@@ -482,6 +486,8 @@ do
local tags = table.setmetatableindex("table")
+ local indirectcrossrefs = true
+
local function do_definition(category,tag,tab,dataset)
publicationsstats.nofdefinitions = publicationsstats.nofdefinitions + 1
if tag == "" then
@@ -529,11 +535,23 @@ do
value = lpegmatch(filter_2,value,1,dataset.commands) -- we need to start at 1 for { }
end
if normalized == "crossref" then
- local parent = luadata[value]
- if parent then
- setmetatableindex(entries,parent)
+ if indirectcrossrefs then
+ setmetatableindex(entries,function(t,k)
+ local parent = rawget(luadata,value)
+ if parent == entries then
+ report_duplicates("bad parent %a for %a in dataset %s",value,hashtag,dataset.name)
+ setmetatableindex(entries,nil)
+ return entries
+ elseif parent then
+ setmetatableindex(entries,parent)
+ return entries[k]
+ else
+ report_duplicates("no valid parent %a for %a in dataset %s",value,hashtag,dataset.name)
+ setmetatableindex(entries,nil)
+ end
+ end)
else
- -- warning
+ dataset.nofcrossrefs = dataset.nofcrossrefs +1
end
end
entries[normalized] = value
@@ -640,16 +658,17 @@ do
local somevalue = d_value + b_value + s_value + r_value + n_value + e_value
local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0))
- local stripper = lpegpatterns.stripper
- value = value / function(s) return lpegmatch(stripper,s) end
+ local stripper = lpegpatterns.collapser
+ local stripped = value / function(s) return lpegmatch(stripper,s) end
local forget = percent^1 * (1-lineending)^0
local spacing = spacing * forget^0 * spacing
- local assignment = spacing * key * spacing * equal * spacing * value * spacing
+ local replacement= spacing * key * spacing * equal * spacing * value * spacing
+ local assignment = spacing * key * spacing * equal * spacing * stripped * spacing
local definition = category * spacing * left * spacing * tag * spacing * comma * Ct((assignment * comma^0)^0) * spacing * right * Carg(1) / do_definition
local crapword = C((1-space-left)^1)
- local shortcut = Cmt(crapword,function(_,p,s) return lower(s) == "string" and p end) * spacing * left * ((assignment * Carg(1))/do_shortcut * comma^0)^0 * spacing * right
+ local shortcut = Cmt(crapword,function(_,p,s) return lower(s) == "string" and p end) * spacing * left * ((replacement * Carg(1))/do_shortcut * comma^0)^0 * spacing * right
local comment = Cmt(crapword,function(_,p,s) return lower(s) == "comment" and p end) * spacing * lpegpatterns.argument * Carg(1) / do_comment
local casecrap = #S("sScC") * (shortcut + comment)
@@ -682,12 +701,37 @@ do
statistics.starttiming(publications)
publicationsstats.nofbytes = publicationsstats.nofbytes + size
current.nofbytes = current.nofbytes + size
+ current.nofcrossrefs = 0
if source then
table.insert(current.sources, { filename = source, checksum = md5.HEX(content) })
current.loaded[source] = kind or true
end
- current.newtags = #current.luadata > 0 and { } or current.newtags
+ local luadata = current.luadata
+ current.newtags = #luadata > 0 and { } or current.newtags
lpegmatch(bibtotable,content or "",1,current)
+ if current.nofcrossrefs > 0 then
+ for tag, entries in next, luadata do
+ local value = entries.crossref
+ if value then
+ local parent = luadata[value]
+ if parent == entries then
+ report_duplicates("bad parent %a for %a in dataset %s",value,hashtag,dataset.name)
+ elseif parent then
+ local t = { }
+ for k, v in next, parent do
+ if not entries[k] then
+ entries[k] = v
+ t[#t+1] = k
+ end
+ end
+ sort(t)
+ entries.inherited = concat(t,",")
+ else
+ report_duplicates("no valid parent %a for %a in dataset %s",value,hashtag,dataset.name)
+ end
+ end
+ end
+ end
statistics.stoptiming(publications)
end
@@ -708,22 +752,27 @@ do
local compact = false -- can be a directive but then we also need to deal with newlines ... not now
- function publications.converttoxml(dataset,nice,dontstore,usedonly,subset) -- we have fields !
+ function publications.converttoxml(dataset,nice,dontstore,usedonly,subset,noversion,rawtoo) -- we have fields !
local current = datasets[dataset]
local luadata = subset or (current and current.luadata)
if luadata then
statistics.starttiming(publications)
--
local result, r, n = { }, 0, 0
- local usedonly = usedonly and publications.usedentries()
+ if usedonly then
+ usedonly = publications.usedentries()
+ usedonly = usedonly[current.name]
+ end
--
r = r + 1 ; result[r] = ""
- r = r + 1 ; result[r] = ""
+ r = r + 1 ; result[r] = formatters[""](current.name)
--
if nice then -- will be default
local f_entry_start = formatters[" "]
local s_entry_stop = " "
local f_field = formatters[" %s "]
+ local f_cdata = formatters[" "]
+
for tag, entry in sortedhash(luadata) do
if not usedonly or usedonly[tag] then
r = r + 1 ; result[r] = f_entry_start(tag,entry.category,entry.index)
@@ -737,6 +786,11 @@ do
end
end
end
+ if rawtoo then
+ local s = publications.savers.bib(current,false,{ [tag] = entry })
+ s = utilities.strings.striplines(s,"prune and collapse")
+ r = r + 1 ; result[r] = f_cdata(s)
+ end
r = r + 1 ; result[r] = s_entry_stop
n = n + 1
end
@@ -766,7 +820,7 @@ do
--
r = r + 1 ; result[r] = " "
--
- result = concat(result,nice and "\n" or nil)
+ result = concat(result,nice and "\n" or nil,noversion and 2 or 1,#result)
--
if dontstore then
-- indeed
@@ -1084,7 +1138,7 @@ do
\ifdefined\btxcmd
% we're probably in context
\else
- \def\btxcmd#1{\csname#1\endcsname}
+ \def\btxcmd#1{\begincsname#1\endcsname}
\fi
}
@@ -1094,8 +1148,8 @@ do
local f_start = formatters["@%s{%s,\n"]
local f_field = formatters[" %s = {%s},\n"]
local s_stop = "}\n\n"
- local result = { s_preamble }
- local n, r = 0, 1
+ local result = { }
+ local n, r = 0, 0
for tag, data in sortedhash(tobesaved) do
r = r + 1 ; result[r] = f_start(data.category or "article",tag)
for key, value in sortedhash(data) do
@@ -1106,8 +1160,16 @@ do
r = r + 1 ; result[r] = s_stop
n = n + 1
end
- report("%s entries from dataset %a saved in %a",n,dataset,filename)
- io.savedata(filename,concat(result))
+ result = concat(result)
+ if find(result,"\\btxcmd") then
+ result = s_preamble .. result
+ end
+ if filename then
+ report("%s entries from dataset %a saved in %a",n,dataset,filename)
+ io.savedata(filename,result)
+ else
+ return result
+ end
end
function savers.lua(dataset,filename,tobesaved)
@@ -1127,8 +1189,8 @@ do
table.save(filename,list)
end
- function savers.xml(dataset,filename,tobesaved)
- local result, n = publications.converttoxml(dataset,true,true,false,tobesaved)
+ function savers.xml(dataset,filename,tobesaved,rawtoo)
+ local result, n = publications.converttoxml(dataset,true,true,false,tobesaved,false,rawtoo)
report("%s entries from dataset %a saved in %a",n,dataset,filename)
io.savedata(filename,result)
end
@@ -1175,6 +1237,8 @@ do
return dataset
end
+ publications.savers = savers
+
if implement then
implement {
@@ -1248,3 +1312,18 @@ do
writers.pagenumber = writers.range
end
+
+if implement then
+
+ implement {
+ name = "btxshortcut",
+ arguments = "2 strings",
+ actions = function(instance,key)
+ local d = publications.datasets[instance]
+ context(d and d.shortcuts[key] or "?")
+ end,
+ }
+
+end
+
+-- inspect(publications.load { filename = "e:/tmp/oeps.bib" })
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-imp-apa.mkvi b/Master/texmf-dist/tex/context/base/mkiv/publ-imp-apa.mkvi
index cd78a879959..160cc452209 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-imp-apa.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-imp-apa.mkvi
@@ -432,8 +432,44 @@
\c!style=\v!italic]
\definebtx
+ [apa:\s!cite:subtitle]
+ [apa:\s!cite:title]
+
+\definebtx
+ [apa:\s!cite:booktitle]
+ [apa:\s!cite:title]
+
+\definebtx
+ [apa:\s!cite:subbooktitle]
[apa:\s!cite:booktitle]
+
+% Will these get used?
+
+\definebtx
+ [apa:\s!cite:title:inbook]
[apa:\s!cite:title]
+ [\c!style=] % not italic
+
+\definebtx
+ [apa:\s!cite:title:incollection]
+ [apa:\s!cite:title:inbook]
+
+\definebtx
+ [apa:\s!cite:title:inproceedings]
+ [apa:\s!cite:title:inbook]
+
+\definebtx
+ [apa:\s!cite:subtitle:inbook]
+ [apa:\s!cite:title:inbook]
+
+\definebtx
+ [apa:\s!cite:subtitle:incollection]
+ [apa:\s!cite:title:incollection]
+
+\definebtx
+ [apa:\s!cite:subtitle:inproceedings]
+ [apa:\s!cite:title:inproceedings]
+
\definebtx
[apa:\s!cite:tag]
@@ -441,7 +477,6 @@
[\c!left={[},
\c!right={]}]
-
\definebtx
[apa:\s!cite:index]
[apa:\s!cite]
@@ -679,6 +714,50 @@
\fastsetup{\s!btx:\s!cite:author:years}
\stopsetups
+% these setups need to be explicitly defined in order to get cite rendering
+
+\startsetups \s!btx:apa:\s!cite:organization
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:subtitle
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:booktitle
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:subbooktitle
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+% are these needed?
+
+\startsetups \s!btx:apa:\s!cite:title:inbook
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:title:incollection
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:title:inproceedings
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:subtitle:inbook
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:subtitle:incollection
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
+\startsetups \s!btx:apa:\s!cite:subtitle:inproceedings
+ \fastsetup{\s!btx:\s!cite:normal}
+\stopsetups
+
% used in publ-imp-page.mkvi
\startsetups btx:apa:list:page-or-pages
@@ -797,7 +876,7 @@
% A book might have an editor AND an author
\doif {\currentbtxcategory} {book} {
\doifnot {\btxfoundname{author}} {editor} {
- \btxdoif {ineditor} { % ineditor authorconversion
+ \btxdoif {ineditor} { % ineditor specific authorconversion
\btxleftparenthesis
\btxflush{ineditor}
\btxcomma
@@ -973,11 +1052,11 @@
\starttexdefinition unexpanded btx:apa:editor-in
\btxdoif {booktitle} {
\btxlabeltext{In}
+ \btxspace
\doifnot {\btxfoundname{author}} {editor} {
- \btxspace
\texdefinition{btx:apa:author-or-editor} {ineditor}
+ \btxcomma
}
- \btxspace
\texdefinition{btx:apa:composed-title}{booktitle}
\btxperiod
}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-imp-cite.mkvi b/Master/texmf-dist/tex/context/base/mkiv/publ-imp-cite.mkvi
index 8fe96429d1b..56af83a1b15 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-imp-cite.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-imp-cite.mkvi
@@ -232,9 +232,6 @@
\startsetups \s!btx:\s!cite:pages
\fastsetup{\s!btx:\s!cite:range}
\stopsetups
-\startsetups \s!btx:\s!cite:organization
- \fastsetup{\s!btx:\s!cite:range}
-\stopsetups
% is the next one used?
% Yes, bibtex is a mess and one can have pages or sometimes page
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-inc.lua b/Master/texmf-dist/tex/context/base/mkiv/publ-inc.lua
new file mode 100644
index 00000000000..9231be3c192
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-inc.lua
@@ -0,0 +1,26 @@
+if not modules then modules = { } end modules ['publ-inc'] = {
+ version = 1.001,
+ comment = "this module part of publication support",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local fullstrip = string.fullstrip
+local datasets, savers = publications.datasets, publications.savers
+local assignbuffer = buffers.assign
+
+interfaces.implement {
+ name = "btxentrytobuffer",
+ arguments = "3 strings",
+ actions = function(dataset,tag,target)
+ local d = datasets[dataset]
+ if d then
+ d = d.luadata[tag]
+ end
+ if d then
+ d = fullstrip(savers.bib(dataset,false,{ [tag] = d }))
+ end
+ assignbuffer(target,d or "")
+ end
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-inc.mkiv b/Master/texmf-dist/tex/context/base/mkiv/publ-inc.mkiv
new file mode 100644
index 00000000000..c1728f44a4f
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-inc.mkiv
@@ -0,0 +1,63 @@
+%D \module
+%D [ file=publ-inc,
+%D version=2018.06.23,
+%D title=\CONTEXT\ Publication Macros,
+%D subtitle=XML inclusion,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Publication Macros / XML inclusion}
+
+\registerctxluafile{publ-inc}{}
+
+%D A teaser for Alan.
+
+\unprotect
+
+\definesymbol[btxattachment][{\infofont\darkred btx}]
+\definesymbol[btxcomment] [{\infofont\darkblue btx}]
+
+\unexpanded\def\btx_add_blob#1#2%
+ {\relax
+ \clf_btxentrytobuffer{\currentbtxdataset}{\currentbtxtag}{temp-btx-export}%
+ #2%
+ [\c!symbol=#1,%
+ \c!space=\v!yes,
+ \c!buffer=temp-btx-export,%
+ \c!name={\currentbtxtag.bib}]%
+ \relax}
+
+\unexpanded\def\btxattach
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \btx_add_blob{btxattachment}\attachment
+ \dostoptagged
+ \fi \fi \fi}
+
+\unexpanded\def\btxcomment
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \btx_add_blob{btxcomment}\comment
+ \dostoptagged
+ \fi \fi \fi}
+
+%D This kind of feature creep is not yet configurable, nor documented.
+
+\unexpanded\def\btxaddsource
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \llap{%
+ \btx_add_blob{btxattachment}\attachment
+ \quad
+ \btx_add_blob{btxcomment}\comment
+ \hskip\leftmargindistance
+ }%
+ \dostoptagged
+ \fi \fi \fi}
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua
index 9dfeda168cc..f62352f07f0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua
@@ -32,7 +32,7 @@ local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash
local setmetatableindex = table.setmetatableindex
local lpegmatch = lpeg.match
local P, S, C, Ct, Cs, R, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.R, lpeg.Carg
-local upper = utf.upper
+local upper = characters.upper
local report = logs.reporter("publications")
local report_cite = logs.reporter("publications","cite")
@@ -229,9 +229,9 @@ logs.registerfinalactions(function()
logs.startfilelogging(report,"used btx commands")
done = true
end
- if isdefined[command] then
+ if isdefined(command) then
report("%-20s %-20s % 5i %s",name,command,n,"known")
- elseif isdefined[upper(command)] then
+ elseif isdefined(upper(command)) then
report("%-20s %-20s % 5i %s",name,command,n,"KNOWN")
else
report("%-20s %-20s % 5i %s",name,command,n,"unknown")
@@ -246,7 +246,7 @@ logs.registerfinalactions(function()
logs.starterrorlogging(report,"unknown btx commands")
for name, dataset in sortedhash(datasets) do
for command, n in sortedhash(dataset.commands) do
- if not isdefined[command] and not isdefined[upper(command)] then
+ if not isdefined(command) and not isdefined(upper(command)) then
report("%-20s %-20s % 5i %s",name,command,n,"unknown")
end
end
@@ -1065,14 +1065,17 @@ do
-- maybe not redo when already done
local function shortsorter(a,b)
- local ay, by = a[2], b[2] -- year
+ local ay = a[2] -- year
+ local by = b[2] -- year
if ay ~= by then
return ay < by
end
- local ay, by = a[3], b[3] -- suffix
+ local ay = a[3] -- suffix
+ local by = b[3] -- suffix
if ay ~= by then
-- bah, bah, bah
- local an, bn = tonumber(ay), tonumber(by)
+ local an = tonumber(ay)
+ local bn = tonumber(by)
if an and bn then
return an < bn
else
@@ -2023,7 +2026,8 @@ do
for i=1,nofranges do
local r = ranges[i]
ctx_btxsetconcat(concatstate(i,nofranges))
- local first, last = r[1], r[2]
+ local first = r[1]
+ local last = r[2]
ctx_btxsetfirstinternal(first[2].internal)
ctx_btxsetfirstpage(first[1])
if last then
@@ -2044,7 +2048,8 @@ do
}
local function identical(a,b)
- local na, nb = #a, #b
+ local na = #a
+ local nb = #b
if na ~= nb then
return false
end
@@ -2056,7 +2061,8 @@ do
end
return true
end
- local ha, hb = a.hash, b.hash
+ local ha = a.hash
+ local hb = b.hash
if ha then
return ha == hb
end
@@ -3456,3 +3462,20 @@ do
}
end
+
+do
+
+ local btxstring = ""
+
+ implement {
+ name = "btxcmdstring",
+ actions = function() if btxstring ~= "" then context(btxstring) end end,
+ }
+
+ function publications.prerollcmdstring(str)
+ btxstring = str or ""
+ tex.runtoks("t_btx_cmd")
+ return nodes.toutf(tex.getbox("b_btx_cmd").list) or str
+ end
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/publ-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/publ-ini.mkiv
index 9f970547d33..ead46929d44 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/publ-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/publ-ini.mkiv
@@ -107,23 +107,27 @@
%D to split between cite and list here as it only complicates matters (timing) and is
%D not clear either.
-\let\currentbtxspecification\empty
+\let\currentbtxspecification \empty
+\let\currentbtxspecificationfallback\empty
+
+\installmacrostack\currentbtxspecification
+\installmacrostack\currentbtxspecificationfallback
\unexpanded\def\startbtxrenderingdefinitions[#1]%
{\unprotect
- \pushmacro\currentbtxspecification
+ \push_macro_currentbtxspecification
\edef\currentbtxspecification{#1}}
\unexpanded\def\stopbtxrenderingdefinitions
- {\popmacro\currentbtxspecification
+ {\pop_macro_currentbtxspecification
\protect}
\unexpanded\def\loadbtxdefinitionfile [#1]{\clf_btxloaddefinitionfile {#1}}
\unexpanded\def\loadbtxreplacementfile[#1]{\clf_btxloadreplacementfile{#1}}
\unexpanded\def\publ_specification_push#1%
- {\pushmacro\currentbtxspecification
- \pushmacro\currentbtxspecificationfallback
+ {\push_macro_currentbtxspecification
+ \push_macro_currentbtxspecificationfallback
\edef\currentbtxspecification{#1}%
\edef\currentbtxspecificationfallback{\namedbtxparameter\currentbtxspecification\c!default}%
\ifx\currentbtxspecificationfallback\currentbtxspecification
@@ -132,8 +136,8 @@
\clf_btxsetspecification{\currentbtxspecification}}
\unexpanded\def\publ_specification_pop
- {\popmacro\currentbtxspecificationfallback
- \popmacro\currentbtxspecification
+ {\pop_macro_currentbtxspecificationfallback
+ \pop_macro_currentbtxspecification
\clf_btxsetspecification{\currentbtxspecification}}
\unexpanded\def\publ_specification_set#1% beware: is global
@@ -223,9 +227,6 @@
\installcommandhandler \??btxregister {btxregister} \??btxregister
\installcommandhandler \??btxrendering {btxrendering} \??btxrendering
-\let\currentbtxcitealternative \empty
-\let\currentbtxspecificationfallback\empty
-
\unexpanded\def\setbtxparameterset#1#2%
{\edef\currentbtx
{\ifcsname\??btx\currentbtxspecification:#1:#2:\s!parent\endcsname
@@ -333,6 +334,11 @@
\expandafter\publ_command_nop
\fi{#1}}
+\newtoks\t_btx_cmd
+\newbox \b_btx_cmd
+
+\t_btx_cmd{\global\setbox\b_btx_cmd\hpack{\clf_btxcmdstring}}
+
\let\btxcmd\btxcommand
\def\publ_command_yes#1%
@@ -341,10 +347,10 @@
\def\publ_command_nop#1%
{\ifcsname#1\endcsname
\showmessage\m!publications{10}{#1,#1}%
- \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname
+ \expandafter\glet\csname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname
\else\ifcsname\utfupper{#1}\endcsname
\showmessage\m!publications{10}{#1}{\utfupper{#1}}%
- \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname
+ \expandafter\glet\csname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname
\else
\showmessage\m!publications{11}{#1}%
\setugvalue{\??btxcommand#1}{\underbar{\tttf#1}}%
@@ -385,6 +391,12 @@
\let\btxsetup\fastsetup
+\def\btxfield #1{\dostarttagged\t!pubfld{#1}\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\def\btxdetail #1{\dostarttagged\t!pubfld{#1}\clf_btxdetail{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\def\btxflush #1{\dostarttagged\t!pubfld{#1}\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\def\btxdirect #1{\dostarttagged\t!pubfld{#1}\clf_btxdirect{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+%def\btxauthorfield#1{\dostarttagged\t!pubfld{#1}\clf_btxauthorfield \currentbtxauthorindex{#1}\dostoptagged}
+
%D How complex will we go? Can we assume that e.g. an apa style will not be mixed
%D with another one? I think this assumption is okay. For manuals we might want to
%D mix but we can work around it.
@@ -629,11 +641,13 @@
\unexpanded\def\btxnumberingsetup#1%
{\begingroup
+ \dostarttagged\t!listtag\empty
\setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering % brrrr \setbtxlist
\btxparameter\c!left
% \btxparameter\c!command{\publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}}%
\publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}%
\btxparameter\c!right
+ \dostoptagged
\endgroup
\btx_reset_numbering} % probably not needed
@@ -655,21 +669,34 @@
\def\btx_entry_inject_list_text
{\publ_fast_setup\plusfour\s!list\s!text}
+\ifdefined\dotagpublication \else \let\dotagpublication \gobbletwoarguments \fi
+
\unexpanded\def\btx_entry_inject
{\begingroup
+ \dostarttagged\t!publication\empty
+ \dotagpublication\currentbtxdataset\currentbtxtag
\redoconvertfont % see (**) in strc-lst, this will become an configuration option
\edef\currentbtxcategory{\btxfield{category}}%
\ignorespaces
\ifconditional\c_btx_list_texts
+ \dostarttagged\t!listtext\s!left
\currentbtxbefore
+ \dostoptagged
\fi
+ %\dostarttagged\t!listcontent\empty
\btx_entry_inject_list_text
+ %\dostoptagged
\ifconditional\c_btx_list_pages
+ \dostarttagged\t!listpage\empty
\btx_entry_inject_pages
+ \dostoptagged
\fi
\ifconditional\c_btx_list_texts
+ \dostarttagged\t!listtext\s!right
\currentbtxafter
+ \dostoptagged
\fi
+ \dostoptagged
\endgroup}
\unexpanded\def\btxshowentryinline
@@ -843,6 +870,8 @@
\expandafter\p_command\expandafter{\number\nofbtxlistentries}\relax
\fi
\else
+ \dostarttagged\t!publications\currentbtxrendering
+ \dostarttagged\t!list{btx}%
\startpacked[\v!blank]%
% sorting and so
\clf_btxpreparelistentries{\currentbtxdataset}% could be put in collect
@@ -865,6 +894,8 @@
{\let\currentbtxlistentry\recurselevel
\clf_btxflushlistentry{\currentbtxdataset}\currentbtxlistentry\relax}%
\stoppacked
+ \dostoptagged
+ \dostoptagged
\fi
\btxrenderingparameter\c!after
\fi
@@ -978,8 +1009,10 @@
\strc_lists_apply_renderingsetup}
\def\btx_entry_indeed
- {\btx_list_reference_inject
- \btx_entry_inject}
+ {\dostarttagged\t!listcontent\empty
+ \btx_list_reference_inject
+ \btx_entry_inject
+ \dostoptagged}
\def\btx_page_indeed
{}
@@ -1113,7 +1146,8 @@
\let\btxcitereference\btx_cite_reference_inject
-\let\currentbtxnumbering\empty
+\let\currentbtxnumbering \empty
+\let\currentbtxcitealternative \empty
\appendtoks
\edef\currentbtxnumbering{\btxrenderingparameter\c!numbering}%
@@ -1995,4 +2029,15 @@
\fetchruntimecommand \showbtxfields \f!publ_tra
\fetchruntimecommand \showbtxtables \f!publ_tra
+%D Some potential crap:
+%D
+%D Because I consider this bad data management and a weird mix of languages only one
+%D accessor is provided.
+
+\unexpanded\def\btxshortcut
+ {\dosingleempty\publ_shortcut}
+
+\def\publ_shortcut[#1]#2%
+ {\clf_btxshortcut{\iffirstargument#1\else\s!default\fi}{#2}}
+
\protect
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-bar.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-bar.mkvi
index 7634398f8db..0c320cd03bf 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-bar.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-bar.mkvi
@@ -138,7 +138,7 @@
\setbox2\hbox{\inheritedinteractionbarframed{\symbol[\interactionparameter\c!symbolset][\v!previouspage]}}%
\scratchheight\ht2 % needed because we default to nothing
\letinteractionbarparameter\c!strut\v!no
- \letinteractionparameter\c!width\zeropoint
+ % \letinteractionparameter\c!width\zeropoint
\scratchcounterone\zerocount % new, was 1
\processallactionsinset
[#list]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-but.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-but.mkvi
index 8bbd6eeda90..87af29cfb9d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-but.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-but.mkvi
@@ -11,20 +11,16 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% \restorestandardblank
-% better namespace for pos
-
\writestatus{loading}{ConTeXt Screen Macros / Buttons}
\registerctxluafile{scrn-but}{}
\unprotect
-%D Buttons are just what their names says: things that can be
-%D clicked (pushed) on. They are similar to \type{\goto},
-%D except that the text argument is not interpreted.
-%D Furthermore one can apply anything to them that can be done
-%D with \type{\framed}.
+%D Buttons are just what their names says: things that can be clicked (pushed) on.
+%D They are similar to \type{\goto}, except that the text argument is not
+%D interpreted. Furthermore one can apply anything to them that can be done with
+%D \type {\framed}.
%D
%D \startbuffer
%D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer]
@@ -119,8 +115,8 @@
%D \overlaybutton[reference]
%D \stoptyping
%D
-%D This command can be used to define overlays an/or can be
-%D used in the whatevertext areas, like:
+%D This command can be used to define overlays an/or can be used in the whatevertext
+%D areas, like:
%D
%D \starttyping
%D \defineoverlay[PrevPage][\overlaybutton{PrevPage}]
@@ -128,8 +124,7 @@
%D \setuptexttexts[\overlaybutton{NextPage}]
%D \stoptyping
%D
-%D For practical reasons, this macro accepts square brackets
-%D as well as braces.
+%D For practical reasons, this macro accepts square brackets as well as braces.
\unexpanded\def\overlaybutton
{\dosingleempty\scrn_button_overlay}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-fld.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-fld.mkvi
index dec334209db..7710a32dcb5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-fld.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-fld.mkvi
@@ -480,7 +480,7 @@
\let\resetfields\relax
-\def\scrn_field_load_scripts{\useJSscripts[fld]\globallet\scrn_field_load_scripts\relax}
+\def\scrn_field_load_scripts{\useJSscripts[fld]\glet\scrn_field_load_scripts\relax}
\newconditional\fieldlabelshown
\newconditional\fieldframeshown
@@ -627,11 +627,13 @@
%D Common stuff (obsolete)
+
\newcount\c_scrn_field_system_n
-\def\nextsystemfield
- {\global\advance\c_scrn_field_system_n\plusone
- \def\currentsystemfield{sys::\number\c_scrn_field_system_n}}
+\def\currentsystemfield{sys::\number\c_scrn_field_system_n}
+
+\unexpanded\def\nextsystemfield
+ {\global\advance\c_scrn_field_system_n\plusone}
%D \CONTEXT\ had tooltips right from the moment that it
%D supported fields. Due to the at that moment somewhat
@@ -754,7 +756,8 @@
{\ifcsname\??fieldstack#tag\endcsname
% already done
\else
- \setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}%
+ %setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}%
+ \setxvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][\normalunexpanded{#settings}]}%
\fi}
\unexpanded\def\fieldstack
@@ -768,26 +771,28 @@
\newbox\b_scrn_fieldstack_box
+\definesymbol[\s!empty][]
+
\def\scrn_fieldstack_add#tag#settings#symbol%
{\advance\scratchcounter\plusone
\edef\currentfieldstackname{#tag:\number\scratchcounter}%
\ifnum\scratchcounter=\fieldcategoryparameter\c!start\relax
- \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\empty},\c!default={#symbol}]%
+ \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default={#symbol}]%
\else
- \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\empty},\c!default=]%
+ \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default=\s!empty]%
\fi
\setbox\b_scrn_fieldstack_box\hbox{\symbol[#symbol]}%
\setcollector
[fieldstack]
{\fieldbody
[\currentfieldstackname]
- [\c!option=\v!readonly,
+ [\c!option={\v!readonly},
\c!width=\wd\b_scrn_fieldstack_box,
\c!height=\ht\b_scrn_fieldstack_box,
\c!depth=\dp\b_scrn_fieldstack_box,
#settings]}}
-\def\scrn_fieldstack_construct[#tag][#symbols][#settings]% start=n, 0 == leeg
+\unexpanded\def\scrn_fieldstack_construct[#tag][#symbols][#settings]% start=n, 0 == leeg
{\iflocation
\dontleavehmode
\begingroup
@@ -822,21 +827,56 @@
\unexpanded\def\overlayrollbutton
{\dodoubleargument\scrn_rollbutton_overlay}
-\def\scrn_rollbutton_overlay[#regionin][#regionout]%
+\unexpanded\def\scrn_rollbutton_overlay[#regionin][#regionout]%
+ {\iffirstargument
+ \scrn_rollbutton_overlay_indeed[#regionin][#regionout]%
+ \else
+ \expandafter\scrn_rollbutton_overlay_indeed
+ \fi}
+
+% \def\scrn_rollbutton_overlay_indeed#regionin#regionout%
+% {\iflocation
+% \bgroup
+% \global\advance\c_scrn_rollbutton_n\plusone
+% \definesymbol
+% [rollbutton:\number\c_scrn_rollbutton_n]
+% [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]%
+% \definefieldbody
+% [rollbutton:\number\c_scrn_rollbutton_n]
+% [\c!type=push,
+% \c!regionin={#regionin},
+% \c!regionout={#regionout},
+% \c!values=\currentsystemfield,
+% \c!default=\currentsystemfield]%
+% \fitfield[\currentsystemfield]%
+% \egroup
+% \fi}
+
+\def\scrn_rollbutton_overlay_indeed#regionin#regionout%
{\iflocation
\bgroup
- \global\advance\c_scrn_rollbutton_n\plusone
+ \global\advance\c_scrn_rollbutton_n_button\plusone
+ \global\advance\c_scrn_rollbutton_n_symbol\plusone
\definesymbol
- [rollbutton:\number\c_scrn_rollbutton_n]
+ [rollsymbol:\number\c_scrn_rollbutton_n_symbol]
[{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]%
- \definefieldbody
- [rollbutton:\number\c_scrn_rollbutton_n]
- [\c!type=push,
- \c!regionin={#regionin},
- \c!regionout={#regionout},
- \c!values=\currentsystemfield,
- \c!default=\currentsystemfield]%
- \fitfield[\currentsystemfield]%
+ % \definefieldbody
+ % [rollbutton:\number\c_scrn_rollbutton_n_button]
+ % [\c!type=push,
+ % \c!values=rollsymbol:\number\c_scrn_rollbutton_n_symbol,
+ % \c!default=rollsymbol:\number\c_scrn_rollbutton_n_symbol]%
+ % \fitfield
+ % [rollbutton:\number\c_scrn_rollbutton_n_button]%
+ % [\c!regionin={#regionin},
+ % \c!regionout={#regionout}]%
+ %
+ \definefield
+ [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton]
+ [rollsymbol:\number\c_scrn_rollbutton_n_symbol]%
+ \fitfield
+ [rollbutton:\number\c_scrn_rollbutton_n_button]%
+ [\c!regionin={#regionin},\c!regionout={#regionout}]%
+ %
\egroup
\fi}
@@ -914,7 +954,7 @@
%D We plug into the menu system
\unexpanded\def\scrn_menu_psh_start[#reference]#text\stoppsh
- {\starttxt\pushbutton[\currentmenu][#reference]\stoptxt}
+ {\starttxt\pushbutton[\currentinteractionmenu][#reference]\stoptxt}
\unexpanded\def\scrn_menu_psh_direct[#reference]#text\\
{\scrn_menu_psh_start[#reference]\stoprob}
@@ -956,6 +996,8 @@
\newcount\c_scrn_rollbutton_n_button
\newcount\c_scrn_rollbutton_n_symbol
+\def\lastrollbuttonindex{\the\c_scrn_rollbutton_n_button}
+
\unexpanded\def\rollbutton
{\dodoubleempty\scrn_rollbutton}
@@ -973,11 +1015,16 @@
\setbuttonparameter
\usebuttonstyleandcolor}
+\setupfield
+ [rollbutton]
+ [\c!frame=\v!off,
+ \c!offset=\v!overlay]
+
\def\scrn_rollbutton[#tag][#settings]#text[#reference]%
{\dontleavehmode
\bgroup
- \advance\c_scrn_rollbutton_n_button\plusone
- \advance\c_scrn_rollbutton_n_symbol\plusone
+ \global\advance\c_scrn_rollbutton_n_button\plusone
+ \global\advance\c_scrn_rollbutton_n_symbol\plusone
\iffirstargument
\ifsecondargument
\edef\currentinteractionmenu{#tag}%
@@ -994,21 +1041,18 @@
\else
\let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b
\fi
- % todo: share symbols, tricky since different dimensions
+ % todo: share symbols, tricky since different dimensions (maybe \unique...)
\definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:n][\scrn_rollbutton_symbol{n}{#text}]%
\definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:r][\scrn_rollbutton_symbol{r}{#text}]%
\definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:d][\scrn_rollbutton_symbol{d}{#text}]%
- \setupfield
- [rollbutton]
- [\c!frame=\v!off,
- \c!offset=\v!overlay,
- \c!clickout={#reference}]%
\definefield
[rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton]
[rollsymbol:\number\c_scrn_rollbutton_n_symbol:n,%
rollsymbol:\number\c_scrn_rollbutton_n_symbol:r,%
rollsymbol:\number\c_scrn_rollbutton_n_symbol:d]%
- \fitfield[rollbutton:\number\c_scrn_rollbutton_n_button]%
+ \fitfield
+ [rollbutton:\number\c_scrn_rollbutton_n_button]%
+ [\c!clickout={#reference}]%
\egroup}
\unexpanded\def\scrn_rollbutton_symbol_indeed#getparameter#inheritedframed#setparameter#usestyleandcolor#what#text%
@@ -1023,7 +1067,7 @@
%D We plug into the menu system
\unexpanded\def\scrn_menu_rob_start[#reference]#text\stoprob
- {\starttxt\rollbutton[\currentmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt}
+ {\starttxt\rollbutton[\currentinteractionmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt}
\unexpanded\def\scrn_menu_rob_direct[#reference]#text\\
{\scrn_menu_rob_start[#reference]#text\stoprob}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-ini.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-ini.mkvi
index e1be43f3782..557ceb5631a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-ini.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-ini.mkvi
@@ -61,7 +61,7 @@
\to \everyjob
% it makes no sense to create an environment as we will seldom have structured
-% interactionso a general start-stop will do
+% interactions so a general start-stop will do
%
% \appendtoks
% \setuevalue \currentinteraction {\scrn_interaction_direct{\currentinteraction}}%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-pag.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-pag.mkvi
index 7695443adb2..a3b0a78c61c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-pag.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-pag.mkvi
@@ -188,13 +188,13 @@
\let\scrn_canvas_synchronize_complex\relax
\appendtoks
- \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
- \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
+ \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
+ \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
\to \everysetuplayout
\appendtoks
- \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
- \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
+ \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
+ \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
\to \everysetuplayouttarget
\def\scrn_canvas_synchronize_only
@@ -213,8 +213,8 @@
\def\scrn_canvas_synchronize_simple_indeed
{\scrn_canvas_synchronize_only
- %\global\let\scrn_canvas_synchronize_simple \relax
- \global\let\scrn_canvas_synchronize_complex\relax}
+ %\glet\scrn_canvas_synchronize_simple \relax
+ \glet\scrn_canvas_synchronize_complex\relax}
\def\scrn_canvas_synchronize_complex_indeed
{\scrn_canvas_calculate % otherwise we need to hook it into setuppage etc
@@ -235,8 +235,8 @@
copies \numexpr\interactionscreenparameter\c!copies\relax
print {\interactionscreenparameter\c!print}%
\relax
- %\global\let\scrn_canvas_synchronize_simple \relax
- \global\let\scrn_canvas_synchronize_complex\relax}
+ %\glet\scrn_canvas_synchronize_simple \relax
+ \glet\scrn_canvas_synchronize_complex\relax}
\appendtoks
\begingroup
@@ -262,8 +262,8 @@
\c!option=\v!auto]
\appendtoks
- \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
- \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
+ \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed
+ \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed
\to \everysetupinteractionscreen
%D Conditional page breaks:
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-ref.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-ref.mkvi
index bace1331288..df395e5505b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-ref.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-ref.mkvi
@@ -83,15 +83,15 @@
%D delayed ...
-\def\scrn_reference_enable_references
- {\ifproductionrun
- \clf_enableinteraction % only once anyway
- \glet\scrn_reference_enable_references\relax
- \fi}
-
-\appendtoks
- \scrn_reference_enable_references
-\to \everysetupinteraction
+% \def\scrn_reference_enable_references
+% {\ifproductionrun
+% \clf_enableinteraction % only once anyway
+% \glet\scrn_reference_enable_references\relax
+% \fi}
+%
+% \appendtoks
+% \scrn_reference_enable_references
+% \to \everysetupinteraction
\setupinteraction % start fit page and reset form
[\c!openaction=,
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrn-wid.mkvi b/Master/texmf-dist/tex/context/base/mkiv/scrn-wid.mkvi
index c74125c72b6..d1571ca656d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrn-wid.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrn-wid.mkvi
@@ -212,11 +212,10 @@
name {\attachmentparameter\c!name}%
buffer {\attachmentparameter\c!buffer}%
\relax
- \setbox\b_scrn_attachment_link\hbox{\scrn_attachment_place}%
\wd\b_scrn_attachment_link\currentattachmentwidth
\ht\b_scrn_attachment_link\currentattachmentheight
\dp\b_scrn_attachment_link\currentattachmentdepth
- \box\b_scrn_attachment_link}
+ \expandnamespaceparameter\??attachmentlocation\attachmentparameter\c!location\s!unknown}
\setvalue{\??attachmentmethod\v!hidden}%
{\clf_insertattachment
@@ -231,29 +230,48 @@
buffer {\attachmentparameter\c!buffer}%
\relax}
-\def\scrn_attachment_place
- {\executeifdefined
- {\??attachmentlocation\attachmentparameter\c!location}\hbox
- {\box\b_scrn_attachment_link}}
-
-\setvalue{\??attachmentlocation\v!inmargin }{\inmargin }
-\setvalue{\??attachmentlocation\v!leftedge }{\inleftedge }
-\setvalue{\??attachmentlocation\v!rightedge }{\inrightedge }
-\setvalue{\??attachmentlocation\v!leftmargin }{\inleftmargin }
-\setvalue{\??attachmentlocation\v!rightmargin}{\inrightmargin}
-\setvalue{\??attachmentlocation\v!high }{\high}
-\setvalue{\??attachmentlocation\v!none }{\scrn_attachment_collect}
-%setvalue{\??attachmentlocation\v!text }{\gobblenextargument} % gobbles the box
-
-\def\scrn_attachment_collect#content%
+\unexpanded\def\scrn_attachment_flush_traced
+ {\hpack\bgroup
+ \blackrule % can be a fast one
+ [ \c!color=trace:r,
+ \c!width=\wd\b_scrn_attachment_link,
+ \c!height=\ht\b_scrn_attachment_link,
+ \c!depth=\dp\b_scrn_attachment_link]%
+ \kern-\wd\b_scrn_attachment_link
+ \box\b_scrn_attachment_link
+ \egroup}
+
+\unexpanded\def\scrn_attachment_flush_normal
+ {\box\b_scrn_attachment_link}
+
+\installtextracker
+ {attachments.anchors}
+ {\let\scrn_attachment_flush\scrn_attachment_flush_traced}
+ {\let\scrn_attachment_flush\scrn_attachment_flush_normal}
+
+\let\scrn_attachment_flush\scrn_attachment_flush_normal
+
+\setvalue{\??attachmentlocation\v!inmargin }{\inmargin {\scrn_attachment_flush}}
+\setvalue{\??attachmentlocation\v!leftedge }{\inleftedge {\scrn_attachment_flush}}
+\setvalue{\??attachmentlocation\v!rightedge }{\inrightedge {\scrn_attachment_flush}}
+\setvalue{\??attachmentlocation\v!leftmargin }{\inleftmargin {\scrn_attachment_flush}}
+\setvalue{\??attachmentlocation\v!rightmargin}{\inrightmargin{\scrn_attachment_flush}}
+\setvalue{\??attachmentlocation\v!high }{\high {\scrn_attachment_flush}}
+
+\setvalue{\??attachmentlocation\v!none}%
{\global\setbox\b_scrn_attachment_collect\hbox\bgroup
\ifvoid\b_scrn_attachment_collect\else
\box\b_scrn_attachment_collect
\hskip\attachmentparameter\c!distance\relax
\fi
- #content%
+ \scrn_attachment_flush
\egroup}
+\setvalue{\??attachmentlocation\s!unknown}%
+ {\ifvoid\b_scrn_attachment_collect\else
+ \box\b_scrn_attachment_collect
+ \fi}
+
\unexpanded\def\placeattachments
{\ifvoid\b_scrn_attachment_collect\else
\box\b_scrn_attachment_collect
@@ -317,7 +335,7 @@
%
% test
%
-% \startcomment[symbol=Balloon]
+% \startcomment[symbol=Help]
% Do we want this kind of rubish?
% \stopcomment
%
@@ -360,6 +378,9 @@
%
% test
+%D The implementation is mostly the same as for attachments but sharing code
+%D will not make it cleaner.
+
\installcorenamespace{comment}
\installcorenamespace{commentlocation}
@@ -489,17 +510,37 @@
\dp\b_scrn_comment_link\currentcommentdepth
\expandnamespaceparameter\??commentlocation\commentparameter\c!location\s!unknown}
-\setvalue{\??commentmethods\v!hidden}%
- {}
+\letvalue{\??commentmethods\v!hidden}\donothing
+
+\unexpanded\def\scrn_comment_flush_traced
+ {\hpack\bgroup
+ \blackrule % can be a fast one
+ [ \c!color=trace:y,
+ \c!width=\wd\b_scrn_comment_link,
+ \c!height=\ht\b_scrn_comment_link,
+ \c!depth=\dp\b_scrn_comment_link]%
+ \kern-\wd\b_scrn_comment_link
+ \box\b_scrn_comment_link
+ \egroup}
+
+\unexpanded\def\scrn_comment_flush_normal
+ {\box\b_scrn_comment_link}
+
+\installtextracker
+ {comments.anchors}
+ {\let\scrn_comment_flush\scrn_comment_flush_traced}
+ {\let\scrn_comment_flush\scrn_comment_flush_normal}
+
+\let\scrn_comment_flush\scrn_comment_flush_normal
% todo: dedicated margin classes
-\setvalue{\??commentlocation\v!inmargin }{\inmargin {\box\b_scrn_comment_link}}
-\setvalue{\??commentlocation\v!leftedge }{\inleftedge {\box\b_scrn_comment_link}}
-\setvalue{\??commentlocation\v!rightedge }{\inrightedge {\box\b_scrn_comment_link}}
-\setvalue{\??commentlocation\v!leftmargin }{\inleftmargin {\box\b_scrn_comment_link}}
-\setvalue{\??commentlocation\v!rightmargin}{\inrightmargin{\box\b_scrn_comment_link}}
-\setvalue{\??commentlocation\v!high }{\high {\box\b_scrn_comment_link}}
+\setvalue{\??commentlocation\v!inmargin }{\inmargin {\scrn_comment_flush}}
+\setvalue{\??commentlocation\v!leftedge }{\inleftedge {\scrn_comment_flush}}
+\setvalue{\??commentlocation\v!rightedge }{\inrightedge {\scrn_comment_flush}}
+\setvalue{\??commentlocation\v!leftmargin }{\inleftmargin {\scrn_comment_flush}}
+\setvalue{\??commentlocation\v!rightmargin}{\inrightmargin{\scrn_comment_flush}}
+\setvalue{\??commentlocation\v!high }{\high {\scrn_comment_flush}}
\setvalue{\??commentlocation\v!none}%
{\global\setbox\b_scrn_comment_collect\hbox\bgroup
@@ -507,7 +548,7 @@
\box\b_scrn_comment_collect
\hskip\commentparameter\c!distance\relax
\fi
- \box\b_scrn_comment_link
+ \scrn_comment_flush
\egroup}
\setvalue{\??commentlocation\s!unknown}%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrp-cjk.lua b/Master/texmf-dist/tex/context/base/mkiv/scrp-cjk.lua
index b31dc335a4a..83eecf6a3b3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrp-cjk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrp-cjk.lua
@@ -6,23 +6,24 @@ if not modules then modules = { } end modules ['scrp-cjk'] = {
license = "see context related readme files"
}
--- We can speed this up by preallocating nodes and copying them but the
--- gain is not that large.
-
--- The input line endings: there is no way to distinguish between
--- inline spaces and endofline turned into spaces (would not make
--- sense either because otherwise a wanted space at the end of a
--- line would have to be a hard coded ones.
+-- We can speed this up by preallocating nodes and copying them but the gain is not
+-- that large.
+--
+-- If needed we can speed this up (traversers and prev next and such) but cjk
+-- documents don't have that many glyphs and certainly not much font processing so
+-- there not much gain in it.
+--
+-- The input line endings: there is no way to distinguish between inline spaces and
+-- endofline turned into spaces (would not make sense either because otherwise a
+-- wanted space at the end of a line would have to be a hard coded ones.
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local copy_node = nuts.copy
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -41,12 +42,14 @@ local new_kern = nodepool.kern
local new_penalty = nodepool.penalty
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
+
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
-local userskip_code = skipcodes.userskip
-local spaceskip_code = skipcodes.spaceskip
-local xspaceskip_code = skipcodes.xspaceskip
+
+local userskip_code = gluecodes.userskip
+local spaceskip_code = gluecodes.spaceskip
+local xspaceskip_code = gluecodes.xspaceskip
local a_scriptstatus = attributes.private('scriptstatus')
local a_scriptinjection = attributes.private('scriptinjection')
@@ -439,13 +442,16 @@ local injectors = { -- [previous] [current]
local function process(head,first,last)
if first ~= last then
- local lastfont, previous, last = nil, "start", nil
+ local lastfont = nil
+ local previous = "start"
+ local last = nil
while true do
- local upcoming, id = getnext(first), getid(first)
+ local upcoming = getnext(first)
+ local id = getid(first)
if id == glyph_code then
- local a = getattr(first,a_scriptstatus)
+ local a = getattr(first,a_scriptstatus)
local current = numbertocategory[a]
- local action = injectors[previous]
+ local action = injectors[previous]
if action then
action = action[current]
if action then
@@ -459,12 +465,16 @@ local function process(head,first,last)
end
previous = current
else -- glue
- local p, n = getprev(first), upcoming
+ local p = getprev(first)
+ local n = upcoming
if p and n then
- local pid, nid = getid(p), getid(n)
+ local pid = getid(p)
+ local nid = getid(n)
if pid == glyph_code and nid == glyph_code then
- local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus)
- local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
+ local pa = getattr(p,a_scriptstatus)
+ local na = getattr(n,a_scriptstatus)
+ local pcjk = pa and numbertocategory[pa]
+ local ncjk = na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
or pcjk == "other" or ncjk == "other"
@@ -509,10 +519,9 @@ scripts.installmethod {
}
function scripts.decomposehangul(head)
- local head = tonut(head)
local done = false
- for current in traverse_id(glyph_code,head) do
- local lead_consonant, medial_vowel, tail_consonant = decomposed(getchar(current))
+ for current, char in nextglyph, head do
+ local lead_consonant, medial_vowel, tail_consonant = decomposed(char)
if lead_consonant then
setchar(current,lead_consonant)
local m = copy_node(current)
@@ -526,7 +535,7 @@ function scripts.decomposehangul(head)
done = true
end
end
- return tonode(head), done
+ return head, done
end
-- nodes.tasks.prependaction("processors","normalizers","scripts.decomposehangul")
@@ -695,13 +704,16 @@ local injectors = { -- [previous] [current]
local function process(head,first,last)
if first ~= last then
- local lastfont, previous, last = nil, "start", nil
+ local lastfont = nil
+ local previous = "start"
+ local last = nil
while true do
- local upcoming, id = getnext(first), getid(first)
+ local upcoming = getnext(first)
+ local id = getid(first)
if id == glyph_code then
- local a = getattr(first,a_scriptstatus)
+ local a = getattr(first,a_scriptstatus)
local current = numbertocategory[a]
- local action = injectors[previous]
+ local action = injectors[previous]
if action then
action = action[current]
if action then
@@ -715,12 +727,16 @@ local function process(head,first,last)
end
previous = current
else -- glue
- local p, n = getprev(first), upcoming
+ local p = getprev(first)
+ local n = upcoming
if p and n then
- local pid, nid = getid(p), getid(n)
+ local pid = getid(p)
+ local nid = getid(n)
if pid == glyph_code and nid == glyph_code then
- local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus)
- local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
+ local pa = getattr(p,a_scriptstatus)
+ local na = getattr(n,a_scriptstatus)
+ local pcjk = pa and numbertocategory[pa]
+ local ncjk = na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
or pcjk == "other" or ncjk == "other"
@@ -917,13 +933,16 @@ local injectors = { -- [previous] [current]
local function process(head,first,last)
if first ~= last then
- local lastfont, previous, last = nil, "start", nil
+ local lastfont = nil
+ local previous = "start"
+ local last = nil
while true do
- local upcoming, id = getnext(first), getid(first)
+ local upcoming = getnext(first)
+ local id = getid(first)
if id == glyph_code then
- local a = getattr(first,a_scriptstatus)
+ local a = getattr(first,a_scriptstatus)
local current = numbertocategory[a]
- local action = injectors[previous]
+ local action = injectors[previous]
if action then
action = action[current]
if action then
@@ -940,12 +959,16 @@ local function process(head,first,last)
-- upcoming = getnext(end_of_math(current))
-- previous = "start"
else -- glue
- local p, n = getprev(first), upcoming -- we should remember prev
+ local p = getprev(first)
+ local n = upcoming
if p and n then
- local pid, nid = getid(p), getid(n)
+ local pid = getid(p)
+ local nid = getid(n)
if pid == glyph_code and nid == glyph_code then
- local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus)
- local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
+ local pa = getattr(p,a_scriptstatus)
+ local na = getattr(n,a_scriptstatus)
+ local pcjk = pa and numbertocategory[pa]
+ local ncjk = na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
or pcjk == "other" or ncjk == "other"
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrp-eth.lua b/Master/texmf-dist/tex/context/base/mkiv/scrp-eth.lua
index 43cb2ff6a4e..f6a994b884b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrp-eth.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrp-eth.lua
@@ -12,71 +12,16 @@ if not modules then modules = { } end modules ['scrp-eth'] = {
local nuts = nodes.nuts
local getnext = nuts.getnext
-local getfont = nuts.getfont
-local getid = nuts.getid
+local ischar = nuts.ischar
local getattr = nuts.getattr
-local insert_node_before = nuts.insert_before
-
-local nodepool = nuts.pool
-
-local new_glue = nodepool.glue
-local new_penalty = nodepool.penalty
-
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
local a_scriptstatus = attributes.private('scriptstatus')
-local a_scriptinjection = attributes.private('scriptinjection')
-local categorytonumber = scripts.categorytonumber
local numbertocategory = scripts.numbertocategory
-local hash = scripts.hash
-local numbertodataset = scripts.numbertodataset
-
-local fonthashes = fonts.hashes
-local parameters = fonthashes.parameters
-
-local space, stretch, shrink, lastfont
-
-local inter_character_space_factor = 1
-local inter_character_stretch_factor = 1
-local inter_character_shrink_factor = 1
-
-local function space_glue(current)
- local data = numbertodataset[getattr(current,a_scriptinjection)]
- if data then
- inter_character_space_factor = data.inter_character_space_factor or 1
- inter_character_stretch_factor = data.inter_character_stretch_factor or 1
- inter_character_shrink_factor = data.inter_character_shrink_factor or 1
- end
- local font = getfont(current)
- if lastfont ~= font then
- local pf = parameters[font]
- space = pf.space
- stretch = pf.space_stretch
- shrink = pf.space_shrink
- lastfont = font
- end
- return new_glue(
- inter_character_space_factor * space,
- inter_character_stretch_factor * stretch,
- inter_character_shrink_factor * shrink
- )
-end
-
-local function insert_space(head,current)
- insert_node_before(head,current,space_glue(current))
-end
-
-local function insert_zerowidthspace(head,current)
- insert_node_before(head,current,new_glue(0))
-end
-
-local function insert_nobreakspace(head,current)
- insert_node_before(head,current,new_penalty(10000))
- insert_node_before(head,current,space_glue(current))
-end
+local inserters = scripts.inserters
-- syllable [zerowidthspace] syllable
-- syllable [zerowidthspace] word
@@ -88,21 +33,22 @@ end
-- sentence [space] word
-- sentence [space] sentence
+
local injectors = { -- [previous] [current]
ethiopic_syllable = {
- ethiopic_syllable = insert_zerowidthspace,
- ethiopic_word = insert_nobreakspace,
- ethiopic_sentence = insert_nobreakspace,
+ ethiopic_syllable = inserters.zerowidthspace_before,
+ ethiopic_word = inserters.nobreakspace_before,
+ ethiopic_sentence = inserters.nobreakspace_before,
},
ethiopic_word = {
- ethiopic_syllable = insert_space,
- ethiopic_word = insert_space,
- ethiopic_sentence = insert_space,
+ ethiopic_syllable = inserters.space_before,
+ ethiopic_word = inserters.space_before,
+ ethiopic_sentence = inserters.space_before,
},
ethiopic_sentence = {
- ethiopic_syllable = insert_space,
- ethiopic_word = insert_space,
- ethiopic_sentence = insert_space,
+ ethiopic_syllable = inserters.space_before,
+ ethiopic_word = inserters.space_before,
+ ethiopic_sentence = inserters.space_before,
},
}
@@ -111,10 +57,10 @@ local function process(head,first,last)
local injector = false
local current = first
while current do
- local id = getid(current)
- if id == glyph_code then
+ local char, id = ischar(current)
+ if char then
local scriptstatus = getattr(current,a_scriptstatus)
- local category = numbertocategory[scriptstatus]
+ local category = numbertocategory[scriptstatus]
if injector then
local action = injector[category]
if action then
@@ -122,8 +68,6 @@ local function process(head,first,last)
end
end
injector = injectors[category]
- else
- -- nothing yet
end
if current == last then
break
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.lua
index 9bd70e30af1..e6aa5f0720c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.lua
@@ -22,72 +22,75 @@ local report_splitting = logs.reporter("scripts","splitting")
local utfbyte, utfsplit = utf.byte, utf.split
local gmatch = string.gmatch
-local attributes = attributes
-local nodes = nodes
-local context = context
+local attributes = attributes
+local nodes = nodes
+local context = context
-local texsetattribute = tex.setattribute
+local texsetattribute = tex.setattribute
-local nodecodes = nodes.nodecodes
-local unsetvalue = attributes.unsetvalue
+local nodecodes = nodes.nodecodes
+local unsetvalue = attributes.unsetvalue
-local implement = interfaces.implement
+local implement = interfaces.implement
-local glyph_code = nodecodes.glyph
-local glue_code = nodecodes.glue
+local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
-local emwidths = fonts.hashes.emwidths
-local exheights = fonts.hashes.exheights
+local emwidths = fonts.hashes.emwidths
+local exheights = fonts.hashes.exheights
-local a_scriptinjection = attributes.private('scriptinjection')
-local a_scriptsplitting = attributes.private('scriptsplitting')
-local a_scriptstatus = attributes.private('scriptstatus')
+local a_scriptinjection = attributes.private('scriptinjection')
+local a_scriptsplitting = attributes.private('scriptsplitting')
+local a_scriptstatus = attributes.private('scriptstatus')
-local fontdata = fonts.hashes.identifiers
-local allocate = utilities.storage.allocate
-local setnodecolor = nodes.tracers.colors.set
-local setmetatableindex = table.setmetatableindex
+local fontdata = fonts.hashes.identifiers
+local allocate = utilities.storage.allocate
+local setnodecolor = nodes.tracers.colors.set
+local setmetatableindex = table.setmetatableindex
-local enableaction = nodes.tasks.enableaction
-local disableaction = nodes.tasks.disableaction
+local enableaction = nodes.tasks.enableaction
+local disableaction = nodes.tasks.disableaction
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
+local nuts = nodes.nuts
-local getnext = nuts.getnext
-local getchar = nuts.getchar
-local getfont = nuts.getfont
-local getid = nuts.getid
-local getattr = nuts.getattr
-local setattr = nuts.setattr
-local isglyph = nuts.isglyph
+local getnext = nuts.getnext
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getid = nuts.getid
+local getattr = nuts.getattr
+local setattr = nuts.setattr
+local isglyph = nuts.isglyph
-local insert_node_after = nuts.insert_after
-local first_glyph = nuts.first_glyph
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+local insert_node_after = nuts.insert_after
+local insert_node_before = nuts.insert_before
-local nodepool = nuts.pool
+local first_glyph = nuts.first_glyph
-local new_glue = nodepool.glue
-local new_rule = nodepool.rule
-local new_penalty = nodepool.penalty
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextglyph = nuts.traversers.glyph
+local nextchar = nuts.traversers.char
-scripts = scripts or { }
-local scripts = scripts
+local nodepool = nuts.pool
-scripts.hash = scripts.hash or { }
-local hash = scripts.hash
+local new_glue = nodepool.glue
+local new_rule = nodepool.rule
+local new_penalty = nodepool.penalty
-local handlers = allocate()
-scripts.handlers = handlers
+scripts = scripts or { }
+local scripts = scripts
-local injectors = allocate()
-scripts.injectors = handlers
+scripts.hash = scripts.hash or { }
+local hash = scripts.hash
-local splitters = allocate()
-scripts.splitters = splitters
+local handlers = allocate()
+scripts.handlers = handlers
+
+local injectors = allocate()
+scripts.injectors = handlers
+
+local splitters = allocate()
+scripts.splitters = splitters
local hash = { -- we could put these presets in char-def.lua
--
@@ -206,6 +209,11 @@ local hash = { -- we could put these presets in char-def.lua
[0x1361] = "ethiopic_word",
[0x1362] = "ethiopic_sentence",
--
+ -- tibetan:
+ --
+ [0x0F0B] = "breaking_tsheg",
+ [0x0F0C] = "nonbreaking_tsheg",
+
}
local function provide(t,k)
@@ -225,6 +233,7 @@ local function provide(t,k)
elseif (k >= 0x01160 and k <= 0x011A7) then v = "jamo_medial"
elseif (k >= 0x011A8 and k <= 0x011FF) then v = "jamo_final"
elseif (k >= 0x01200 and k <= 0x0139F) then v = "ethiopic_syllable"
+ elseif (k >= 0x00F00 and k <= 0x00FFF) then v = "tibetan"
else v = false
end
t[k] = v
@@ -267,6 +276,7 @@ function scripts.installmethod(handler)
report_preprocessing("missing (default) dataset in script %a",name)
datasets.default = { } -- slower but an error anyway
end
+
for k, v in next, datasets do
setmetatableindex(v,defaults)
end
@@ -387,6 +397,8 @@ local scriptcolors = allocate { -- todo: just named colors
ethiopic_syllable = "trace:1",
ethiopic_word = "trace:2",
ethiopic_sentence = "trace:3",
+ breaking_tsheg = "trace:1",
+ nonbreaking_tsheg = "trace:2",
}
scripts.colors = scriptcolors
@@ -409,6 +421,8 @@ local numbertocategory = allocate { -- rather bound to cjk ... will be generaliz
"ethiopic_syllable",
"ethiopic_word",
"ethiopic_sentence",
+ "breaking_tsheg",
+ "nonbreaking_tsheg",
}
local categorytonumber = allocate(table.swapped(numbertocategory)) -- could be one table
@@ -417,7 +431,7 @@ scripts.categorytonumber = categorytonumber
scripts.numbertocategory = numbertocategory
local function colorize(start,stop)
- for n in traverse_id(glyph_code,start) do
+ for n in nextglyph, start do
local kind = numbertocategory[getattr(n,a_scriptstatus)]
if kind then
local ac = scriptcolors[kind]
@@ -450,13 +464,12 @@ end
-- we can have a fonts.hashes.originals
function scripts.injectors.handler(head)
- head = tonut(head)
local start = first_glyph(head) -- we already have glyphs here (subtype 1)
if not start then
- return tonode(head), false
+ return head
else
- local last_a, normal_process, lastfont, originals = nil, nil, nil, nil
- local done, first, last, ok = false, nil, nil, false
+ local last_a, normal_process, lastfont, originals, first, last
+ local ok = false
while start do
local char, id = isglyph(start)
if char then
@@ -473,7 +486,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -482,16 +495,15 @@ function scripts.injectors.handler(head)
normal_process = handler.injector
end
if normal_process then
- -- wrong: originals are indices !
- local font = getfont(start)
- if font ~= lastfont then
- originals = fontdata[font].resources
+ -- id == font
+ if id ~= lastfont then
+ originals = fontdata[id].resources
if resources then
originals = resources.originals
else
originals = nil -- can't happen
end
- lastfont = font
+ lastfont = id
end
if originals and type(originals) == "number" then
char = originals[char] or char
@@ -517,7 +529,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -532,7 +544,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -554,7 +566,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- first, last, ok, done = nil, nil, false, true
+ first, last, ok = nil, nil, false
elseif first then
first, last = nil, nil
end
@@ -570,16 +582,15 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- done = true
end
- return tonode(head), done
+ return head
end
end
-- kind of experimental .. might move to it's own module
-- function scripts.splitters.handler(head)
--- return head, false
+-- return head
-- end
local function addwords(tree,data)
@@ -701,32 +712,6 @@ end)
local categories = characters.categories or { }
--- local function hit(root,head)
--- local current = getnext(head)
--- local lastrun = false
--- local lastfinal = false
--- while current and getid(current) == glyph_code do
--- local char = getchar(current)
--- local newroot = root[char]
--- if newroot then
--- local final = newroot.final
--- if final then
--- lastrun = current
--- lastfinal = final
--- end
--- root = newroot
--- elseif categories[char] == "mn" then
--- -- continue
--- else
--- return lastrun, lastfinal
--- end
--- current = getnext(current)
--- end
--- if lastrun then
--- return lastrun, lastfinal
--- end
--- end
-
local function hit(root,head)
local current = getnext(head)
local lastrun = false
@@ -759,9 +744,7 @@ end
local tree, attr, proc
function splitters.handler(head) -- todo: also first_glyph test
- head = tonut(head)
local current = head
- local done = false
while current do
if getid(current) == glyph_code then
local a = getattr(current,a_scriptsplitting)
@@ -792,7 +775,6 @@ function splitters.handler(head) -- todo: also first_glyph test
end
end
head, current = proc(handler,head,current,last,1)
- done = true
else
if trace_splitdetail then
-- could be punctuation
@@ -803,7 +785,6 @@ function splitters.handler(head) -- todo: also first_glyph test
end
end
head, current = proc(handler,head,current,last,2)
- done = true
end
end
end
@@ -813,7 +794,7 @@ function splitters.handler(head) -- todo: also first_glyph test
end
current = getnext(current)
end
- return tonode(head), done
+ return head
end
local function marker(head,current,font,color) -- could become: nodes.tracers.marker
@@ -907,15 +888,13 @@ setmetatableindex(cache_nop,function(t,k) local v = { } t[k] = v return v end)
-- playing nice
function autofontfeature.handler(head)
- for n in traverse_char(tonut(head)) do
+ for n, char, font in nextchar, head do
-- if getattr(n,a_scriptinjection) then
-- -- already tagged by script feature, maybe some day adapt
-- else
- local char = getchar(n)
local script = otfscripts[char]
if script then
local dynamic = getattr(n,0) or 0
- local font = getfont(n)
if dynamic > 0 then
local slot = cache_yes[font]
local attr = slot[script]
@@ -980,3 +959,73 @@ implement {
name = "resetscript",
actions = scripts.reset
}
+
+-- some common helpers
+
+
+do
+
+ local parameters = fonts.hashes.parameters
+
+ local space, stretch, shrink, lastfont
+
+ local inter_character_space_factor = 1
+ local inter_character_stretch_factor = 1
+ local inter_character_shrink_factor = 1
+
+ local function space_glue(current)
+ local data = numbertodataset[getattr(current,a_scriptinjection)]
+ if data then
+ inter_character_space_factor = data.inter_character_space_factor or 1
+ inter_character_stretch_factor = data.inter_character_stretch_factor or 1
+ inter_character_shrink_factor = data.inter_character_shrink_factor or 1
+ end
+ local font = getfont(current)
+ if lastfont ~= font then
+ local pf = parameters[font]
+ space = pf.space
+ stretch = pf.space_stretch
+ shrink = pf.space_shrink
+ lastfont = font
+ end
+ return new_glue(
+ inter_character_space_factor * space,
+ inter_character_stretch_factor * stretch,
+ inter_character_shrink_factor * shrink
+ )
+ end
+
+ scripts.inserters = {
+
+ space_before = function(head,current)
+ return insert_node_before(head,current,space_glue(current))
+ end,
+ space_after = function(head,current)
+ return insert_node_after(head,current,space_glue(current))
+ end,
+
+ zerowidthspace_before = function(head,current)
+ return insert_node_before(head,current,new_glue(0))
+ end,
+ zerowidthspace_after = function(head,current)
+ return insert_node_after(head,current,new_glue(0))
+ end,
+
+ nobreakspace_before = function(head,current)
+ local g = space_glue(current)
+ local p = new_penalty(10000)
+ head, current = insert_node_before(head,current,p)
+ return insert_node_before(head,current,g)
+ end,
+ nobreakspace_after = function(head,current)
+ local g = space_glue(current)
+ local p = new_penalty(10000)
+ head, current = insert_node_after(head,current,g)
+ return insert_node_after(head,current,p)
+ end,
+
+ }
+
+end
+
+-- end of helpers
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.mkiv
index 8f28f505d14..f2d1da62741 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrp-ini.mkiv
@@ -17,10 +17,11 @@
\registerctxluafile{scrp-cjk}{}
\registerctxluafile{scrp-eth}{}
\registerctxluafile{scrp-tha}{}
+\registerctxluafile{scrp-tib}{}
-\definesystemattribute[scriptinjection][public]
-\definesystemattribute[scriptsplitting][public]
-\definesystemattribute[scriptstatus] [public]
+\definesystemattribute[scriptinjection][public,pickup]
+\definesystemattribute[scriptsplitting][public,pickup]
+\definesystemattribute[scriptstatus] [public,pickup]
%D Since scripts need specific \LUA\ code we use hard coded attribute
%D values, but we might have more tricks at some time, so we use a
@@ -43,10 +44,23 @@
\unexpanded\def\scripts_basics_set
{\clf_setscript{\currentscript}{\scriptparameter\c!method}{\scriptparameter\c!preset}}
-\unexpanded\def\setscript[#1]%
+% \unexpanded\def\setscript[#1]%
+% {\edef\currentscript{#1}%
+% \scripts_basics_set}
+
+\unexpanded\def\setglobalscript[#1]%
+ {\edef\currentscript{#1}%
+ \scripts_basics_set
+ \pickupscriptinjectionattribute
+ \pickupscriptsplittingattribute
+ \pickupscriptstatusattribute}
+
+\unexpanded\def\setlocalscript[#1]%
{\edef\currentscript{#1}%
\scripts_basics_set}
+\let\setscript\setlocalscript
+
\unexpanded\def\resetscript
{\clf_resetscript}
@@ -73,6 +87,7 @@
\definescript [nihongo] [\c!method=nihongo]
\definescript [ethiopic] [\c!method=ethiopic]
\definescript [thai] [\c!method=thai]
+\definescript [tibetan] [\c!method=tibetan]
\definescript [latin] [\c!method=] % resets the attribute (also currentscript)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/scrp-tib.lua b/Master/texmf-dist/tex/context/base/mkiv/scrp-tib.lua
new file mode 100644
index 00000000000..b67f6964800
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/scrp-tib.lua
@@ -0,0 +1,81 @@
+if not modules then modules = { } end modules ['scrp-tib'] = {
+ version = 1.001,
+ comment = "companion to scrp-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local nuts = nodes.nuts
+
+local getnext = nuts.getnext
+local getattr = nuts.getattr
+local ischar = nuts.ischar
+
+local a_scriptstatus = attributes.private('scriptstatus')
+
+local numbertocategory = scripts.numbertocategory
+local inserters = scripts.inserters
+
+local injectors = {
+ breaking_tsheg = inserters.space_after,
+}
+
+-- more efficient is to check directly
+--
+-- local b_tsheg = 0x0F0B -- breaking
+-- local n_tsheg = 0x0F0C -- nonbreaking
+--
+-- if char == b_tsheg then
+-- head, current = insert_space_after(head,current)
+-- end
+--
+-- but this is more general
+
+local function process(head,first,last)
+ if first ~= last then
+ local current = first
+ while current do
+ local char, id = ischar(current)
+ if char then
+ local scriptstatus = getattr(current,a_scriptstatus)
+ if scriptstatus and scriptstatus > 0 then
+ local category = numbertocategory[scriptstatus]
+ if category then
+ local injector = injectors[category]
+ if injector then
+ head, current = injector(head,current)
+ end
+ end
+ end
+ end
+ if current == last then
+ break
+ else
+ current = getnext(current)
+ end
+ end
+ end
+end
+
+scripts.installmethod {
+ name = "tibetan",
+ injector = process,
+ datasets = {
+ default = {
+ inter_character_space_factor = 1,
+ inter_character_stretch_factor = 1,
+ inter_character_shrink_factor = 1,
+ },
+ half = {
+ inter_character_space_factor = 0.5,
+ inter_character_stretch_factor = 0.5,
+ inter_character_shrink_factor = 0.5,
+ },
+ quarter = {
+ inter_character_space_factor = 0.25,
+ inter_character_stretch_factor = 0.25,
+ inter_character_shrink_factor = 0.25,
+ },
+ },
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua
index f90b70be5c9..0916337b197 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua
@@ -401,8 +401,10 @@ local function basic(a,b) -- trace ea and eb
-- hashed (shared) entries
return 0
end
- local ea, eb = a.split, b.split
- local na, nb = #ea, #eb
+ local ea = a.split
+ local eb = b.split
+ local na = #ea
+ local nb = #eb
if na == 0 and nb == 0 then
-- simple variant (single word)
local result = 0
@@ -414,7 +416,8 @@ local function basic(a,b) -- trace ea and eb
end
end
if result == 0 then
- local la, lb = #ea.uc, #eb.uc
+ local la = #ea.uc
+ local lb = #eb.uc
if la > lb then
return 1
elseif lb > la then
@@ -429,7 +432,8 @@ local function basic(a,b) -- trace ea and eb
-- complex variant, used in register (multiple words)
local result = 0
for i=1,nb < na and nb or na do
- local eai, ebi = ea[i], eb[i]
+ local eai = ea[i]
+ local ebi = eb[i]
for j=1,#sequence do
local m = sequence[j]
result = basicsort(eai[m],ebi[m])
@@ -438,7 +442,8 @@ local function basic(a,b) -- trace ea and eb
end
end
if result == 0 then
- local la, lb = #eai.uc, #ebi.uc
+ local la = #eai.uc
+ local lb = #ebi.uc
if la > lb then
return 1
elseif lb > la then
@@ -586,8 +591,18 @@ function splitters.utf(str,checked) -- we could append m and u but this is clean
-- end
-- end
end
- local m_case, z_case, p_case, m_mapping, z_mapping, p_mapping, char, byte, n = { }, { }, { }, { }, { }, { }, { }, { }, 0
- local nm, nz, np = 0, 0, 0
+ local m_case = { }
+ local z_case = { }
+ local p_case = { }
+ local m_mapping = { }
+ local z_mapping = { }
+ local p_mapping = { }
+ local char = { }
+ local byte = { }
+ local n = 0
+ local nm = 0
+ local nz = 0
+ local np = 0
for sc in utfcharacters(str) do
local b = utfbyte(sc)
if b >= digitsoffset then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/sort-lan.lua b/Master/texmf-dist/tex/context/base/mkiv/sort-lan.lua
index 1aa173d1b20..b277989664b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/sort-lan.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/sort-lan.lua
@@ -71,16 +71,22 @@ definitions['fr'] = { parent = 'default' }
-- DIN 5007-1
-definitions['DIN 5007-1'] = { parent = 'default' }
+definitions['DIN 5007-1'] = {
+ parent = 'default',
+ replacements = {
+ { "ß", "ss" },
+ },
+}
-- DIN 5007-2
definitions['DIN 5007-2'] = {
parent = 'default',
replacements = {
- { "ä", 'ae' }, { "Ä", 'Ae' },
- { "ö", 'oe' }, { "Ö", 'Oe' },
- { "ü", 'ue' }, { "Ü", 'Ue' },
+ { "ä", "ae" }, { "Ä", "Ae" },
+ { "ö", "oe" }, { "Ö", "Oe" },
+ { "ü", "ue" }, { "Ü", "Ue" },
+ { "ß", "ss" },
},
}
@@ -88,7 +94,9 @@ definitions['DIN 5007-2'] = {
definitions['Duden'] = {
parent = 'default',
- replacements = { { "ß", 's' } },
+ replacements = {
+ { "ß", "s" },
+ },
}
-- definitions['de'] = { parent = 'default' } -- new german
@@ -126,7 +134,7 @@ definitions['de-AT'] = {
},
}
--- finish (by Wolfgang Schuster)
+-- finnish (by Wolfgang Schuster)
definitions['fi'] = {
entries = {
@@ -897,22 +905,24 @@ definitions["hu"] = {
},
}
---- Estonian
+-- Estonian
definitions["et"] = {
- entries = { -- w x y are used for foreign words only
- ["a"] = "a", ["b"] = "b", ["d"] = "d", ["e"] = "e", ["f"] = "f",
- ["g"] = "g", ["h"] = "h", ["i"] = "i", ["j"] = "j", ["k"] = "k",
- ["l"] = "l", ["m"] = "m", ["n"] = "n", ["o"] = "o", ["p"] = "p",
- ["r"] = "r", ["s"] = "s", ["š"] = "š", ["z"] = "z", ["ž"] = "ž",
- ["t"] = "t", ["u"] = "u", ["v"] = "v", ["w"] = "v", ["õ"] = "õ",
- ["ä"] = "ä", ["ö"] = "ö", ["ü"] = "ü", ["x"] = "x", ["y"] = "y",
+ entries = { -- f š z ž are used in estonian words of foreign origin, c č q w x y are used for foreign words only
+ ["a"] = "a", ["b"] = "b", ["c"] = "c", ["č"] = "č", ["d"] = "d",
+ ["e"] = "e", ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i",
+ ["j"] = "j", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n",
+ ["o"] = "o", ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s",
+ ["š"] = "š", ["z"] = "z", ["ž"] = "ž", ["t"] = "t", ["u"] = "u",
+ ["v"] = "v", ["w"] = "w", ["õ"] = "õ", ["ä"] = "ä", ["ö"] = "ö",
+ ["ü"] = "ü", ["x"] = "x", ["y"] = "y",
},
orders = {
- "a", "b", "d", "e", "f", "g", "h", "i", "j", "k",
- "l", "m", "n", "o", "p", "r", "s", "š", "z", "ž",
- "t", "u", "v", "w", "õ", "ä", "ö", "ü", "x", "y",
- }
+ "a", "b", "c", "č", "d", "e", "f", "g", "h", "i",
+ "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
+ "š", "z", "ž", "t", "u", "v", "w", "õ", "ä", "ö",
+ "ü", "x", "y",
+ },
}
--- Korean
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-adj.lua b/Master/texmf-dist/tex/context/base/mkiv/spac-adj.lua
deleted file mode 100644
index 3db59881b20..00000000000
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-adj.lua
+++ /dev/null
@@ -1,67 +0,0 @@
-if not modules then modules = { } end modules ['spac-adj'] = {
- version = 1.001,
- comment = "companion to spac-adj.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- sort of obsolete code
-
-local a_vadjust = attributes.private('graphicvadjust')
-
-local nodecodes = nodes.nodecodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-
-local remove_node = nodes.remove
-local hpack_node = node.hpack
-
-local enableaction = nodes.tasks.enableaction
-
-function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only
- if groupcode == "" then -- mvl only
- local h, p, done = head, nil, false
- while h do
- local id = h.id
- if id == hlist_code or id == vlist_code then
- local a = h[a_vadjust]
- if a then
- if p then
- local n
- head, h, n = remove_node(head,h)
- local pl = p.list
- if n.width ~= 0 then
- n = hpack_node(n,0,'exactly') -- todo: dir
- end
- if pl then
- pl.prev = n
- n.next = pl
- end
- p.list = n
- done = true
- else
- -- can't happen
- end
- else
- p = h
- h = h.next
- end
- else
- h = h.next
- end
- end
- return head, done
- else
- return head, false
- end
-end
-
-interfaces.implement {
- name = "enablegraphicvadjust",
- onlyonce = true,
- actions = function()
- enableaction("finalizers","nodes.handlers.graphicvadjust")
- end
-}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-adj.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-adj.mkiv
deleted file mode 100644
index d29d15c17cb..00000000000
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-adj.mkiv
+++ /dev/null
@@ -1,51 +0,0 @@
-%D \module
-%D [ file=spac-adj, % moved from spac-par.mkiv
-%D version=2009.10.16, % 1997.03.31, was core-spa.tex
-%D title=\CONTEXT\ Spacing Macros,
-%D subtitle=Paragraphs,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-\writestatus{loading}{ConTeXt Spacing Macros / Adjustments}
-
-\unprotect
-
-% Very nasty but needed for margin stuff inside colored
-% paragraphs. Obsolete for while .
-
-\registerctxluafile{spac-adj}{}
-
-\definesystemattribute [graphicvadjust] [public]
-
-\unexpanded\def\enablegraphicvadjust
- {\writestatus\m!system{graphicvadjusting is no longer needed!}
- \clf_enablegraphicvadjust %once anyway
- \glet\enablegraphicvadjust\relax}
-
-\unexpanded\def\graphicvadjust % currently not enabled ... nasty bidi handling
- {\clf_enablegraphicvadjust % and probably no longer needed anyway
- \dowithnextboxcontentcs\forgetall\spac_vadjust_graphic_finish\vbox}
-
-\def\spac_vadjust_graphic_finish
- {\vadjust
- {\vbox attr \graphicvadjustattribute \plusone
- {\unvbox\nextbox
- % corrects for one line paragraphs
- \nointerlineskip
- \kern-\struttotal
- \nointerlineskip
- \verticalstrut}}}
-
-\unexpanded\def\fakedvadjust
- {\dowithnextboxcs\spac_vadjust_faked_finish\vtop}
-
-\def\spac_vadjust_faked_finish
- {\setbox\nextbox\hpack{\llap{\lower\strutdepth\box\nextbox}}%
- \smashedbox\nextbox}
-
-\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua b/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua
index 640478d3499..b58040ac72a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua
@@ -38,7 +38,8 @@ local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-local line_code = listcodes.line
+
+local linelist_code = listcodes.line
local new_stretch = nodepool.stretch
@@ -63,13 +64,12 @@ local nofrealigned = 0
-- raggedright 0 0 fil
-- raggedcenter 0 + 0 + -
-local function handler(head,leftpage,realpageno)
+local function handler(head,leftpage,realpageno) -- traverse_list
local current = head
- local done = false
while current do
local id = getid(current)
if id == hlist_code then
- if getsubtype(current) == line_code then
+ if getsubtype(current) == linelist_code then
local a = takeattr(current,a_realign)
if not a or a == 0 then
-- skip
@@ -102,7 +102,6 @@ local function handler(head,leftpage,realpageno)
elseif trace_realign then
report_realign("invalid flushing, align %a, page %a, realpage %a",align,pageno,realpageno)
end
- done = true
nofrealigned = nofrealigned + 1
end
end
@@ -113,14 +112,11 @@ local function handler(head,leftpage,realpageno)
end
current = getnext(current)
end
- return head, done
+ return head
end
function alignments.handler(head)
- local leftpage = isleftpage()
- local realpageno = texgetcount("realpageno")
- local head, done = handler(tonut(head),leftpage,realpageno)
- return tonode(head), done
+ return handler(head,isleftpage(),texgetcount("realpageno"))
end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-ali.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-ali.mkiv
index fbcf45caa2e..4362ff25002 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-ali.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-ali.mkiv
@@ -27,7 +27,7 @@
%
% but that also means myoption gets frozen due to caching.
-\registerctxluafile{spac-ali}{}
+\registerctxluafile{spac-ali}{optimize}
\definesystemattribute[realign] [public] % might be combined with the next one
\definesystemattribute[alignstate][public] % will make a single attributes for several states
@@ -61,16 +61,6 @@
\newtoks\everyresetalign % todo
-%D We will not use bodydir and pagedir so we disable them. That way we get
-%D normal hyperlink support. We back on it (too hard to fake \type {\the}).
-
-\unexpanded\def\syst_fatal_dir_error#1%
- {\writestatus{fatal error}{\string#1\space is forbidden}%
- \wait}
-
-\def\pagedir {\syst_fatal_dir_error\pagedir} \let\normalpagedir\pagedir
-\def\bodydir {\syst_fatal_dir_error\bodydir} \let\normalbodydir\bodydir
-
% This will become a more advanced layout controller soon:
\newconditional\layoutlefttoright \settrue\layoutlefttoright
@@ -94,63 +84,23 @@
\unexpanded\def\spac_directions_lefttoright_vmode
{\settrue\displaylefttoright
\settrue\inlinelefttoright
- \textdir TLT\relax
- \pardir TLT\relax}
+ \textdirection\directionlefttoright
+ \pardirection \directionlefttoright}
\unexpanded\def\spac_directions_righttoleft_vmode
{\setfalse\displaylefttoright
\setfalse\inlinelefttoright
- \textdir TRT\relax
- \pardir TRT\relax}
-
-% % keep this as reference
-%
-% \unexpanded\def\spac_directions_lefttoright_hmode
-% {\textdir TLT\relax
-% \settrue\inlinelefttoright}
-%
-% \unexpanded\def\spac_directions_righttoleft_hmode
-% {\textdir TRT\relax
-% \setfalse\inlinelefttoright}
-%
-% \unexpanded\def\spac_directions_lefttoright_hmode
-% {\ifzeropt\lastskip
-% \textdir TLT\relax
-% \else
-% \scratchskip\lastskip
-% \unskip
-% \textdir TLT\relax
-% \hskip\scratchskip
-% \fi
-% \settrue\inlinelefttoright}
-%
-% \unexpanded\def\spac_directions_righttoleft_hmode
-% {\ifzeropt\lastskip
-% \textdir TRT\relax
-% \else
-% \scratchskip\lastskip
-% \unskip
-% \textdir TRT\relax
-% \hskip\scratchskip
-% \fi
-% \setfalse\inlinelefttoright}
+ \textdirection\directionrighttoleft
+ \pardirection \directionrighttoleft}
\unexpanded\def\spac_directions_lefttoright_hmode
- {\linedir TLT\relax % linedir keeps subtype of skip
+ {\linedirection\directionlefttoright % linedir keeps subtype of skip
\settrue\inlinelefttoright}
\unexpanded\def\spac_directions_righttoleft_hmode
- {\linedir TRT\relax % linedir keeps subtype of skip
+ {\linedirection\directionrighttoleft % linedir keeps subtype of skip
\setfalse\inlinelefttoright}
-% \def\currentdirectionparameters
-% {\ifconditional\inlinelefttoright \else
-% idir {r2l}%
-% \fi
-% \ifconditional\displaylefttoright \else
-% ddir {r2l}%
-% \fi}
-
\unexpanded\def\synchronizelayoutdirection
{\ifconditional\layoutlefttoright
\spac_directions_synchronize_lr
@@ -167,16 +117,17 @@
\def\spac_directions_synchronize_lr
{\settrue\inlinelefttoright
- \textdir TLT\relax
- \pardir TLT\relax}
+ \textdirection\directionlefttoright
+ \pardirection \directionlefttoright}
\def\spac_directions_synchronize_rl
{\setfalse\inlinelefttoright
- \textdir TRT\relax
- \pardir TRT\relax}
+ \textdirection\directionrighttoleft
+ \pardirection \directionrighttoleft}
\unexpanded\def\synchronizeinlinedirection
- {\textdir T\ifconditional\inlinelefttoright L\else R\fi T\relax}
+ {% why not \linedirection here
+ \textdirection\ifconditional\inlinelefttoright\directionlefttoright\else\directionrighttoleft\fi}
\unexpanded\def\checkedlefttoright
{\ifvmode
@@ -210,49 +161,20 @@
\unexpanded\def\usebidiparameter#1%
{\begincsname\??bidi#1\c!bidi\endcsname}
-% maybe some day:
-%
-% \newcount\postdirpenalty % \zerocount
-% \newcount\predirpenalty % \zerocount
-%
-% \def\spac_directions_post_break
-% {\ifhmode
-% \removeunwantedspaces
-% \penalty\postdirpenalty
-% \fi}
-%
-% \def\spac_directions_pre_break
-% {\ifhmode
-% \penalty\predirpenalty
-% \ignorespaces
-% \fi}
-%
-% \unexpanded\def\spac_directions_lefttoright_hmode
-% {\settrue\inlinelefttoright
-% \textdir TLT\relax
-% \aftergroup\spac_directions_post_break
-% \spac_directions_pre_break}
-%
-% \unexpanded\def\spac_directions_righttoleft_hmode
-% {\textdir TRT\relax
-% \setfalse\inlinelefttoright
-% \aftergroup\spac_directions_post_break
-% \spac_directions_pre_break}
-
\unexpanded\def\showdirections
{\dontleavehmode
- \begingroup\infofont\textdir TLT[\space
- layout:\ifconditional \layoutlefttoright l2r\else r2l\fi\space
- display:\ifconditional\displaylefttoright l2r\else r2l\fi\space
- inline:\ifconditional \inlinelefttoright l2r\else r2l\fi\space
+ \begingroup\infofont\textdirection\directionlefttoright[\space
+ layout: \ifconditional\layoutlefttoright l2r\else r2l\fi\space
+ display: \ifconditional\displaylefttoright l2r\else r2l\fi\space
+ inline: \ifconditional\inlinelefttoright l2r\else r2l\fi\space
]\endgroup}
-\unexpanded\def\righttolefthbox#1#{\normalhbox dir TRT #1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox
-\unexpanded\def\lefttorighthbox#1#{\normalhbox dir TLT #1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox
-\unexpanded\def\righttoleftvbox#1#{\normalvbox dir TRT #1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox
-\unexpanded\def\lefttorightvbox#1#{\normalvbox dir TLT #1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox
-\unexpanded\def\righttoleftvtop#1#{\normalvtop dir TRT #1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop
-\unexpanded\def\lefttorightvtop#1#{\normalvtop dir TLT #1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop
+\unexpanded\def\righttolefthbox#1#{\reversehbox#1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox
+\unexpanded\def\lefttorighthbox#1#{\naturalhbox#1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox
+\unexpanded\def\righttoleftvbox#1#{\reversevbox#1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox
+\unexpanded\def\lefttorightvbox#1#{\naturalvbox#1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox
+\unexpanded\def\righttoleftvtop#1#{\reversevtop#1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop
+\unexpanded\def\lefttorightvtop#1#{\naturalvtop#1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop
\unexpanded\def\autodirhbox#1#{\hbox#1\bgroup\synchronizeinlinedirection\let\next}
\unexpanded\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox
@@ -355,7 +277,8 @@
\newconstant\c_spac_align_state_par_fill
\def\v_spac_align_fill_amount {\plusone fil}
-\def\v_spac_align_fill_amount_hard {\plusone fill}
+\def\v_spac_align_fill_amount_hard {\plusone fill}
+\def\v_spac_align_fill_amount_extreme {\plustenthousand filll}
\def\v_spac_align_fill_amount_negative {\minusone fil}
\def\v_spac_align_fill_amount_double {\plustwo fil}
\def\v_spac_align_fill_amount_space {\plustwo fil} % can be added to xspace if we have a key
@@ -479,7 +402,8 @@
\spaceskip \zeropoint\relax
\xspaceskip \zeropoint\relax
\parfillskip \zeropoint
- \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_hard\relax
+ \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
+ \parfillleftmode\plustwo % \plusone checks for multiple lines
\parindent \zeropoint
\relax}
@@ -643,8 +567,8 @@
}}% kept, nice for tracing
\edef\raggedcommand {\the\t_spac_align_collected }%
\edef\updateraggedskips{\spac_align_flush_horizontal}%
- \global\expandafter\let\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand
- \global\expandafter\let\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips}
+ \expandafter\glet\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand
+ \expandafter\glet\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips}
\def\spac_align_collect#1%
{\csname\??aligncommand#1\endcsname}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-chr.lua b/Master/texmf-dist/tex/context/base/mkiv/spac-chr.lua
index 0fa639f9295..23cf9741b14 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-chr.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-chr.lua
@@ -27,9 +27,6 @@ local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local getnext = nuts.getnext
local getprev = nuts.getprev
local getattr = nuts.getattr
@@ -38,7 +35,6 @@ local getlang = nuts.getlang
local setchar = nuts.setchar
local setattrlist = nuts.setattrlist
local getfont = nuts.getfont
-local getchar = nuts.getchar
local setsubtype = nuts.setsubtype
local setdisc = nuts.setdisc
local isglyph = nuts.isglyph
@@ -48,13 +44,13 @@ local setcolor = nodes.tracers.colors.set
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+local nextglyph = nuts.traversers.glyph
local copy_node = nuts.copy
-local tasks = nodes.tasks
-
local nodepool = nuts.pool
local new_penalty = nodepool.penalty
local new_glue = nodepool.glue
@@ -63,12 +59,10 @@ local new_rule = nodepool.rule
local new_disc = nodepool.disc
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
-local disccodes = nodes.disccodes
+local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
-local space_skip_code = skipcodes.spaceskip
-local explicit_code = disccodes.explicit
+local spaceskip_code = gluecodes.spaceskip
local chardata = characters.data
local is_punctuation = characters.is_punctuation
@@ -101,8 +95,7 @@ local function inject_quad_space(unicode,head,current,fraction)
setattrlist(glue,current)
setattrlist(current) -- why reset all
setattr(glue,a_character,unicode)
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function inject_char_space(unicode,head,current,parent)
@@ -112,8 +105,7 @@ local function inject_char_space(unicode,head,current,parent)
setattrlist(glue,current)
setattrlist(current) -- why reset all
setattr(glue,a_character,unicode)
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink)
@@ -132,18 +124,17 @@ local function inject_nobreak_space(unicode,head,current,space,spacestretch,spac
head, current = insert_node_after(head,current,kern)
head, current = insert_node_after(head,current,penalty)
end
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function nbsp(head,current)
local para = fontparameters[getfont(current)]
if getattr(current,a_alignstate) == 1 then -- flushright
head, current = inject_nobreak_space(0x00A0,head,current,para.space,0,0)
- setsubtype(current,space_skip_code)
+ setsubtype(current,spaceskip_code)
else
head, current = inject_nobreak_space(0x00A0,head,current,para.space,para.spacestretch,para.spaceshrink)
- setsubtype(current,space_skip_code)
+ setsubtype(current,spaceskip_code)
end
return head, current
end
@@ -152,27 +143,13 @@ end
function characters.replacenbsp(head,original)
local head, current = nbsp(head,original)
- head = remove_node(head,original,true)
- return head, current
+ return remove_node(head,original,true)
end
--- function characters.replacenbspaces(head)
--- for current in traverse_id(glyph_code,head) do
--- if getchar(current) == 0x00A0 then
--- local h = nbsp(head,current)
--- if h then
--- head = remove_node(h,current,true)
--- end
--- end
--- end
--- return head
--- end
-
function characters.replacenbspaces(head)
- local head = tonut(head)
local wipe = false
- for current in traverse_id(glyph_code,head) do -- can be anytiem so no traverse_char
- if getchar(current) == 0x00A0 then
+ for current, char, font in nextglyph, head do -- can be anytime so no traverse_char
+ if char == 0x00A0 then
if wipe then
head = remove_node(h,current,true)
wipe = false
@@ -184,15 +161,16 @@ function characters.replacenbspaces(head)
end
end
if wipe then
- head = remove_node(h,current,true)
+ head = remove_node(head,current,true)
end
- return tonode(head)
+ return head
end
-- This initialization might move someplace else if we need more of it. The problem is that
-- this module depends on fonts so we have an order problem.
local nbsphash = { } setmetatableindex(nbsphash,function(t,k)
+ -- this needs checking !
for i=unicodeblocks.devanagari.first,unicodeblocks.devanagari.last do nbsphash[i] = true end
for i=unicodeblocks.kannada .first,unicodeblocks.kannada .last do nbsphash[i] = true end
setmetatableindex(nbsphash,nil)
@@ -209,11 +187,11 @@ local methods = {
[0x001F] = function(head,current) -- kind of special
local next = getnext(current)
if next then
- local char = isglyph(next)
+ local char, font = isglyph(next)
if char then
head, current = remove_node(head,current,true)
if not is_punctuation[char] then
- local p = fontparameters[getfont(next)]
+ local p = fontparameters[font]
head, current = insert_node_before(head,current,new_glue(p.space,p.space_stretch,p.space_shrink))
end
end
@@ -319,9 +297,7 @@ local methods = {
characters.methods = methods
-- function characters.handler(head) -- todo: use traverse_id
--- head = tonut(head)
-- local current = head
--- local done = false
-- while current do
-- local char, id = isglyph(current)
-- if char then
@@ -335,47 +311,39 @@ characters.methods = methods
-- if h then
-- head = remove_node(h,current,true)
-- end
--- done = true
-- end
-- current = next
-- else
-- current = getnext(current)
-- end
-- end
--- return tonode(head), done
+-- return head
-- end
--- for current, char, font in traverse_char_data(head) will save 0.015 on a 300 page doc
-
-- this also works ok in math as we run over glyphs and these stay glyphs ... not sure
-- about scripts and such but that is not important anyway ... some day we can consider
-- special definitions in math
function characters.handler(head)
- local head = tonut(head)
local wipe = false
- for current in traverse_char(head) do
- local char = getchar(current)
- if char then
- local method = methods[char]
- if method then
- if wipe then
- head = remove_node(head,wipe,true)
- wipe = false
- end
- if trace_characters then
- report_characters("replacing character %C, description %a",char,lower(chardata[char].description))
- end
- local h = method(head,current)
- if h then
- wipe = current
- end
- done = true
+ for current, char in nextchar, head do
+ local method = methods[char]
+ if method then
+ if wipe then
+ head = remove_node(head,wipe,true)
+ wipe = false
+ end
+ if trace_characters then
+ report_characters("replacing character %C, description %a",char,lower(chardata[char].description))
+ end
+ local h = method(head,current)
+ if h then
+ wipe = current
end
end
end
if wipe then
head = remove_node(head,wipe,true)
end
- return tonode(head), done
+ return head
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-chr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-chr.mkiv
index ed2cb47f982..23f4ac8dd64 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-chr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-chr.mkiv
@@ -15,7 +15,7 @@
\unprotect
-\registerctxluafile{spac-chr}{}
+\registerctxluafile{spac-chr}{optimize}
\definesystemattribute[characters][public]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-flr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-flr.mkiv
index 29351a3dd46..bd50bfea68b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-flr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-flr.mkiv
@@ -60,6 +60,35 @@
\endgroup
\ignorespaces}
+% \definefiller
+% [MyFiller]
+% [offset=.25\emwidth,
+% rightmargindistance=-\rightskip,
+% method=middle]
+%
+% \startitemize[packed,joinedup][rightmargin=5em]
+% \startitem
+% \input sapolsky \fillupto[MyFiller]{RS}
+% \stopitem
+% \stopitemize
+
+\unexpanded\def\fillupto
+ {\dosingleempty\spac_fillers_upto}
+
+\def\spac_fillers_upto[#1]#2%
+ {\removeunwantedspaces
+ \begingroup
+ \edef\currentfiller{#1}%
+ \scratchdimen\dimexpr\fillerparameter\c!rightmargindistance\relax
+ \ifdim\scratchdimen=\zeropoint\else
+ \parfillskip \scratchdimen\s!plus \plusone\s!fil\relax
+ \fi
+ \spac_fillers_indeed[#1]%
+ \doifsomething{#2}{\hbox{#2}}%
+ \par
+ \endgroup
+ \ignorespaces}
+
\setvalue{\??filleralternative\s!unknown}%
{}
@@ -87,8 +116,8 @@
\setvalue{\??filleralternative\v!rule}%
{\expandnamespaceparameter\??fillerleadermethod\fillerparameter\c!method\v!local
\hrule
- \!!height\fillerparameter\c!height
- \!!depth \fillerparameter\c!depth
+ \s!height\fillerparameter\c!height
+ \s!depth \fillerparameter\c!depth
\hfill}
\letvalue{\??fillerleadermethod\s!local }\normalleaders % overflow ends up inbetween (current box)
@@ -106,6 +135,7 @@
\c!depth=\zeropoint,
\c!leftmargin=\zeropoint,
\c!rightmargin=\zeropoint,
+ \c!rightmargindistance=\zeropoint,
\c!alternative=\v!symbol,
\c!method=\s!local]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-grd.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-grd.mkiv
index 73c6e0dd151..72d017836f6 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-grd.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-grd.mkiv
@@ -108,8 +108,8 @@
\newbox \b_spac_lines_correction_after
\def\spac_lines_initialize_corrections
- {\setbox\b_spac_lines_correction_before\hbox{\setstrut\strut}%
- \setbox\b_spac_lines_correction_after \hbox{(}%
+ {\setbox\b_spac_lines_correction_before\hpack{\setstrut\strut}%
+ \setbox\b_spac_lines_correction_after \hbox {(}%
\d_spac_lines_correction_before\dimexpr\ht\b_spac_lines_correction_before-\ht\b_spac_lines_correction_after\relax
\d_spac_lines_correction_after \dimexpr\dp\b_spac_lines_correction_before-\dp\b_spac_lines_correction_after\relax
\ifdim\d_spac_lines_correction_before<\zeropoint\d_spac_lines_correction_before\zeropoint\fi
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-hor.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-hor.mkiv
index ce747a2025b..32b7f06fb81 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-hor.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-hor.mkiv
@@ -17,8 +17,9 @@
\registerctxluafile{spac-hor}{}
-\let \parfillrightskip \parfillskip
-\newskip\parfillleftskip
+\let \parfillrightskip \parfillskip
+\newskip \parfillleftskip
+\newconstant\parfillleftmode
\let\v_spac_indentation_current\empty % amount/keyword
@@ -205,6 +206,9 @@
\let\checkindentation\relax
+\installmacrostack\checkindentation
+\installmacrostack\ifindentation
+
\def\spac_indentation_remove
{\ifdim\parindent=\zeropoint \else
\begingroup
@@ -218,21 +222,21 @@
\def\spac_indentation_do_toggle_indeed
{\global\indentationfalse
- \global\let\checkindentation\spac_indentation_no_toggle_indeed
+ \glet\checkindentation\spac_indentation_no_toggle_indeed
\spac_indentation_remove}
\def\spac_indentation_no_toggle_indeed
{\global\indentationtrue
- \global\let\checkindentation\spac_indentation_do_toggle_indeed}
+ \glet\checkindentation\spac_indentation_do_toggle_indeed}
\def\spac_indentation_do_indeed
{\global\indentationtrue}
\def\spac_indentation_do_toggle
- {\global\let\checkindentation\spac_indentation_do_toggle_indeed}
+ {\glet\checkindentation\spac_indentation_do_toggle_indeed}
\def\spac_indentation_no_toggle
- {\global\let\checkindentation\spac_indentation_no_toggle_indeed}
+ {\glet\checkindentation\spac_indentation_no_toggle_indeed}
\def\spac_indentation_check_toggle
{\ifcase\c_spac_indentation_toggle_state
@@ -244,22 +248,22 @@
\fi}
\def\spac_indentation_variant_yes
- {\global\let\checkindentation\spac_indentation_do_indeed}
+ {\glet\checkindentation\spac_indentation_do_indeed}
\def\spac_indentation_no_next_check
{\spac_indentation_remove
- \global\let\checkindentation\spac_indentation_do_indeed}
+ \glet\checkindentation\spac_indentation_do_indeed}
\def\spac_indentation_variant_no % made global
{\ifinpagebody \else
\global\indentationfalse
- \global\let\checkindentation\spac_indentation_no_next_check
+ \glet\checkindentation\spac_indentation_no_next_check
\fi}
\def\nonoindentation % bv bij floats
{\ifinpagebody \else
\global\indentationtrue
- \global\let\checkindentation\spac_indentation_do_indeed
+ \glet\checkindentation\spac_indentation_do_indeed
\fi}
\def\spac_indentation_variant_force
@@ -271,13 +275,13 @@
\fi \fi}
\appendtoks
- \pushmacro\checkindentation
- \pushmacro\ifindentation
+ \push_macro_checkindentation
+ \push_macro_ifindentation
\to \everypushsomestate
\appendtoks
- \popmacro\ifindentation
- \popmacro\checkindentation
+ \pop_macro_ifindentation
+ \pop_macro_checkindentation
\to \everypopsomestate
% public:
@@ -287,16 +291,16 @@
\let\doindentation\spac_indentation_variant_yes % public
\def\dontrechecknextindentation % public (in macros)
- {\global\let\dorechecknextindentation\relax}
+ {\glet\dorechecknextindentation\relax}
\let\dorechecknextindentation\relax % public (in macros)
\unexpanded\def\spac_indentation_check_next_indentation
- {\global\let\dorechecknextindentation\relax
+ {\glet\dorechecknextindentation\relax
\doifelsenextchar\par\donothing\spac_indentation_variant_no} % messy check as next is seldom \par
\def\spac_indentation_variant_auto
- {\global\let\dorechecknextindentation\spac_indentation_check_next_indentation}
+ {\glet\dorechecknextindentation\spac_indentation_check_next_indentation}
%D This one sets up the local indentation behaviour (i.e. either or not
%D a next paragraph will be indented).
@@ -564,6 +568,13 @@
\fi
\fi}
+\unexpanded\def\onlynonbreakablespace
+ {\ifdim\lastskip=\interwordspace
+ \unskip
+ \nonbreakablespace
+ \fi
+ \ignorespaces}
+
% \startbuffer
% \startlines \tt \fixedspaces
% 0~1~~2~~~3~~~~4~~~~~5
@@ -598,12 +609,15 @@
\ifdefined\quad \else
- \unexpanded\def\enskip{\hskip.5\emwidth}
- \unexpanded\def\quad {\hskip \emwidth}
- \unexpanded\def\qquad {\hskip 2\emwidth}
+ \unexpanded\def\enskip{\hskip.5\emwidth\relax}
+ \unexpanded\def\quad {\hskip \emwidth\relax}
+ \unexpanded\def\qquad {\hskip 2\emwidth\relax}
\fi
+\unexpanded\def\negenspace{\kern-.5\emwidth}
+\unexpanded\def\negemspace{\kern- \emwidth}
+
\let\emspace\quad
\unexpanded\def\charspace{ } % the unexpandable \space (as space can also be delimiter for numbers)
@@ -1116,6 +1130,8 @@
\unexpanded\def\spac_spaces_checked_normal {\mathortext\normalspace{\dontleavehmode\normalspace}}%
\unexpanded\def\spac_spaces_checked_fixed {\mathortext\normalspace{\dontleavehmode\fixedspace}}%
+% hm, order matters when we \let in \obeyspaces
+
\installspacemethod \v!on
{\obeyspaces
\let\obeyedspace\spac_spaces_checked_control
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-lin.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-lin.mkiv
index 6558cb1113f..d862f6d8109 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-lin.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-lin.mkiv
@@ -86,7 +86,7 @@
\let\spac_lines_break\relax
\fi
\linesparameter\c!before
- \pushmacro\checkindentation
+ \push_macro_checkindentation
\whitespace
\dostarttaggedchained\t!lines\currentlines\??lines
\begingroup
@@ -126,7 +126,7 @@
{\dostoptagged
\endgroup
\dostoptagged
- \popmacro\checkindentation
+ \pop_macro_checkindentation
\linesparameter\c!after
\egroup}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-pag.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-pag.mkiv
index c7d22f0e0c5..9adc591ed96 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-pag.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-pag.mkiv
@@ -151,6 +151,7 @@
\unexpanded\def\signalrightpage {\dotrackpagestate \s!paragraph\nofraggedparagraphs} % use \dontleavehmode if needed
\unexpanded\def\doifelserightpage{\doifelserightpagestate\s!paragraph\nofraggedparagraphs}
+\unexpanded\def\rightpageorder {\pagestaterealpageorder\s!paragraph\nofraggedparagraphs}
\let\doifrightpageelse\doifelserightpage
@@ -169,9 +170,9 @@
\fi
\ifpagechanged
\letgvalue{\??pagechanges#2:#1}\m_spac_pagestates_realpage
- \globallet\lastchangedpage\m_spac_pagestates_realpage
+ \glet\lastchangedpage\m_spac_pagestates_realpage
\else
- \globallet\lastchangedpage\realfolio
+ \glet\lastchangedpage\realfolio
\fi}
\def\changedpagestate#1#2%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-par.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-par.mkiv
index 4dd3db24338..0932b735989 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-par.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-par.mkiv
@@ -79,17 +79,17 @@
\setvalue{\??paragraphintro\v!first}#1%
{\global\settrue\c_spac_paragraphs_intro_first
- \global\t_spac_paragraphs_intro_first\expandafter{\the\t_spac_paragraphs_intro_first#1}%
+ \gtoksapp\t_spac_paragraphs_intro_first{#1}%
\glet\insertparagraphintro\spac_paragraphs_flush_intro}
\setvalue{\??paragraphintro\v!next}#1%
{\global\settrue\c_spac_paragraphs_intro_next
- \global\t_spac_paragraphs_intro_next\expandafter{\the\t_spac_paragraphs_intro_next#1}%
+ \gtoksapp\t_spac_paragraphs_intro_next{#1}%
\glet\insertparagraphintro\spac_paragraphs_flush_intro}
\setvalue{\??paragraphintro\v!each}#1%
{\global\settrue\c_spac_paragraphs_intro_each
- \global\t_spac_paragraphs_intro_each\expandafter{\the\t_spac_paragraphs_intro_each#1}%
+ \gtoksapp\t_spac_paragraphs_intro_each{#1}%
\glet\insertparagraphintro\spac_paragraphs_flush_intro}
%D We can say:
@@ -130,7 +130,7 @@
\unexpanded\def\flushatparagraph#1%
{\global\c_spac_paragraphs_intro_first\plusone
- \global\t_spac_paragraphs_intro_first\expandafter{\the\t_spac_paragraphs_intro_first#1}%
+ \gtoksapp\t_spac_paragraphs_intro_first{#1}%
\glet\insertparagraphintro\spac_paragraphs_flush_intro}
%D Here comes the flusher (we misuse the one level expansion of token
@@ -221,19 +221,19 @@
\dowithnextboxcs\spac_postponed_data_finish\hbox}
\def\spac_postponed_data_finish
- {\global\setbox\b_spac_postponed_data\hbox % to\zeropoint
+ {\global\setbox\b_spac_postponed_data\hpack % to\zeropoint
{\box\b_spac_postponed_data\box\nextbox}%
\endgroup}
\def\spac_postponed_data_flush
{%\iftrialtypesetting \else
\ifvoid\b_spac_postponed_data\else
- \hbox{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data
+ \hpack{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data
\fi
\glet\flushpostponednodedata\relax
}%\fi}
-\unexpanded\def\doflushatpar
+\unexpanded\def\doflushatpar % might be renamed
{\ifvmode
\expandafter\flushatnextpar
\else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua b/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua
index a28f305932c..32582c56fc5 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua
@@ -17,6 +17,7 @@ local formatters = string.formatters
local nodecodes = nodes.nodecodes
local gluecodes = nodes.gluecodes
local listcodes = nodes.listcodes
+local leadercodes = nodes.leadercodes
local glyph_code = nodecodes.glyph
local disc_code = nodecodes.disc
@@ -30,10 +31,12 @@ local math_code = nodecodes.math
local rule_code = nodecodes.rule
local marginkern_code = nodecodes.marginkern
-local leaders_code = gluecodes.leaders
+local leaders_code = leadercodes.leaders
+
local lineskip_code = gluecodes.lineskip
local baselineskip_code = gluecodes.baselineskip
-local line_code = listcodes.line
+
+local linelist_code = listcodes.line
local texlists = tex.lists
local settexattribute = tex.setattribute
@@ -128,6 +131,9 @@ local function getprofile(line,step)
local margin = step / 4
local min = 0
local max = ceiling(getwidth(line)/step) + 1
+ local wd = 0
+ local ht = 0
+ local dp = 0
for i=min,max do
heights[i] = 0
@@ -136,8 +142,6 @@ local function getprofile(line,step)
-- remember p
- local wd, ht, dp = 0, 0, 0
-
local function progress()
position = width
width = position + wd
@@ -639,7 +643,7 @@ end
local function profilelist(line,mvl)
- local current = tonut(line)
+ local current = line
local top = nil
local bot = nil
@@ -668,7 +672,7 @@ local function profilelist(line,mvl)
local id = getid(current)
if id == hlist_code then
local subtype = getsubtype(current)
- if subtype == line_code then
+ if subtype == linelist_code then
t_profile = hasprofile(current)
if t_profile then
top = current
@@ -710,7 +714,7 @@ local function profilelist(line,mvl)
if id == hlist_code then -- check subtype
local subtype = getsubtype(current)
- if subtype == line_code then
+ if subtype == linelist_code then
if top == current then
-- skip
bot = nil -- to be sure
@@ -819,7 +823,7 @@ function profiling.profilebox(specification)
local id = getid(current)
if id == hlist_code then
local subtype = getsubtype(current)
- if subtype == line_code then
+ if subtype == linelist_code then
if top then
bot = current
b_profile = setprofile(bot)
@@ -899,9 +903,8 @@ end
--
-- function profiling.vboxhandler(head,where)
-- if head and not ignore[where] then
--- local h = tonut(head)
--- if getnext(h) then
--- profilelist(h)
+-- if getnext(head) then
+-- profilelist(head)
-- end
-- end
-- return head
@@ -911,7 +914,7 @@ function profiling.pagehandler(head)
if head then
profilelist(head,true)
end
- return head, true
+ return head
end
interfaces.implement {
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-ver.lua b/Master/texmf-dist/tex/context/base/mkiv/spac-ver.lua
index 969a195e1fe..b55f1ca7cae 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-ver.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-ver.lua
@@ -116,8 +116,8 @@ local a_snapmethod = attributes.private('snapmethod')
local a_snapvbox = attributes.private('snapvbox')
local nuts = nodes.nuts
-local tonode = nuts.tonode
local tonut = nuts.tonut
+local tonode = nuts.tonode
local getnext = nuts.getnext
local setlink = nuts.setlink
@@ -147,15 +147,16 @@ local getdepth = nuts.getdepth
local find_node_tail = nuts.tail
local flush_node = nuts.flush_node
-local traverse_nodes = nuts.traverse
-local traverse_nodes_id = nuts.traverse_id
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local remove_node = nuts.remove
local count_nodes = nuts.countall
local hpack_node = nuts.hpack
local vpack_node = nuts.vpack
------ writable_spec = nuts.writable_spec
+
+local nextnode = nuts.traversers.node
+local nexthlist = nuts.traversers.hlist
+
local nodereference = nuts.reference
local theprop = nuts.theprop
@@ -170,8 +171,9 @@ local new_kern = nodepool.kern
local new_rule = nodepool.rule
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
-local penaltycodes = nodes.penaltycodes
+local gluecodes = nodes.gluecodes
+----- penaltycodes = nodes.penaltycodes
+----- listcodes = nodes.listcodes
local penalty_code = nodecodes.penalty
local kern_code = nodecodes.kern
@@ -179,21 +181,22 @@ local glue_code = nodecodes.glue
local insert_code = nodecodes.ins
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local rule_code = nodecodes.rule
local localpar_code = nodecodes.localpar
-local linebreak_code = penaltycodes.linebreakpenalty
+local userskip_code = gluecodes.userskip
+local lineskip_code = gluecodes.lineskip
+local baselineskip_code = gluecodes.baselineskip
+local parskip_code = gluecodes.parskip
+local topskip_code = gluecodes.topskip
+local splittopskip_code = gluecodes.splittopskip
-local userskip_code = skipcodes.userskip
-local lineskip_code = skipcodes.lineskip
-local baselineskip_code = skipcodes.baselineskip
-local parskip_code = skipcodes.parskip
-local topskip_code = skipcodes.topskip
-local splittopskip_code = skipcodes.splittopskip
+local linelist_code = nodes.listcodes.line
-local abovedisplayskip_code = skipcodes.abovedisplayskip
-local belowdisplayskip_code = skipcodes.belowdisplayskip
-local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip
-local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip
+local abovedisplayskip_code = gluecodes.abovedisplayskip
+local belowdisplayskip_code = gluecodes.belowdisplayskip
+local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip
+local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip
local properties = nodes.properties.data
@@ -208,90 +211,93 @@ vspacingdata.snapmethods = snapmethods
storage.register("builders/vspacing/data/snapmethods", snapmethods, "builders.vspacing.data.snapmethods")
-local default = {
- [v_maxheight] = true,
- [v_maxdepth] = true,
- [v_strut] = true,
- [v_hfraction] = 1,
- [v_dfraction] = 1,
- [v_bfraction] = 0.25,
-}
+do
-local fractions = {
- [v_minheight] = v_hfraction, [v_maxheight] = v_hfraction,
- [v_mindepth] = v_dfraction, [v_maxdepth] = v_dfraction,
- [v_box] = v_bfraction,
- [v_top] = v_tlines, [v_bottom] = v_blines,
-}
+ local default = {
+ [v_maxheight] = true,
+ [v_maxdepth] = true,
+ [v_strut] = true,
+ [v_hfraction] = 1,
+ [v_dfraction] = 1,
+ [v_bfraction] = 0.25,
+ }
-local values = {
- offset = "offset"
-}
+ local fractions = {
+ [v_minheight] = v_hfraction, [v_maxheight] = v_hfraction,
+ [v_mindepth] = v_dfraction, [v_maxdepth] = v_dfraction,
+ [v_box] = v_bfraction,
+ [v_top] = v_tlines, [v_bottom] = v_blines,
+ }
-local colonsplitter = lpeg.splitat(":")
+ local values = {
+ offset = "offset"
+ }
-local function listtohash(str)
- local t = { }
- for s in gmatch(str,"[^, ]+") do
- local key, detail = lpegmatch(colonsplitter,s)
- local v = variables[key]
- if v then
- t[v] = true
- if detail then
- local k = fractions[key]
- if k then
- detail = tonumber("0" .. detail)
- if detail then
- t[k] = detail
- end
- else
- k = values[key]
+ local colonsplitter = lpeg.splitat(":")
+
+ local function listtohash(str)
+ local t = { }
+ for s in gmatch(str,"[^, ]+") do
+ local key, detail = lpegmatch(colonsplitter,s)
+ local v = variables[key]
+ if v then
+ t[v] = true
+ if detail then
+ local k = fractions[key]
if k then
- detail = todimen(detail)
+ detail = tonumber("0" .. detail)
if detail then
t[k] = detail
end
+ else
+ k = values[key]
+ if k then
+ detail = todimen(detail)
+ if detail then
+ t[k] = detail
+ end
+ end
end
end
+ else
+ detail = tonumber("0" .. key)
+ if detail then
+ t[v_hfraction] = detail
+ t[v_dfraction] = detail
+ end
end
+ end
+ if next(t) then
+ t[v_hfraction] = t[v_hfraction] or 1
+ t[v_dfraction] = t[v_dfraction] or 1
+ return t
else
- detail = tonumber("0" .. key)
- if detail then
- t[v_hfraction] = detail
- t[v_dfraction] = detail
- end
+ return default
end
end
- if next(t) then
- t[v_hfraction] = t[v_hfraction] or 1
- t[v_dfraction] = t[v_dfraction] or 1
- return t
- else
- return default
+
+ function vspacing.definesnapmethod(name,method)
+ local n = #snapmethods + 1
+ local t = listtohash(method)
+ snapmethods[n] = t
+ t.name = name -- not interfaced
+ t.specification = method -- not interfaced
+ context(n)
end
-end
-function vspacing.definesnapmethod(name,method)
- local n = #snapmethods + 1
- local t = listtohash(method)
- snapmethods[n] = t
- t.name = name -- not interfaced
- t.specification = method -- not interfaced
- context(n)
end
local function validvbox(parentid,list)
if parentid == hlist_code then
local id = getid(list)
- if id == localpar_code then -- check for initial par subtype
+ if id == localpar_code and getsubtype(list) == 0 then
list = getnext(list)
if not next then
return nil
end
end
local done = nil
- for n in traverse_nodes(list) do
- local id = getid(n)
+ for n, id in nextnode, list do
if id == vlist_code or id == hlist_code then
if done then
return nil
@@ -320,14 +326,13 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only
-- problem: any snapped vbox ends up in a line
if list and parentid == hlist_code then
local id = getid(list)
- if id == localpar_code then -- check for initial par subtype
+ if id == localpar_code and getsubtype(list) == 0 then
list = getnext(list)
if not list then
return false
end
end
- for n in traverse_nodes(list) do
- local id = getid(n)
+ for n, id in nextnode, list do
if id == hlist_code or id == vlist_code then
-- local a = getattr(n,a_snapmethod)
-- if not a then
@@ -536,7 +541,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut]
if thebox and id == vlist_code then
local list = getlist(thebox)
local lw, lh, ld
- for n in traverse_nodes_id(hlist_code,list) do
+ for n in nexthlist, list do
lw, lh, ld = getwhd(n)
break
end
@@ -572,7 +577,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut]
if thebox and id == vlist_code then
local list = getlist(thebox)
local lw, lh, ld
- for n in traverse_nodes_id(hlist_code,list) do
+ for n in nexthlist, list do
lw, lh, ld = getwhd(n)
end
if lh then
@@ -872,14 +877,15 @@ end
local trace_list, tracing_info, before, after = { }, false, "", ""
local function nodes_to_string(head)
- local current, t = head, { }
+ local current = head
+ local t = { }
while current do
local id = getid(current)
local ty = nodecodes[id]
if id == penalty_code then
t[#t+1] = formatters["%s:%s"](ty,getpenalty(current))
elseif id == glue_code then
- t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getwidth(current))
+ t[#t+1] = formatters["%s:%s:%p"](ty,gluecodes[getsubtype(current)],getwidth(current))
elseif id == kern_code then
t[#t+1] = formatters["%s:%p"](ty,getkern(current))
else
@@ -1261,17 +1267,26 @@ do
if trace then
reset_tracing(head)
end
- local current, oldhead = head, head
- local glue_order, glue_data, force_glue = 0, nil, false
- local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil
- local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false
- local lastsnap = nil
+ local current = head
+ local oldhead = head
+ local glue_order = 0
+ local glue_data
+ local force_glue = false
+ local penalty_order = 0
+ local penalty_data
+ local natural_penalty
+ local special_penalty
+ local parskip
+ local ignore_parskip = false
+ local ignore_following = false
+ local ignore_whitespace = false
+ local keep_together = false
+ local lastsnap
+ local pagehead
+ local pagetail
--
-- todo: keep_together: between headers
--
- local pagehead = nil
- local pagetail = nil
-
local function getpagelist()
if not pagehead then
pagehead = texlists.page_head
@@ -1396,7 +1411,7 @@ do
end
head = insert_node_before(head,current,glue_data)
else
- -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w)
+ -- report_vspacing("needs checking (%s): %p",gluecodes[getsubtype(glue_data)],w)
flush_node(glue_data)
end
end
@@ -1814,7 +1829,7 @@ do
if snap and trace_vsnapping then
local w = getwidth(current)
if w ~= 0 then
- report_snapper("glue %p of type %a kept",w,skipcodes[subtype])
+ report_snapper("glue %p of type %a kept",w,gluecodes[subtype])
end
end
if trace then
@@ -1881,7 +1896,7 @@ do
trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)])
end
end
- return head, true
+ return head
end
-- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
@@ -1909,43 +1924,47 @@ do
-- ugly code: we get partial lists (check if this stack is still okay) ... and we run
-- into temp nodes (sigh)
+ local forceflush = false
+
function vspacing.pagehandler(newhead,where)
-- local newhead = texlists.contrib_head
if newhead then
- newhead = tonut(newhead)
local newtail = find_node_tail(newhead) -- best pass that tail, known anyway
local flush = false
stackhack = true -- todo: only when grid snapping once enabled
-- todo: fast check if head = tail
- for n in traverse_nodes(newhead) do -- we could just look for glue nodes
- local id = getid(n)
+ for n, id, subtype in nextnode, newhead do -- we could just look for glue nodes
if id ~= glue_code then
flush = true
- else
- local subtype = getsubtype(n)
- if subtype == userskip_code then
- if getattr(n,a_skipcategory) then
- stackhack = true
- else
- flush = true
- end
- elseif subtype == parskip_code then
- -- if where == new_graf then ... end
- if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then
--- texsetcount("c_spac_vspacing_ignore_parskip",0)
- setglue(n)
- -- maybe removenode
- end
+ elseif subtype == userskip_code then
+ if getattr(n,a_skipcategory) then
+ stackhack = true
+ else
+ flush = true
+ end
+ elseif subtype == parskip_code then
+ -- if where == new_graf then ... end
+ if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then
+ -- texsetcount("c_spac_vspacing_ignore_parskip",0)
+ setglue(n)
+ -- maybe removenode
end
end
end
texsetcount("c_spac_vspacing_ignore_parskip",0)
+
+ if forceflush then
+ forceflush = false
+ flush = true
+ end
+
if flush then
if stackhead then
if trace_collect_vspacing then report("%s > appending %s nodes to stack (final): %s",where,newhead) end
setlink(stacktail,newhead)
- newhead = stackhead
- stackhead, stacktail = nil, nil
+ newhead = stackhead
+ stackhead = nil
+ stacktail = nil
end
if stackhack then
stackhack = false
@@ -1956,7 +1975,7 @@ do
if trace_collect_vspacing then report("%s > flushing %s nodes: %s",where,newhead) end
-- texlists.contrib_head = newhead
end
- return tonode(newhead)
+ return newhead
else
if stackhead then
if trace_collect_vspacing then report("%s > appending %s nodes to stack (intermediate): %s",where,newhead) end
@@ -1966,13 +1985,43 @@ do
stackhead = newhead
end
stacktail = newtail
- -- texlists.contrib_head = nil
- -- newhead = nil
end
end
return nil
end
+ -- function vspacing.flushpagestack()
+ -- if stackhead then
+ -- local head = texlists.contrib_head
+ -- if head then
+ -- local tail = find_node_tail(head)
+ -- setlink(tail,stackhead)
+ -- else
+ -- texlists.contrib_head = tonode(stackhead)
+ -- end
+ -- stackhead, stacktail = nil, nil
+ -- end
+ --
+ -- end
+
+ function vspacing.pageoverflow()
+ local h = 0
+ if stackhead then
+ for n, id in nextnode, stackhead do
+ if id == glue_code then
+ h = h + getwidth(n)
+ elseif id == kern_code then
+ h = h + getkern(n)
+ end
+ end
+ end
+ return h
+ end
+
+ function vspacing.forcepageflush()
+ forceflush = true
+ end
+
local ignore = table.tohash {
"split_keep",
"split_off",
@@ -1980,11 +2029,10 @@ do
}
function vspacing.vboxhandler(head,where)
- if head and not ignore[where] then
- local h = tonut(head)
- if getnext(h) then -- what if a one liner and snapping?
- h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
- return tonode(h)
+ if head and not ignore[where] and getnext(head) then
+ if getnext(head) then -- what if a one liner and snapping?
+ head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
+ return head
end
end
return head
@@ -2015,7 +2063,6 @@ do
local outer = texnest[0]
local enabled = true
- local count = true
local trace = false
local report = logs.reporter("vspacing")
@@ -2024,96 +2071,84 @@ do
end)
directives.register("vspacing.synchronizepage",function(v)
- if v == true or v == "count" then
- enabled = true
- count = true
- elseif v == "first" then
- enabled = true
- count = false
- else
- enabled = false
- count = false
- end
+ enabled = v
end)
- -- hm, check the old one
+ local ignoredepth = -65536000
- -- function vspacing.synchronizepage()
- -- if enabled then
- -- local head = texlists.hold_head
- -- local skip = 0
- -- while head and head.id == insert_code do
- -- head = head.next
- -- skip = skip + 1
- -- end
- -- if head then
- -- outer.prevdepth = 0
- -- end
- -- if trace then
- -- report("prevdepth %s at page %i, skipped %i, value %p",
- -- head and "reset" or "kept",texgetcount("realpageno"),skip,outer.prevdepth)
- -- end
- -- end
- -- end
+ -- A previous version analyzed the number of lines moved to the next page in
+ -- synchronizepage because prevgraf is unreliable in that case. However, we cannot
+ -- tweak that parameter because it is also used in postlinebreak and hangafter, so
+ -- there is a danger for interference. Therefore we now do it dynamically.
- local ignoredepth = -65536000
+ -- We can also support other lists but there prevgraf probably is ok.
- function vspacing.synchronizepage()
+ function vspacing.getnofpreviouslines(head)
if enabled then
- local newdepth = outer.prevdepth
- local olddepth = newdepth
- local oldlines = outer.prevgraf
- local newlines = 0
- local boxfound = false
- local head = texlists.contrib_head
+ if not thead then
+ head = texlists.page_head
+ end
+ local noflines = 0
if head then
local tail = find_node_tail(tonut(head))
while tail do
local id = getid(tail)
if id == hlist_code then
- if not boxfound then
- newdepth = getdepth(tail)
- boxfound = true
- end
- newlines = newlines + 1
- if not count then
+ if getsubtype(tail) == linelist_code then
+ noflines = noflines + 1
+ else
break
end
elseif id == vlist_code then
- if not boxfound then
- newdepth = getdepth(tail)
- boxfound = true
- end
break
elseif id == glue_code then
local subtype = getsubtype(tail)
- if not (subtype == baselineskip_code or subtype == lineskip_code) then
- break
- elseif boxfound and not count then
- break
+ if subtype == baselineskip_code or subtype == lineskip_code then
+ -- we're ok
+ elseif subtype == parskip_code then
+ if getwidth(tail) > 0 then
+ break
+ else
+ -- we assume we're ok
+ end
end
elseif id == penalty_code then
- if boxfound and not count then
- break
- end
- else
- -- ins, mark, kern, rule, boundary, whatsit
+ -- we're probably ok
+ elseif id == rule_code or id == kern_code then
break
+ else
+ -- ins, mark, boundary, whatsit
end
tail = getprev(tail)
end
end
- if boxfound then
- -- what if newdepth ...
- else
- texset("prevdepth",ignoredepth)
- outer.prevdepth = ignoredepth
- end
- texset("prevgraf", newlines)
- outer.prevgraf = newlines
+ return noflines
+ end
+ end
+
+ interfaces.implement {
+ name = "getnofpreviouslines",
+ public = true,
+ actions = vspacing.getnofpreviouslines,
+ }
+
+ function vspacing.synchronizepage()
+ if enabled then
if trace then
- report("page %i, prevdepth %p (last depth %p), prevgraf %i (from %i), %sboxes",
- texgetcount("realpageno"),olddepth,newdepth,oldlines,newlines,boxfound and "" or "no ")
+ local newdepth = outer.prevdepth
+ local olddepth = newdepth
+ if not texlists.page_head then
+ newdepth = ignoredepth
+ texset("prevdepth",ignoredepth)
+ outer.prevdepth = ignoredepth
+ end
+ report("page %i, prevdepth %p => %p",texgetcount("realpageno"),olddepth,newdepth)
+ -- report("list %s",nodes.idsandsubtypes(head))
+ else
+ if not texlists.page_head then
+ texset("prevdepth",ignoredepth)
+ outer.prevdepth = ignoredepth
+ end
end
end
end
@@ -2226,7 +2261,7 @@ do
-- end
-- }
- interfaces.implement {
+ implement {
name = "removelastline",
actions = function()
local head = texlists.page_head
@@ -2242,7 +2277,7 @@ do
end
}
- interfaces.implement {
+ implement {
name = "showpagelist", -- will improve
actions = function()
local head = texlists.page_head
@@ -2256,4 +2291,14 @@ do
end
}
+ implement {
+ name = "pageoverflow",
+ actions = { vspacing.pageoverflow, context }
+ }
+
+ implement {
+ name = "forcepageflush",
+ actions = vspacing.forcepageflush
+ }
+
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/spac-ver.mkiv b/Master/texmf-dist/tex/context/base/mkiv/spac-ver.mkiv
index b71e28219b7..7b36f9a5b52 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/spac-ver.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/spac-ver.mkiv
@@ -15,7 +15,7 @@
\unprotect
-\registerctxluafile{spac-ver}{}
+\registerctxluafile{spac-ver}{optimize}
% todo: use usernodes ?
@@ -165,6 +165,8 @@
\installcommandhandler \??interlinespace {interlinespace} \??interlinespace
+\installmacrostack\currentinterlinespace
+
\unexpanded\def\setupinterlinespace
{\dodoubleempty\spac_linespacing_setup}
@@ -205,7 +207,7 @@
\ifx\p_spac_checked_interlinespace\empty
\spac_linespacing_synchronize_local
\else\ifcsname\namedinterlinespacehash\p_spac_checked_interlinespace\s!parent\endcsname % we could have a \s!check
- \pushmacro\currentinterlinespace
+ \push_macro_currentinterlinespace
\let\currentinterlinespace\p_spac_checked_interlinespace
\spac_linespacing_setup_specified_interline_space % \dosetupspecifiedinterlinespaceindeed
\iflocalinterlinespace
@@ -215,7 +217,7 @@
\the\everysetuplocalinterlinespace
\localinterlinespacefalse
\fi
- \popmacro\currentinterlinespace
+ \pop_macro_currentinterlinespace
\else
\normalexpanded{\noexpand\doifelseassignment{\p_spac_checked_interlinespace}%
\setupspecifiedinterlinespace\setuprelativeinterlinespace[\p_spac_checked_interlinespace]}%
@@ -230,9 +232,9 @@
\unexpanded\def\setuplocalinterlinespace[#1]%
{\localinterlinespacetrue
- \pushmacro\currentinterlinespace
+ \push_macro_currentinterlinespace
\setupinterlinespace[#1]%
- \popmacro\currentinterlinespace
+ \pop_macro_currentinterlinespace
\localinterlinespacefalse}
\let\switchtointerlinespace\setuplocalinterlinespace
@@ -282,47 +284,50 @@
\unexpanded\def\smallbreak
{\par
- \ifdim\lastskip<\smallskipamount
+ \ifvmode\ifdim\lastskip<\smallskipamount
\removelastskip
- \penalty-50
+ \penalty-\plusfifty
\smallskip
- \fi}
+ \fi\fi}
\unexpanded\def\medbreak
{\par
- \ifdim\lastskip<\medskipamount
+ \ifvmode\ifdim\lastskip<\medskipamount
\removelastskip
- \penalty-100
+ \penalty-\plusonehundred
\medskip
- \fi}
+ \fi\fi}
\unexpanded\def\bigbreak
{\par
- \ifdim\lastskip<\bigskipamount
+ \ifvmode\ifdim\lastskip<\bigskipamount
\removelastskip
- \penalty-200
+ \penalty-\plustwohundred
\bigskip
- \fi}
+ \fi\fi}
-\unexpanded\def\break {\penalty-\plustenthousand} % can be hmode or vmode
-\unexpanded\def\nobreak {\penalty \plustenthousand} % can be hmode or vmode
-\unexpanded\def\allowbreak{\penalty \zeropoint} % can be hmode or vmode
-\unexpanded\def\goodbreak {\par\penalty-500\relax} % forces vmode
-\unexpanded\def\filbreak {\par\vfil\penalty-200\vfilneg} % forces vmode
+\unexpanded\def\break {\penalty-\plustenthousand} % can be hmode or vmode
+\unexpanded\def\nobreak {\penalty \plustenthousand} % can be hmode or vmode
+\unexpanded\def\allowbreak{\penalty \zerocount} % can be hmode or vmode
+
+\unexpanded\def\goodbreak {\par\ifvmode\penalty-\plusfivehundred\relax\fi} % forces vmode
+\unexpanded\def\filbreak {\par\ifvmode\vfil\penalty-\plustwohundred\vfilneg\fi} % forces vmode
%D Made slightly more readable:
\unexpanded\def\vglue {\afterassignment\spac_helpers_vglue_indeed\s_spac_lastskip=}
\unexpanded\def\hglue {\afterassignment\spac_helpers_hglue_indeed\s_spac_lastskip=}
-\unexpanded\def\topglue{\nointerlineskip\vglue-\topskip\vglue}
+\unexpanded\def\topglue{\par\ifvmode\nointerlineskip\vglue-\topskip\vglue\fi}
\def\spac_helpers_vglue_indeed
{\par
- \d_spac_prevdepth\prevdepth
- \hrule\s!height\zeropoint
- \nobreak
- \vskip\s_spac_lastskip
- \prevdepth\d_spac_prevdepth}
+ \ifvmode
+ \d_spac_prevdepth\prevdepth
+ \hrule\s!height\zeropoint
+ \nobreak
+ \vskip\s_spac_lastskip
+ \prevdepth\d_spac_prevdepth
+ \fi}
\def\spac_helpers_hglue_indeed
{\dontleavehmode
@@ -895,11 +900,14 @@
\dosetstrut}
\unexpanded\def\setcharstrut#1%
- {\setbox\strutbox\hbox{#1}% hm, maybe hpack i.e. why apply fonts .. conceptual choice
+ {\setbox\strutbox\hbox{#1}% no \hpack, in case we have smallcaps
\strutht\ht\strutbox
\strutdp\dp\strutbox
\dosetstrut}
+\unexpanded\def\settightstrut
+ {\setcharstrut{(}}
+
\unexpanded\def\setfontstrut
{\setcharstrut{(gplQT}}
@@ -1307,9 +1315,41 @@
\let\normaloffinterlineskip\offinterlineskip % knuth's original
+%D This is tricky. The prevdepth value is still set to the last one even if there is
+%D nothing on the page. The same is true for prevgraf, which doesn't resemble the
+%D value on the current page.
+%D
+%D So, here we kick in a checker but it has to happen after the output group and it
+%D only has to be done once (output can trigger itself!).
+%D
+%D However, prevgraf is somehow bound to hangindent so we can get very
+%D nasty side effects. So, in tne end we use our own variable!
+
+\ifdefined\getnofpreviouslines
+ % defined public at the lua end
+\else
+ \let\getnofpreviouslines\!!zerocount
+\fi
+
+\unexpanded\def\page_otr_synchronize_page_yes
+ {\aftergroup\page_otr_synchronize_page_indeed
+ \glet\page_otr_synchronize_page\relax}
+
+% \unexpanded\def\page_otr_synchronize_page_indeed
+% {\clf_synchronizepage
+% \glet\page_otr_synchronize_page\page_otr_synchronize_page_yes}
+%
+% This has to become an otr method: \s!page_otr_command_synchonize_page
+
+\unexpanded\def\page_otr_synchronize_page_indeed
+ {\ifx\currentoutputroutine\s!multicolumn\else\clf_synchronizepage\fi
+ \glet\page_otr_synchronize_page\page_otr_synchronize_page_yes}
+
+\let\page_otr_synchronize_page\page_otr_synchronize_page_yes
+
\appendtoks
- \ifvmode\clf_synchronizepage\fi % a nasty hack (tested for a while now)
-\to \everyafteroutput
+ \page_otr_synchronize_page
+\to \everyaftershipout
%D My own one:
@@ -1361,7 +1401,7 @@
\let\restoreinterlinepenalty\relax
\unexpanded\def\spac_penalties_restore
- {\global\let\restoreinterlinepenalty\relax
+ {\glet\restoreinterlinepenalty\relax
\global\resetpenalties\interlinepenalties
\global\c_spac_keep_lines_together\zerocount}
@@ -1369,7 +1409,7 @@
{\ifnum#1>\c_spac_keep_lines_together
\global\c_spac_keep_lines_together#1%
\global\setpenalties\interlinepenalties\c_spac_keep_lines_together\plustenthousand
- \global\let\restoreinterlinepenalty\spac_penalties_restore
+ \glet\restoreinterlinepenalty\spac_penalties_restore
\fi}
\def\defaultdisplaywidowpenalty {50}
@@ -1701,7 +1741,7 @@
\fi
\doifelsenothing{#1}{\spac_grids_snap_value_set\v!normal}{\spac_grids_snap_value_set{#1}}%
\clf_vspacingsnap\nextbox\attribute\snapmethodattribute\relax
- \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% *pack ?
+ \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% no pack (?), we snap
\egroup}
\def\spac_grids_check_nop
@@ -1816,15 +1856,15 @@
\unexpanded\def\gridboxvbox
{\ifcase\gridboxlinemode
- \vbox
+ \vpack
\or
- \ruledvbox
+ \ruledvpack
\or
- \vbox
+ \vpack
\or
- \ruledvbox
+ \ruledvpack
\else
- \ruledvbox
+ \ruledvpack
\fi}
\def\gridboxwidth{\ifcase\gridboxlinemode0\or.5\or.5\or0\else.5\fi\linewidth}
@@ -1836,8 +1876,10 @@
\resetteststrut
\offinterlineskip
\hsize#2%
- \ifnum\gridboxlinenomode=\plusthree
- \gridboxlinenomode\ifodd\realpageno\plusone\else\plustwo\fi
+ \ifcase\gridboxlinenomode\or\or\or
+ \gridboxlinenomode\doifoddpageelse\plusone\plustwo % 3: outer
+ \or
+ \gridboxlinenomode\doifoddpageelse\plustwo\plusone % 4: inner
\fi
\topskipcorrection
\gridboxvbox % calculated size
@@ -2014,7 +2056,7 @@
\expandafter\nostartblankhandling
\fi}
-\def\nostartblankhandling#1\stopblankhandling
+\unexpanded\def\nostartblankhandling#1\stopblankhandling
{}
\def\dostartblankhandling
@@ -2042,7 +2084,7 @@
\setfalse\c_space_vspacing_done
\the\everybeforeblankhandling}
-\def\addpredefinedblankskip#1#2%
+\unexpanded\def\addpredefinedblankskip#1#2%
{\settrue\c_space_vspacing_done
\advance\s_spac_vspacing_temp#1\dimexpr\csname\??vspacingamount#2\endcsname\relax}
@@ -2089,8 +2131,56 @@
\def\spac_vspacing_nop_ignore
{\ifmmode\else\par\fi}
-\def\directvspacing#1%
- {\par\clf_vspacing{#1}}
+% \unexpanded\def\directvspacing#1%
+% {\par\clf_vspacing{#1}}
+%
+%
+% \def\directdefaultvspacing
+% {\ifinpagebody % somewhat weird
+% \clf_vspacing{\currentvspacing}%
+% \else\ifconditional\c_spac_packed_blank
+% \clf_vspacing{\currentvspacing}%
+% \fi\fi}
+%
+% \unexpanded\def\useblankparameter#1% faster local variant
+% {\edef\m_spac_blank_asked{#1\c!blank}%
+% \ifx\m_spac_blank_asked\empty\else
+% \clf_vspacing{\m_spac_blank_asked}
+% \fi}
+
+\installcorenamespace{vspacing}
+
+\unexpanded\def\directvspacing#1%
+ {\par
+ \ifcsname\??vspacing#1\endcsname
+ \lastnamedcs
+ \else
+ \spac_vspacing_yes_preset{#1}%
+ \fi}
+
+\def\spac_vspacing_yes_preset#1%
+ {\setxvalue{\??vspacing#1}{\clf_vspacing{#1}}%
+ %\writestatus{}{}%
+ %\writestatus{#1}{\expandafter\meaning\csname\??vspacing#1\endcsname}%
+ %\writestatus{}{}%
+ \csname\??vspacing#1\endcsname}
+
+\def\spac_vspacing_yes_indeed[#1]%
+ {\ifmmode\else
+ \directvspacing{#1}%
+ \fi}
+
+\def\spac_vspacing_nop_indeed
+ {\ifmmode\else
+ \directvspacing\currentvspacing
+ \fi}
+
+\def\directdefaultvspacing
+ {\ifinpagebody % somewhat weird
+ \directvspacing\currentvspacing
+ \else\ifconditional\c_spac_packed_blank
+ \directvspacing\currentvspacing
+ \fi\fi}
\def\directcheckedvspacing
{\ifinpagebody % somewhat weird
@@ -2101,17 +2191,10 @@
\doubleexpandafter\gobbleoneargument
\fi\fi}
-\def\directdefaultvspacing
- {\ifinpagebody % somewhat weird
- \clf_vspacing{\currentvspacing}%
- \else\ifconditional\c_spac_packed_blank
- \clf_vspacing{\currentvspacing}%
- \fi\fi}
-
\unexpanded\def\useblankparameter#1% faster local variant
{\edef\m_spac_blank_asked{#1\c!blank}%
\ifx\m_spac_blank_asked\empty\else
- \clf_vspacing{\m_spac_blank_asked}
+ \directvspacing\m_spac_blank_asked
\fi}
% handy (and faster):
@@ -2418,13 +2501,14 @@
\scratchwidth\dimexpr\wd\nextbox+\scratchdistance\relax
\ifx\m_spac_hanging_location\v!right
\hangindent\ifconditional\displaylefttoright-\fi\scratchwidth
- \rlap{\hskip\dimexpr\hsize-\wd\nextbox\relax\box\nextbox}%
+ \rlap{\hskip\dimexpr\hsize-\leftskip-\wd\nextbox\relax\box\nextbox}% \leftskip is new
\else
\hangindent\ifconditional\displaylefttoright\else-\fi\scratchwidth
\llap{\box\nextbox\hskip\scratchdistance}%
\fi
\ignorespaces}
+
%D \macros
%D {startfixed}
%D
diff --git a/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf b/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf
index 74e8e3e8ad5..49b023fb8ce 100644
Binary files a/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf and b/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf differ
diff --git a/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf b/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf
index a2f2ee28b07..8cbd7014cae 100644
Binary files a/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf and b/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf differ
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-blk.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-blk.lua
index 703d36379cb..89df440c966 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-blk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-blk.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['strc-blk'] = {
-- this one runs on top of buffers and structure
local type, next = type, next
-local find, format, validstring = string.find, string.format, string.valid
+local find, formatters, validstring = string.find, string.formatters, string.valid
local settings_to_set, settings_to_array = utilities.parsers.settings_to_set, utilities.parsers.settings_to_array
local allocate = utilities.storage.allocate
@@ -25,6 +25,7 @@ structures.blocks = structures.blocks or { }
local blocks = structures.blocks
local sections = structures.sections
local lists = structures.lists
+local helpers = structures.helpers
local collected = allocate()
local tobesaved = allocate()
@@ -42,14 +43,28 @@ end
job.register('structures.blocks.collected', tobesaved, initializer)
local listitem = utilities.parsers.listitem
+local f_block = formatters["block.%s"]
+
+function blocks.uservariable(index,key,default)
+ local c = collected[index]
+ if c then
+ local u = c.userdata
+ if u then
+ local v = u[key] or default
+ if v then
+ context(v)
+ end
+ end
+ end
+end
-function blocks.print(name,data,hide)
+local function printblock(index,name,data,hide)
if hide then
- context.dostarthiddenblock(name)
+ context.dostarthiddenblock(index,name)
else
- context.dostartnormalblock(name)
+ context.dostartnormalblock(index,name)
end
- context.viafile(data,format("block.%s",validstring(name,"noname")))
+ context.viafile(data,f_block(validstring(name,"noname")))
if hide then
context.dostophiddenblock()
else
@@ -57,12 +72,14 @@ function blocks.print(name,data,hide)
end
end
+blocks.print = printblock
+
function blocks.define(name)
states[name] = { all = "hide" }
end
function blocks.setstate(state,name,tag)
- local all = tag == ""
+ local all = tag == ""
local tags = not all and settings_to_array(tag)
for n in listitem(name) do
local sn = states[n]
@@ -98,12 +115,12 @@ function blocks.select(state,name,tag,criterium)
local metadata = ri.metadata
if names[metadata.name] then
if all then
- blocks.print(name,ri.data,hide)
+ printblock(ri.index,name,ri.data,hide)
else
local mtags = metadata.tags
for tag, sta in next, tags do
if mtags[tag] then
- blocks.print(name,ri.data,hide)
+ printblock(ri.index,name,ri.data,hide)
break
end
end
@@ -112,41 +129,51 @@ function blocks.select(state,name,tag,criterium)
end
end
-function blocks.save(name,tag,buffer) -- wrong, not yet adapted
- local data = buffers.getcontent(buffer)
- local tags = settings_to_set(tag)
- local plus, minus = false, false
- if tags['+'] then plus = true tags['+'] = nil end
- if tags['-'] then minus = true tags['-'] = nil end
- tobesaved[#tobesaved+1] = {
- metadata = {
- name = name,
- tags = tags,
- plus = plus,
+function blocks.save(name,tag,userdata,buffer) -- wrong, not yet adapted
+ local data = buffers.getcontent(buffer)
+ local tags = settings_to_set(tag)
+ local plus = false
+ local minus = false
+ local last = #tobesaved + 1
+ local all = states[name].all
+ if tags['+'] then
+ plus = true
+ tags['+'] = nil
+ end
+ if tags['-'] then
+ minus = true
+ tags['-'] = nil
+ end
+ tobesaved[last] = helpers.simplify {
+ metadata = {
+ name = name,
+ tags = tags,
+ plus = plus,
minus = minus,
},
+ index = last,
+ data = data or "error",
+ userdata = userdata and type(userdata) == "string" and helpers.touserdata(userdata),
references = {
- section = sections.currentid(),
+ section = sections.currentid(),
},
- data = data or "error",
}
- local allstate = states[name].all
if not next(tags) then
- if allstate ~= "hide" then
- blocks.print(name,data)
+ if all ~= "hide" then
+ printblock(last,name,data)
elseif plus then
- blocks.print(name,data,true)
+ printblock(last,name,data,true)
end
else
local sn = states[name]
for tag, _ in next, tags do
if sn[tag] == nil then
- if allstate ~= "hide" then
- blocks.print(name,data)
+ if all ~= "hide" then
+ printblock(last,name,data)
break
end
elseif sn[tag] ~= "hide" then
- blocks.print(name,data)
+ printblock(last,name,data)
break
end
end
@@ -156,7 +183,8 @@ end
-- interface
-implement { name = "definestructureblock", actions = blocks.define, arguments = "string" }
-implement { name = "savestructureblock", actions = blocks.save, arguments = "3 strings" }
-implement { name = "selectstructureblock", actions = blocks.select, arguments = "4 strings" }
-implement { name = "setstructureblockstate", actions = blocks.setstate, arguments = "3 strings" }
+implement { name = "definestructureblock", actions = blocks.define, arguments = "string" }
+implement { name = "savestructureblock", actions = blocks.save, arguments = "4 strings" }
+implement { name = "selectstructureblock", actions = blocks.select, arguments = "4 strings" }
+implement { name = "setstructureblockstate", actions = blocks.setstate, arguments = "3 strings" }
+implement { name = "structureblockuservariable", actions = blocks.uservariable, arguments = { "integer", "string" } }
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-blk.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-blk.mkiv
index c42bb25ec5d..e521987212d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-blk.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-blk.mkiv
@@ -34,48 +34,125 @@
\appendtoks
\clf_definestructureblock{\currentblock}%
- \setuevalue{\e!begin\currentblock}{\dodoubleempty\strc_blocks_begin[\currentblock]}%
- \setuevalue{\e!end \currentblock}{}%
+ \setuevalue{\e!begin\currentblock}{\strc_blocks_begin{\currentblock}}%
+ \letvalue {\e!end \currentblock}\donothing
\to \everydefineblock
-\unexpanded\def\strc_blocks_begin[#1][#2]%
- {\normalexpanded{\buff_pickup{@block@}{\e!begin#1}{\e!end#1}}
- {}% before
- {\clf_savestructureblock{#1}{#2}{@block@}}%
- \plusone}% after
+% The naive way:
+%
+% \unexpanded\def\strc_blocks_begin#1%
+% {\dotripleempty\strc_blocks_begin_indeed[#1]}
+%
+% \unexpanded\def\strc_blocks_begin_indeed[#1][#2][#3]%
+% {\normalexpanded{\buff_pickup{\??block}{\e!begin#1}{\e!end#1}}
+% {}%
+% {\clf_savestructureblock{#1}{#2}{#3}{\??block}}%
+% \plusone}%
+%
+% We need to prevent too much lookahead which will gobble newlines
+% that are needed for buffers. See blocks-002.tex as example.
+
+% maybe: systemmode "block:"
+
+\let\m_block \empty
+\let\m_subblock\empty
+
+\unexpanded\def\strc_blocks_begin#1%
+ {\edef\m_block {#1}%
+ \let \m_subblock\empty
+ \doifelsenextoptionalcs\strc_blocks_begin_yes\strc_blocks_begin_nop}
+
+\unexpanded\def\strc_blocks_begin_yes[#1]%
+ {\doifelseassignmentcs{#1}%
+ \strc_blocks_begin_indeed
+ \strc_blocks_begin_tagged
+ {#1}}
+
+\unexpanded\def\strc_blocks_begin_tagged#1%
+ {\edef\m_subblock{#1}%
+ \doifelsenextoptionalcs\strc_blocks_begin_yes_yes\strc_blocks_begin_nop}
+
+\unexpanded\def\strc_blocks_begin_yes_yes[#1]%
+ {\strc_blocks_begin_indeed{#1}}
+
+\unexpanded\def\strc_blocks_begin_nop
+ {\strc_blocks_begin_indeed{}}
+
+\unexpanded\def\strc_blocks_begin_indeed#1%
+ {\normalexpanded{\buff_pickup{\??block}{\e!begin\m_block}{\e!end\m_block}}%
+ {}%
+ {\clf_savestructureblock{\m_block}{\m_subblock}{#1}{\??block}}%
+ \plusone}
\let\strc_blocks_setup\relax
+\newconstant \c_strc_blocks_index
+\newconditional\c_strc_blocks_display
+
\unexpanded\def\dostarthiddenblock % called at lua end
- {\startnointerference
- \dostartnormalblock}
+ {\begingroup
+ \visiblefalse % blocks float
+ \startnointerference
+ \strc_start_block}
\unexpanded\def\dostophiddenblock % called at lua end
- {\dostopnormalblock
- \stopnointerference}
+ {\strc_stop_block
+ \stopnointerference
+ \endgroup}
+
+\unexpanded\def\dostartnormalblock % called at lua end
+ {\begingroup
+ \visibletrue
+ \strc_start_block}
-\unexpanded\def\dostartnormalblock#1% called at lua end
- {\bgroup
- \visibletrue % will change
- \edef\currentblock{#1}%
+\unexpanded\def\dostopnormalblock % called at lua end
+ {\strc_stop_block
+ \endgroup}
+
+\def\strc_start_block#1#2%
+ {\edef\currentblock{#2}%
+ \c_strc_blocks_index#1\relax
\strc_blocks_setup
\let\strc_blocks_setup\relax
- \blockparameter\c!before
- \useblockstyleandcolor\c!style\c!color % maybe moev one line up (font spacing)
- \blockparameter\c!inner % better \c!setups
+ \edef\p_alternative{\blockparameter\c!alternative}%
+ \ifx\p_alternative\v!text
+ \setfalse\c_strc_blocks_display
+ \else
+ \settrue\c_strc_blocks_display
+ \fi
+ \ifconditional\c_strc_blocks_display
+ \blockparameter\c!before
+ \fi
+ \begingroup
+ \usesetupsparameter\blockparameter\relax
+ \dostarttagged\t!block\currentblock
+ \useblockstyleandcolor\c!style\c!color
+ \blockparameter\c!inner % old
+ \ifconditional\c_strc_blocks_display
+ \usealignparameter\blockparameter
+ \else
+ \blockparameter\c!left
+ \fi
\ignorespaces}
-\unexpanded\def\dostopnormalblock % called at lua end
+\def\strc_stop_block
{\removeunwantedspaces
- \blockparameter\c!after
- \par % todo: alternative = text, paragraph
- \egroup}
+ \ifconditional\c_strc_blocks_display
+ \par
+ \else
+ \blockparameter\c!right
+ \fi
+ \dostoptagged
+ \endgroup
+ \ifconditional\c_strc_blocks_display
+ \blockparameter\c!after
+ \fi}
\def\strc_blocks_set_state[#1][#2][#3]% state name tag
{\clf_setstructureblockstate{#1}{#2}{#3}}
\def\strc_blocks_select[#1][#2][#3][#4]% state name tag setups
- {\bgroup
+ {\begingroup
\doifelseassignment{#3}
{\getparameters[\??blocktemp][\c!criterium=\v!text,#3]%
\def\strc_blocks_setup{\setupcurrentblock[#3]}%
@@ -83,7 +160,10 @@
{\getparameters[\??blocktemp][\c!criterium=\v!text,#4]%
\def\strc_blocks_setup{\setupcurrentblock[#4]}%
\clf_selectstructureblock{#1}{#2}{#3}{\csname\??blocktemp\c!criterium\endcsname}}%
- \egroup}
+ \endgroup}
+
+\def\blockuservariable#1%
+ {\clf_structureblockuservariable\c_strc_blocks_index{#1}}
% hide : save, if [+] also hidden execute
% keep : save and normal execute
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-con.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-con.mkvi
index 57b69cc7f55..d67307ba73b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-con.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-con.mkvi
@@ -980,11 +980,11 @@
\xdef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}%
%
\ifx\currentconstructionexpansion\empty
- \global\let\currentconstructionexpansion\v!no
+ \glet\currentconstructionexpansion\v!no
\fi
%
\ifx\currentconstructionreferenceprefix\empty
- \global\let\currentconstructionreferenceprefix\referenceprefix
+ \glet\currentconstructionreferenceprefix\referenceprefix
\fi
\ifx\currentconstructionexpansion\s!xml
\xmlstartraw
@@ -994,9 +994,9 @@
\xdef\currentconstructionlist {\constructionparameter\c!list}%
\xmlstopraw
\ifx\currentconstructionlist\empty
- \global\let\currentconstructionlist\currentconstructiontitle
+ \glet\currentconstructionlist\currentconstructiontitle
\fi
- \global\let\currentconstructioncoding\s!xml
+ \glet\currentconstructioncoding\s!xml
\else
\ifx\currentconstructionexpansion\v!yes
\xdef\currentconstructiontitle {\constructionparameter\c!title}%
@@ -1016,9 +1016,9 @@
\fi \fi
\fi
\ifx\currentconstructionlist\empty
- \globallet\currentconstructionlist\currentconstructiontitle
+ \glet\currentconstructionlist\currentconstructiontitle
\fi
- \globallet\currentconstructioncoding\s!tex
+ \glet\currentconstructioncoding\s!tex
\fi
%
\ifx\currentconstructiontitle\v!none % will become obsolete
@@ -1093,7 +1093,7 @@
\endgroup
\edef\noexpand\currentconstructionlistentry {\the\scratchcounter}%
\edef\noexpand\currentconstructionattribute {\the\lastdestinationattribute}%
- \edef\noexpand\currentconstructionsynchronize{\ctxlatecommand{enhancelist(\the\scratchcounter)}}%
+ \edef\noexpand\currentconstructionsynchronize{\clf_deferredenhancelist\the\scratchcounter}%
}%
\fi}
@@ -1103,11 +1103,11 @@
\def\reinstateconstructionnumberentry#1% was xdef
{\edef\currentconstructionattribute {\clf_getinternallistreference#1}%
- \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}}
+ \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}}
\def\reinstatecachedconstructionnumberentry#1% was xdef | #1 = cached index can be different from real
{\edef\currentconstructionattribute {\clf_getinternalcachedlistreference#1}% destination
- \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}}
+ \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}}
\installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-def.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-def.mkiv
index 8d1fa371f71..941f561c8ef 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-def.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-def.mkiv
@@ -65,6 +65,17 @@
\setsectionblock [\v!bodypart] % default
+% \setuphead[sectionsegments=\currentheadlevel]
+% \setuphead[sectionsegments=current]
+%
+% \startchapter[title=One,ownnumber={A}]
+% \startsection[title=OneOne,ownnumber={A.B}]
+% \startsubsection[title=OneOneOne,ownnumber={A.B.C}]
+% test
+% \stopsubsection
+% \stopsection
+% \stopchapter
+
% \appendtoks
% \setsectionblock[\v!bodypart]% default
% \to \everyjob
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-doc.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-doc.lua
index 2de26ac64d1..4b2ac04b7f3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-doc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-doc.lua
@@ -18,6 +18,7 @@ if not modules then modules = { } end modules ['strc-doc'] = {
local next, type, tonumber, select = next, type, tonumber, select
local find, match = string.find, string.match
local concat, fastcopy, insert, remove = table.concat, table.fastcopy, table.insert, table.remove
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
local max, min = math.max, math.min
local allocate, mark, accesstable = utilities.storage.allocate, utilities.storage.mark, utilities.tables.accesstable
local setmetatableindex = table.setmetatableindex
@@ -37,11 +38,13 @@ local v_auto = variables.auto
local v_strict = variables.strict
local v_all = variables.all
local v_positive = variables.positive
+local v_current = variables.current
local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end)
local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end)
local report_structure = logs.reporter("structure","sectioning")
+local report_used = logs.reporter("structure")
local context = context
local commands = commands
@@ -122,12 +125,16 @@ local tobesaved = allocate()
sections.collected = collected
sections.tobesaved = tobesaved
--- local function initializer()
--- collected = sections.collected
--- tobesaved = sections.tobesaved
--- end
---
--- job.register('structures.sections.collected', tobesaved, initializer)
+-- We have to save this mostly redundant list because we can have (rare)
+-- cases with own numbers that don't end up in the list so we get out of
+-- sync when we use (*).
+
+local function initializer()
+ collected = sections.collected
+ tobesaved = sections.tobesaved
+end
+
+job.register('structures.sections.collected', tobesaved, initializer)
local registered = sections.registered or allocate()
sections.registered = registered
@@ -158,7 +165,7 @@ end
local lastsaved = 0
function sections.save(sectiondata)
--- local sectionnumber = helpers.simplify(section.sectiondata) -- maybe done earlier
+local sectiondata = helpers.simplify(sectiondata) -- maybe done earlier
local numberdata = sectiondata.numberdata
local ntobesaved = #tobesaved
if not numberdata or sectiondata.metadata.nolist then
@@ -178,28 +185,28 @@ function sections.currentsectionindex()
return lastsaved -- only for special controlled situations
end
-function sections.load()
- setmetatableindex(collected,nil)
- local lists = lists.collected
- for i=1,#lists do
- local list = lists[i]
- local metadata = list.metadata
- if metadata and metadata.kind == "section" and not metadata.nolist then
- local numberdata = list.numberdata
- if numberdata then
- collected[#collected+1] = numberdata
- end
- end
- end
- sections.load = functions.dummy
-end
-
-table.setmetatableindex(collected, function(t,i)
- sections.load()
- return collected[i] or { }
-end)
-
+-- See comment above (*). We cannot use the following space optimization:
+--
+-- function sections.load()
+-- setmetatableindex(collected,nil)
+-- local lists = lists.collected
+-- for i=1,#lists do
+-- local list = lists[i]
+-- local metadata = list.metadata
+-- if metadata and metadata.kind == "section" and not metadata.nolist then
+-- local numberdata = list.numberdata
+-- if numberdata then
+-- collected[#collected+1] = numberdata
+-- end
+-- end
+-- end
+-- sections.load = functions.dummy
+-- end
--
+-- table.setmetatableindex(collected, function(t,i)
+-- sections.load()
+-- return collected[i] or { }
+-- end)
sections.verbose = true
@@ -382,8 +389,9 @@ function sections.setentry(given)
-- new number
olddepth = newdepth
if metadata.increment then
- local oldn, newn = numbers[newdepth] or 0, 0
- local fd = forced[newdepth]
+ local oldn = numbers[newdepth] or 0
+ local newn = 0
+ local fd = forced[newdepth]
if fd then
if fd[1] == "add" then
newn = oldn + fd[2] + 1
@@ -438,7 +446,10 @@ end
function sections.reportstructure()
if sections.verbose then
- local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
+ local numbers = data.numbers
+ local ownnumbers = data.ownnumbers
+ local status = data.status
+ local depth = data.depth
local d = status[depth]
local o = concat(ownnumbers,".",1,depth)
local n = (numbers and concat(numbers,".",1,min(depth,#numbers))) or 0
@@ -711,8 +722,12 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
criterium = 0
end
--
- local firstprefix, lastprefix = 0, 16 -- too much, could max found level
- if segments then
+ local firstprefix = 0
+ local lastprefix = 16 -- too much, could max found level
+ if segments == v_current then
+ firstprefix = data.depth
+ lastprefix = firstprefix
+ elseif segments then
local f, l = match(tostring(segments),"^(.-):(.+)$")
if l == "*" or l == v_all then
l = 100 -- new
@@ -731,9 +746,11 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
end
end
--
- local numbers, ownnumbers = entry.numbers, entry.ownnumbers
+ local numbers = entry.numbers
+ local ownnumbers = entry.ownnumbers
if numbers then
- local done, preceding = false, false
+ local done = false
+ local preceding = false
--
local result = kind == "direct" and { }
if result then
@@ -751,11 +768,14 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
if prefixlist and (kind == "section" or kind == "prefix" or kind == "direct") then
-- find valid set (problem: for sectionnumber we should pass the level)
-- no holes
- local b, e, bb, ee = 1, #prefixlist, 0, 0
+ local b = 1
+ local e = #prefixlist
+ local bb = 0
+ local ee = 0
-- find last valid number
for k=e,b,-1 do
local prefix = prefixlist[k]
- local index = sections.getlevel(prefix) or k
+ local index = sections.getlevel(prefix) or k
if index >= firstprefix and index <= lastprefix then
local number = numbers and numbers[index]
if number then
@@ -771,7 +791,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
-- find valid range
for k=b,e do
local prefix = prefixlist[k]
- local index = sections.getlevel(prefix) or k
+ local index = sections.getlevel(prefix) or k
if index >= firstprefix and index <= lastprefix then
local number = numbers and numbers[index]
if number then
@@ -972,6 +992,47 @@ function sections.getnumber(depth,what) -- redefined here
context(askednumber)
end
+-- maybe handy
+
+function sections.showstructure()
+
+ local tobesaved = structures.lists.tobesaved
+
+ if not tobesaved then
+ return
+ end
+
+ local levels = setmetatableindex("table")
+ local names = setmetatableindex("table")
+
+ report_used()
+ report_used("sections")
+ for i=1,#tobesaved do
+ local si = tobesaved[i]
+ local md = si.metadata
+ if md and md.kind == "section" then
+ local level = md.level
+ local name = md.name
+ local numbers = si.numberdata.numbers
+ local title = si.titledata.title
+ report_used(" %i : %-10s %-20s %s",level,concat(numbers,"."),name,title)
+ levels[level][name] = true
+ names[name][level] = true
+ end
+ end
+ report_used()
+ report_used("levels")
+ for level, list in sortedhash(levels) do
+ report_used(" %s : % t",level,sortedkeys(list))
+ end
+ report_used()
+ report_used("names")
+ for name, list in sortedhash(names) do
+ report_used(" %-10s : % t",name,sortedkeys(list))
+ end
+ report_used()
+end
+
-- experimental
local levels = { }
@@ -1042,6 +1103,7 @@ implement { name = "getsomefullstructurenumber", actions = sections.fullnumber,
implement { name = "getspecificstructuretitle", actions = sections.structuredata, arguments = { "string", "'titledata.title'",false,"string" } }
implement { name = "reportstructure", actions = sections.reportstructure }
+implement { name = "showstructure", actions = sections.showstructure }
implement {
name = "registersection",
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-doc.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-doc.mkiv
index 805525487af..516d87efeb7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-doc.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-doc.mkiv
@@ -19,6 +19,16 @@
%D This will move:
+% \unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext
+% {\clf_setinternalreference
+% prefix {\currentstructurereferenceprefix}%
+% reference {\currentstructurereference}
+% internal \locationcount
+% view {\interactionparameter\c!focus}%
+% \relax
+% \xdef\currentstructureattribute {\the\lastdestinationattribute}%
+% \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}}}
+
\unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext
{\clf_setinternalreference
prefix {\currentstructurereferenceprefix}%
@@ -26,7 +36,20 @@
internal \locationcount
view {\interactionparameter\c!focus}%
\relax
- \xdef\currentstructureattribute {\the\lastdestinationattribute}%
- \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}{\the\locationcount}}}
+ \xdef\currentstructureattribute
+ {\the\lastdestinationattribute}%
+ \xdef\currentstructuresynchronize
+ {\currentstructuresynchronize
+ \strc_lists_inject_enhance{#1}}}
+
+\unexpanded\def\setstructurecomponentsynchronization#1% todo: use ctxcontext
+ {\clf_setinternalreference
+ prefix {\currentstructurecomponentreferenceprefix}%
+ reference {\currentstructurecomponentreference}
+ internal \locationcount
+ view {\interactionparameter\c!focus}%
+ \relax
+ \xdef\currentstructurecomponentattribute {\the\lastdestinationattribute}%
+ \xdef\currentstructurecomponentsynchronize{\strc_lists_inject_enhance{#1}}}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-flt.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-flt.lua
index 466fd515e04..e3a0ea30edb 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-flt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-flt.lua
@@ -7,3 +7,37 @@ if not modules then modules = { } end modules ['strc-flt'] = {
}
-- nothing
+
+local sequencers = utilities.sequencers
+local appendaction = sequencers.appendaction
+local enableaction = sequencers.enableaction
+local disableaction = sequencers.disableaction
+
+local texgetdimen = tex.getdimen
+
+local trace = trackers.register("structure.sidefloats.pageflush")
+local report = logs.reporter("structure","floats")
+
+local forcepageflush = builders.vspacing.forcepageflush
+
+function builders.checksidefloat(mode,indented)
+ local s = texgetdimen("d_page_sides_vsize")
+ if s > 0 then
+ if trace then
+ report("force flushing page state, height %p",s)
+ end
+ forcepageflush()
+ end
+ return indented
+end
+
+appendaction ("newgraf","system","builders.checksidefloat")
+disableaction("newgraf","builders.checksidefloat")
+
+interfaces.implement {
+ name = "enablesidefloatchecker",
+ onlyonce = true,
+ actions = function()
+ enableaction("newgraf","builders.checksidefloat")
+ end,
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-flt.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-flt.mkvi
index 632c6768694..02f6fd75343 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-flt.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-flt.mkvi
@@ -61,9 +61,11 @@
\installcorenamespace{float}
\installcorenamespace{floatbuilder}
\installcorenamespace{floatcaption}
+\installcorenamespace{floatframed}
\installframedcommandhandler \??float {float} \??float
\installframedcommandhandler \??floatcaption {floatcaption} \??floatcaption
+\installframedcommandhandler \??floatframed {floatframed} \??floatframed
\let\setupfloats \setupfloat
\let\setupcaption \setupfloatcaption
@@ -97,6 +99,8 @@
\c!textcolor=,
\c!align=,
\c!number=\v!yes,
+ \c!offset=\v!overlay,
+ \c!frame=\v!off,
% \c!expansion=,
% \c!prefix=,
% \c!prefixconnector=,
@@ -110,7 +114,7 @@
% \c!stopper=,
\c!suffixseparator=, % currently rather hard coded
\c!suffix=\floatcaptionsuffix,
- \c!distance=\emwidth,
+ \c!distance=\emwidth, % plus .5\emwidth minus .25\emwidth
\c!conversion=\v!numbers,
\c!maxwidth=\hsize,
\c!command=]
@@ -171,6 +175,11 @@
\c!sidethreshold=.5\strutdp, % set to "old" to check with old method
\c!numbering=\v!yes]
+\setupfloatframed
+ [\c!frame=\v!off,
+ \c!offset=\v!overlay,
+ \c!strut=\v!no]
+
%D Individial settings:
\installcounterassociation{floatcaption}
@@ -207,6 +216,7 @@
\def\strc_floats_define_a[#1][#2][#3]% name names parent
{\definefloatcaption[#1][#3]%
+ \definefloatframed[#1][#3]%
\definecounter[#1][#3]%
\definelist[#1][#3]%
\copylabeltext[#1=#3]%
@@ -215,6 +225,7 @@
\def\strc_floats_define_b[#1][#2][#3]% name parent settings
{\definefloatcaption[#1][#2]%
+ \definefloatframed[#1][#2]%
\definecounter[#1][#2]%
\definelist[#1][#2]%
\copylabeltext[#1=#2]%
@@ -224,6 +235,7 @@
\def\strc_floats_define_c[#1][#2]% name names
{\registerfloatcaptioncounter{#1}%
\definefloatcaption[#1]%
+ \definefloatframed[#1]%
\definecounter[#1]%
\definelist[#1]%
\presetlabeltext[#1=\Word{#1}~]%
@@ -332,6 +344,7 @@
\def\strc_floats_make_complete_caption
{\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}%
+ \strc_floats_make_complete_caption_before
\synchronizedisplaydirection % temp hack, till we have a proper model
\noindent
\gdef\lastcaptiontag{\strut\thecurrentfloatnumber}% was xdef ... needs checking
@@ -361,8 +374,26 @@
\thecurrentfloatcaption\endgraf
\fi
\endgroup
+ \strc_floats_make_complete_caption_after
\doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}}
+%let\strc_floats_make_complete_caption_before\relax
+\let\strc_floats_make_complete_caption_after \relax
+
+\def\strc_floats_make_complete_caption_before
+ {\doifelseframed\floatcaptionparameter\strc_floats_make_complete_caption_before_indeed\relax}
+
+\def\strc_floats_make_complete_caption_before_indeed
+ {\edef\m_strc_align{\floatcaptionparameter\c!align}%
+ \edef\m_strc_strut{\floatcaptionparameter\c!strut}%
+ \letfloatcaptionparameter\c!align\v!normal
+ \letfloatcaptionparameter\c!strut\v!no
+ \inheritedfloatcaptionframed
+ \bgroup
+ \letfloatcaptionparameter\c!align\m_strc_align
+ \letfloatcaptionparameter\c!strut\m_strc_strut
+ \let\strc_floats_make_complete_caption_after\egroup}
+
% \definefloat [figure-1] [figure]
% \definefloat [figure-2] [figure]
% \setupfloat [figure-1] [location=left,leftmargin=10mm]
@@ -425,7 +456,7 @@
%D {\global\advance\c_strc_floats_n\plusone
%D \xdef\strc_float_realpage{\datasetvariable\s!float{\number\c_strc_floats_n}\s!page}%
%D \ifx\strc_float_realpage\empty
-%D \globallet\strc_float_realpage\realpageno % \realfolio
+%D \glet\strc_float_realpage\realpageno % \realfolio
%D \fi}
%D \stoptyping
%D
@@ -444,7 +475,7 @@
{\global\advance\c_strc_floats_n\plusone
\xdef\strc_float_realpage{\pagestaterealpage\s!float{\number\c_strc_floats_n}}%
\ifx\strc_float_realpage\empty
- \globallet\strc_float_realpage\realpageno % \realfolio
+ \glet\strc_float_realpage\realpageno % \realfolio
\fi}
%D test case:
@@ -482,7 +513,7 @@
\donothing
{\writestatus\m!floatblocks{unknown float type '\currentfloat'}%
\let\currentfloat\v!figure}% also a hack
- \global\let\lastplacedfloat\currentfloat
+ \glet\lastplacedfloat\currentfloat
\let\m_strc_floats_saved_userdata\empty
\let\currentfloatcaption\currentfloat}
@@ -493,8 +524,8 @@
{\global\emptyfloatcaptionfalse
\global\nofloatcaptionfalse
\global\nofloatnumberfalse
- \global\let\askedfloatmethod \empty
- \global\let\askedfloatoptions\empty}
+ \glet\askedfloatmethod \empty
+ \glet\askedfloatoptions\empty}
% place
@@ -505,10 +536,13 @@
\let\floatlocationmethod\empty
\def\strc_floats_analyze_location
- {% moved here, will do more
+ {% more will be moved here
\let\floatlabel \empty
\let\floatcolumn\empty
\let\floatrow \empty
+ %
+ \edef\floatcaptionlocation{\floatcaptionparameter\c!location}%
+ %
\setfloatmethodvariables\floatlocation}
\unexpanded\def\strc_floats_place#tag%
@@ -571,25 +605,49 @@
\strc_floats_set_current_tag{#tag}%
\dodoubleempty\strc_floats_start_place_indeed}
+%D We abuse the settings to pick up some float parameters too which makes it
+%D messy.
+
\def\strc_floats_start_place_indeed[#settings][#userdata]%
{\strc_floats_reset_variables
- \edef\savedfloatlocation{\floatcaptionparameter\c!location}%
+ % save
+ \edef\m_location {\floatcaptionparameter\c!location}%
+ \edef\m_topoffset {\floatcaptionparameter\c!topoffset}%
+ \edef\m_bottomoffset{\floatcaptionparameter\c!bottomoffset}%
+ \edef\m_freeregion {\floatcaptionparameter\c!freeregion}%
+ % preset
+ \letfloatcaptionparameter \c!location \empty
\setexpandedfloatcaptionparameter\c!topoffset {\floatparameter\c!topoffset}%
\setexpandedfloatcaptionparameter\c!bottomoffset{\floatparameter\c!bottomoffset}%
\setexpandedfloatcaptionparameter\c!freeregion {\floatparameter\c!freeregion}%
- \setupcurrentfloatcaption[\c!location=,\c!reference=,\c!title=,\c!marking=,\c!list=,\c!bookmark=,#settings]%
- \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}%
- \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}%
- \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}%
- \def\m_strc_floats_saved_userdata{#2}%
+ \letfloatcaptionparameter \c!reference \empty
+ \letfloatcaptionparameter \c!title \empty
+ \letfloatcaptionparameter \c!marking \empty
+ \letfloatcaptionparameter \c!list \empty
+ \letfloatcaptionparameter \c!bookmark \empty
+ % pickup
+ \setupcurrentfloatcaption[#settings]%
+ \ifsecondargument
+ \setupcurrentfloatuserdata[#userdata]%
+ \def\m_strc_floats_saved_userdata{#userdata}%
+ \else
+ \let\m_strc_floats_saved_userdata\empty
+ \fi
+ % check
\edef\floatlocation{\floatcaptionparameter\c!location}%
- \setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded
\ifx\floatlocation\empty
\edef\floatlocation{\floatparameter\c!default}%
\fi
- \ifsecondargument
- \setupcurrentfloatuserdata[#userdata]%
- \fi
+ % inherit
+ \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}%
+ \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}%
+ \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}%
+ % restore
+ \letfloatcaptionparameter\c!location \m_location
+ \letfloatcaptionparameter\c!topoffset \m_topoffset
+ \letfloatcaptionparameter\c!bottomoffset\m_bottomoffset
+ \letfloatcaptionparameter\c!freeregion \m_freeregion
+ %
\strc_floats_analyze_location
\doifelseinset\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal
\bgroup
@@ -928,9 +986,9 @@
\def\strc_floats_place_packaged_boxes_indeed#userdata%
{\bgroup
\ifconditional\usesamefloatnumber
- \globallet\currentfloatnumber \previousfloatnumber
- \globallet\currentfloatattribute \empty
- \globallet\currentfloatsynchronize\relax
+ \glet\currentfloatnumber \previousfloatnumber
+ \glet\currentfloatattribute \empty
+ \glet\currentfloatsynchronize\relax
\else
\edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}%
\edef\currentfloatgroup {\floatcaptionparameter\c!group}%
@@ -962,10 +1020,10 @@
\s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,%
\s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi]%
[#userdata]%
- \globallet\previousfloatnumber \m_strc_counters_last_registered_index
- \globallet\currentfloatnumber \m_strc_counters_last_registered_index
- \globallet\currentfloatattribute \m_strc_counters_last_registered_attribute
- \globallet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
+ \glet\previousfloatnumber \m_strc_counters_last_registered_index
+ \glet\currentfloatnumber \m_strc_counters_last_registered_index
+ \glet\currentfloatattribute \m_strc_counters_last_registered_attribute
+ \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
\fi
%
\global\setfalse\usesamefloatnumber % one shot
@@ -1191,11 +1249,11 @@
{\global\setbox\floatbox\hpack to \scratchwidth
{\doifnotinset\v!right\floatlocation\hss
\box\floatbox
- \doifnotinset\v!left \floatlocation\hss}}
+ \doifnotinset\v!left\floatlocation\hss}}
-\def\strc_floats_realign_floatbox_horizontal_two
+\def\strc_floats_realign_floatbox_horizontal_two % why is this
{\global\setbox\floatbox\hpack to \scratchwidth
- {\doifnot{\floatparameter\c!location}\v!left \hss
+ {\doifnot{\floatparameter\c!location}\v!left\hss
\box\floatbox
\doifnot{\floatparameter\c!location}\v!right\hss}}
@@ -1336,7 +1394,7 @@
%
% \def\strc_floats_align_content_indeed
% {\alignstrutmode\zerocount
-% \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
+% \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
% {\shiftalignedline
% {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}%
% {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}%
@@ -1371,7 +1429,7 @@
\def\strc_floats_align_content_indeed
{\alignstrutmode\zerocount
\ifx\forcedfloatmethod\v!local \else
- \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
+ \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
{\strc_floats_shift_indeed\floatparameter}%
\expandafter\strc_floats_align_indeed
\fi}
@@ -1462,23 +1520,21 @@
\fi\fi
\strc_floats_align_content{\copy\b_strc_floats_content}}}
+
\def\strc_floats_prepare_page_caption
- {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}%
- \edef\p_strc_floats_caption_width {\floatcaptionparameter\c!width}%
+ {\edef\p_strc_floats_caption_width {\floatcaptionparameter\c!width}%
\edef\p_strc_floats_caption_minwidth{\floatcaptionparameter\c!minwidth}%
\edef\p_strc_floats_caption_align {\floatcaptionparameter\c!align}%
\dostarttagged\t!floatcaption\empty
- \ifx\p_strc_floats_caption_location\v!top
- \strc_floats_prepare_page_caption_top_bottom
- \else\ifx\p_strc_floats_caption_location\v!bottom
- \strc_floats_prepare_page_caption_top_bottom
- \else\ifx\p_strc_floats_caption_width\v!fit
- \strc_floats_prepare_side_auto_caption
- \else\ifx\p_strc_floats_caption_width\v!max
- \strc_floats_prepare_side_auto_caption
- \else
- \strc_floats_prepare_side_width_caption
- \fi\fi\fi\fi
+ \doifcommonelse\floatcaptionlocation{\v!top,\v!bottom}
+ {\strc_floats_prepare_page_caption_top_bottom}
+ {\ifx\p_strc_floats_caption_width\v!fit
+ \strc_floats_prepare_side_auto_caption
+ \else\ifx\p_strc_floats_caption_width\v!max
+ \strc_floats_prepare_side_auto_caption
+ \else
+ \strc_floats_prepare_side_width_caption
+ \fi\fi}%
\dostoptagged}
\def\strc_floats_prepare_page_caption_top_bottom
@@ -1508,7 +1564,11 @@
\fi}
\def\strc_floats_caption_set_align
- {\normalexpanded{\setupalign[\v!reset,\p_strc_floats_caption_align]}}
+ {\edef\m_align{\v!reset\ifx\p_strc_floats_caption_align\empty\else,\fi\p_strc_floats_caption_align}%
+ \doifinset\v!tolerant \floatcaptionlocation{\edef\m_align{\m_align,\v!tolerant}}%
+ \doifinset\v!verytolerant\floatcaptionlocation{\edef\m_align{\m_align,\v!verytolerant}}%
+ \doifinset\v!stretch \floatcaptionlocation{\edef\m_align{\m_align,\v!stretch}}%
+ \setupalign[\m_align]}
\def\strc_floats_prepare_side_auto_caption
{\scratchdimen\dimexpr\hsize-\wd\b_strc_floats_content-\floatparameter\c!margin\relax
@@ -1640,7 +1700,7 @@
{\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi % skip, no pack
{\d_strc_float_temp_height\ht\b_strc_floats_content
\box\b_strc_floats_content
- \doifnotinset\v!hang{\floatcaptionparameter\c!location}
+ \doifnotinset\v!hang\floatcaptionlocation
{\dotfskip{\floatcaptionparameter\c!distance}}%
\vbox to\d_strc_float_temp_height{#1}}}
@@ -1648,7 +1708,7 @@
{\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi % skip, no pack
{\d_strc_float_temp_height\ht\b_strc_floats_content
\vbox to\d_strc_float_temp_height{#1}%
- \doifnotinset\v!hang{\floatcaptionparameter\c!location}
+ \doifnotinset\v!hang\floatcaptionlocation
{\dotfskip{\floatcaptionparameter\c!distance}}%
\box\b_strc_floats_content}}
@@ -1718,7 +1778,7 @@
\def\strc_floats_build_box_next % beware, we first check on left/rightmargin because there can be left/right also
{\let\next\strc_floats_build_box_next_left
- \processallactionsinset[\floatcaptionparameter\c!location]
+ \processallactionsinset[\floatcaptionlocation]
[ \v!outermargin=>\let\next\strc_floats_build_box_next_outer_margin,
\v!innermargin=>\let\next\strc_floats_build_box_next_inner_margin,
\v!leftmargin=>\let\next\strc_floats_build_box_next_left_margin,
@@ -1736,7 +1796,7 @@
\let\next\strc_floats_build_box_high
\else
\let\next\strc_floats_build_box_middle
- \processallactionsinset[\floatcaptionparameter\c!location]
+ \processallactionsinset[\floatcaptionlocation]
[ \v!low=>\let\next\strc_floats_build_box_low,
\v!middle=>\let\next\strc_floats_build_box_middle,
\v!high=>\let\next\strc_floats_build_box_high]%
@@ -1749,14 +1809,13 @@
\def\strc_floats_flush_left_caption_hang
{\hsmash{\llap{\box\b_strc_floats_caption\dotfskip{\floatcaptionparameter\c!distance}}}}
-\def\strc_floats_flush_caption_hang % expanded can go
- {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}%
- \doifelseinset\v!righthanging\p_strc_floats_caption_location
+\def\strc_floats_flush_caption_hang
+ {\doifelseinset\v!righthanging\floatcaptionlocation
{\strc_floats_flush_right_caption_hang}
- {\doifelseinset\v!lefthanging\p_strc_floats_caption_location
+ {\doifelseinset\v!lefthanging\floatcaptionlocation
{\strc_floats_flush_left_caption_hang}
- {\doifelseinset\v!hang\p_strc_floats_caption_location
- {\doifelseinset\v!outer\p_strc_floats_caption_location
+ {\doifelseinset\v!hang\floatcaptionlocation
+ {\doifelseinset\v!outer\floatcaptionlocation
{\doifelserightpagefloat{\strc_floats_flush_right_caption_hang}{\strc_floats_flush_left_caption_hang}}
{\doifelseinset\v!right\floatcaptiondirectives
{\strc_floats_flush_right_caption_hang}
@@ -1834,6 +1893,7 @@
{\dp\b_strc_floats_caption\strutdepth
\setbox\scratchbox\vbox
{\d_strc_float_temp_width\wd\b_strc_floats_content
+ \hsize\d_strc_float_temp_width
\ifconditional\c_strc_floats_par_float
\strc_floats_locate_side_float{\box\b_strc_floats_caption}%
\vss\strc_floats_between_stack
@@ -1845,12 +1905,13 @@
\strc_floats_align_content{\box\b_strc_floats_content}%
\fi}%
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
- \vbox to \noflines\lineheight{\unvbox\scratchbox}} % \vpack ?
+ \vpack to \noflines\lineheight{\unvbox\scratchbox}}
\def\strc_floats_build_box_bottom_stack_grid
{\dp\b_strc_floats_caption\strutdepth
\setbox\scratchbox\vbox
{\d_strc_float_temp_width\wd\b_strc_floats_content
+ \hsize\d_strc_float_temp_width
\ifconditional\c_strc_floats_par_float
\hpack{\box\b_strc_floats_content}%
\vss\strc_floats_between_stack
@@ -1862,7 +1923,7 @@
\strc_floats_locate_text_float{\box\b_strc_floats_caption}%
\fi}%
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
- \vbox to \noflines\lineheight{\unvbox\scratchbox}} % \vpack ?
+ \vpack to \noflines\lineheight{\unvbox\scratchbox}}
\def\strc_floats_build_box_top_stack_stretch
{\dp\b_strc_floats_caption\strutdepth
@@ -1872,6 +1933,7 @@
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
\vbox to \noflines\lineheight % pack ?
{\d_strc_float_temp_width\wd\b_strc_floats_content
+ \hsize\d_strc_float_temp_width
\ifconditional\c_strc_floats_par_float
\strc_floats_locate_side_float{\box\b_strc_floats_caption}%
\vss\strc_floats_between_stack\vss
@@ -1885,16 +1947,17 @@
\def\strc_floats_build_box_bottom_stack_stretch
{\dp\b_strc_floats_caption\strutdepth
- \setbox\scratchbox\vbox % pack ?
- {\strc_floats_align_content{\copy\b_strc_floats_content }%
+ \setbox\scratchbox\vpack
+ {\strc_floats_align_content{\copy\b_strc_floats_content}%
\strc_floats_align_caption{\copy\b_strc_floats_caption}}%
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
\vbox to \noflines\lineheight
{\d_strc_float_temp_width\wd\b_strc_floats_content
+ \hsize\d_strc_float_temp_width
\ifconditional\c_strc_floats_par_float
\hpack{\box\b_strc_floats_content}%
\vss\strc_floats_between_stack\vss
- \strc_floats_locate_side_float{\box\b_strc_floats_caption}
+ \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
\else
\page_otr_command_set_float_hsize
\strc_floats_align_content{\box\b_strc_floats_content}%
@@ -1906,14 +1969,14 @@
{\let\next\strc_floats_build_box_top_stack_normal
\processfirstactioninset[\floatcaptionparameter\c!location]
[ \v!grid=>\let\next\strc_floats_build_box_top_stack_grid,
- \v!stretch=>\let\next\strc_floats_build_box_top_stack_stretch]%
+ \v!lines=>\let\next\strc_floats_build_box_top_stack_stretch]% was \v!grid but interfered
\next}
\def\strc_floats_build_box_bottom
{\let\next\strc_floats_build_box_bottom_stack_normal
\processfirstactioninset[\floatcaptionparameter\c!location]
[ \v!grid=>\let\next\strc_floats_build_box_bottom_stack_grid,
- \v!stretch=>\let\next\strc_floats_build_box_bottom_stack_stretch]%
+ \v!lines=>\let\next\strc_floats_build_box_bottom_stack_stretch]% was \v!grid but interfered
\next}
\def\strc_floats_relocate_caption_right#1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{\hss#1}}}
@@ -1921,23 +1984,50 @@
\unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}}
-\let\strc_floats_mark_box_as_free\relax
-
\def\strc_floats_build_box
- {\global\setbox\floatbox\vbox % pack ? probably not
+ {\strc_floats_build_box_before
+ \global\setbox\floatbox\vbox % pack ? probably not
{\strc_floats_set_local_hsize
\forgetall
\ifconditional\c_floats_store_minimal_package
\strc_floats_build_box_separate_make
\else
- \let\floatcaptionarrangement\s!default
+ % \let\floatcaptionarrangement\s!default
+ \let\floatcaptionarrangement\v!bottom % for Alan
\processcommacommand[\floatcaptionparameter\c!location]\strc_floats_build_box_step
\ifcsname\??floatbuilder\floatcaptionarrangement\endcsname
\lastnamedcs
\else
\strc_floats_build_box_default
\fi
- \fi}}
+ \fi}%
+ \strc_floats_build_box_after}
+
+% \let\strc_floats_build_box_before\relax
+% \let\strc_floats_build_box_after \relax
+
+\def\strc_floats_build_box_before
+ {\let\currentfloatframed\currentfloat
+ \floatwidth\wd
+ \ifdim\wd\b_strc_floats_content>\wd\b_strc_floats_caption
+ \b_strc_floats_content\else\b_strc_floats_caption
+ \fi}
+
+\def\strc_floats_build_box_after
+ {\doifelseframed\floatframedparameter\strc_floats_build_box_after_indeed\relax}
+
+\def\strc_floats_build_box_after_indeed
+ {\global\setbox\floatbox\hpack
+ {\edef\m_width{\floatframedparameter\c!width}%
+ \ifx\m_width\v!fit
+ \let\m_width\floatwidth
+ \else\ifx\m_width\v!broad
+ \let\m_width\v!fit
+ \fi\fi
+ \letfloatframedparameter\c!strut\v!no
+ \letfloatframedparameter\c!width\m_width
+ \inheritedfloatframedframed
+ {\box\floatbox}}}
% special purpose: used in floatcombinations
@@ -1954,7 +2044,7 @@
\vpack to \onepoint{\box\b_strc_floats_caption}}
\def\strc_floats_build_box_separate_split#1%
- {\setbox\scratchbox\vbox{%
+ {\setbox\scratchbox\vbox\bgroup
\setbox\scratchbox\vpack{#1}%
\unvbox\scratchbox\relax
\setbox\scratchbox\lastbox
@@ -1965,13 +2055,20 @@
\unvbox\scratchbox
\setbox\scratchbox\lastbox
% \exitloop
- % \fi}%
+ % \fi
+ %}%
\splittopskip\zeropoint
\global\setbox\b_strc_floats_separate_content\vsplit\scratchbox to \onepoint
\global\setbox\b_strc_floats_separate_caption\vsplit\scratchbox to \onepoint
- \global\setbox\b_strc_floats_separate_content\vpack{\unvbox\b_strc_floats_separate_content\setbox0\lastbox\unvbox0}%
- \global\setbox\b_strc_floats_separate_caption\tpack{\unvbox\b_strc_floats_separate_caption\setbox0\lastbox\unvbox0}%
- }}
+ \egroup
+ \global\setbox\b_strc_floats_separate_content\vpack
+ {\unvbox\b_strc_floats_separate_content
+ \setbox\scratchbox\lastbox
+ \unvbox\scratchbox}%
+ \global\setbox\b_strc_floats_separate_caption\tpack
+ {\unvbox\b_strc_floats_separate_caption
+ \setbox\scratchbox\lastbox
+ \unvbox\scratchbox}}
% \def\strc_floats_build_box_step#1%
% {\doifdefined{\??floatbuilder#1}{\def\floatcaptionarrangement{#1}\quitcommalist}}
@@ -2105,8 +2202,9 @@
\def\strc_floats_prepare_side_caption_fit % or center when smaller
{\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
- \setbox\b_strc_floats_caption\vbox
+ \setbox\b_strc_floats_caption\vbox
{\forgetall % needed?
+ \strc_floats_caption_set_align
\hsize\wd\b_strc_floats_content
\strc_floats_make_complete_caption}%
\else
@@ -2295,6 +2393,8 @@
\definesystemconstant{fxbt}
\definesystemconstant{fixd}
+% can move to page-one:
+
\installfloatmethod \s!singlecolumn \v!here \page_one_place_float_here
\installfloatmethod \s!singlecolumn \v!force \page_one_place_float_force
\installfloatmethod \s!singlecolumn \v!left \page_one_place_float_left
@@ -2330,76 +2430,6 @@
\installfloatmethod \s!singlecolumn \s!fxbt \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!fixd \page_one_place_float_force
-\installfloatmethod \s!multicolumn \v!here \page_mul_place_float_here
-\installfloatmethod \s!multicolumn \v!force \page_mul_place_float_force
-%installfloatmethod \s!multicolumn \v!left
-%installfloatmethod \s!multicolumn \v!right
-%installfloatmethod \s!multicolumn \v!text
-\installfloatmethod \s!multicolumn \v!top \page_mul_place_float_top
-\installfloatmethod \s!multicolumn \v!bottom \page_mul_place_float_bottom
-%installfloatmethod \s!multicolumn \v!auto
-%installfloatmethod \s!multicolumn \v!margin
-%installfloatmethod \s!multicolumn \v!opposite
-%installfloatmethod \s!multicolumn \v!page
-%installfloatmethod \s!multicolumn \v!leftpage
-%installfloatmethod \s!multicolumn \v!rightpage
-%installfloatmethod \s!multicolumn \v!inmargin
-%installfloatmethod \s!multicolumn \v!inleft
-%installfloatmethod \s!multicolumn \v!inright
-%installfloatmethod \s!multicolumn \v!leftmargin
-%installfloatmethod \s!multicolumn \v!rightmargin
-%installfloatmethod \s!multicolumn \v!leftedge
-%installfloatmethod \s!multicolumn \v!rightedge
-%installfloatmethod \s!multicolumn \v!somewhere
-%installfloatmethod \s!multicolumn \v!backspace
-%installfloatmethod \s!multicolumn \v!cutspace
-%installfloatmethod \s!multicolumn \s!tblr
-%installfloatmethod \s!multicolumn \s!lrtb
-%installfloatmethod \s!multicolumn \s!tbrl
-%installfloatmethod \s!multicolumn \s!rltb
-%installfloatmethod \s!multicolumn \s!fxtb
-%installfloatmethod \s!multicolumn \s!btlr
-%installfloatmethod \s!multicolumn \s!lrbt
-%installfloatmethod \s!multicolumn \s!btrl
-%installfloatmethod \s!multicolumn \s!rlbt
-%installfloatmethod \s!multicolumn \s!fxbt
-%installfloatmethod \s!multicolumn \s!fixd
-
-\installfloatmethod \s!columnset \v!here \page_set_place_float_here
-\installfloatmethod \s!columnset \v!force \page_set_place_float_force
-%installfloatmethod \s!columnset \v!left
-%installfloatmethod \s!columnset \v!right
-%installfloatmethod \s!columnset \v!text
-\installfloatmethod \s!columnset \v!top \page_set_place_float_top
-\installfloatmethod \s!columnset \v!bottom \page_set_place_float_bottom
-%installfloatmethod \s!columnset \v!auto
-%installfloatmethod \s!columnset \v!margin
-%installfloatmethod \s!columnset \v!opposite
-\installfloatmethod \s!columnset \v!page \page_set_place_float_page
-%installfloatmethod \s!columnset \v!leftpage
-%installfloatmethod \s!columnset \v!rightpage
-%installfloatmethod \s!columnset \v!inmargin
-%installfloatmethod \s!columnset \v!inleft
-%installfloatmethod \s!columnset \v!inright
-%installfloatmethod \s!columnset \v!leftmargin
-%installfloatmethod \s!columnset \v!rightmargin
-%installfloatmethod \s!columnset \v!leftedge
-%installfloatmethod \s!columnset \v!rightedge
-%installfloatmethod \s!columnset \v!somewhere
-%installfloatmethod \s!columnset \v!backspace
-%installfloatmethod \s!columnset \v!cutspace
-\installfloatmethod \s!columnset \s!tblr \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!lrtb \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!tbrl \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!rltb \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!fxtb \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!btlr \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!lrbt \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!btrl \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!rlbt \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!fxbt \page_set_place_float_slot
-\installfloatmethod \s!columnset \s!fixd \page_set_place_float_force
-
%D Local floats:
\installcorenamespace{localfloats}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-itm.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-itm.mkvi
index 0bea62de8d0..0fc20432081 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-itm.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-itm.mkvi
@@ -352,8 +352,8 @@
\csname\??itemgroupsetting\currentitemgroup\endcsname}
\def\strc_itemgroups_reset_continue_state
- {\global\expandafter\let\csname\??itemgroupoption \currentitemgroup\endcsname\relax
- \global\expandafter\let\csname\??itemgroupsetting\currentitemgroup\endcsname\relax}
+ {\expandafter\glet\csname\??itemgroupoption \currentitemgroup\endcsname\relax
+ \expandafter\glet\csname\??itemgroupsetting\currentitemgroup\endcsname\relax}
% These will become keywords. We will also add a feature to keep the while set
% together.
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-lnt.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-lnt.mkvi
index cd10c9def20..4a6f142458e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-lnt.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-lnt.mkvi
@@ -242,13 +242,13 @@
\def\strc_linenotes_traced_indeed#1%
{\iftracelinenotes
- \hbox to \zeropoint
+ \hpack to \zeropoint
{\forgetall
\hsize\zeropoint
\hss
- \vbox to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}%
+ \vpack to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}%
{\color[blue]{\vl}}%
- \vbox to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}%
+ \vpack to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}%
\hss}%
\prewordbreak
\fi}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua
index 13bdf77865b..bc6135e7242 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua
@@ -35,6 +35,8 @@ local commands = commands
local implement = interfaces.implement
local conditionals = tex.conditionals
+local ctx_latelua = context.latelua
+
local structures = structures
local lists = structures.lists
local sections = structures.sections
@@ -97,7 +99,8 @@ local v_default = variables.default
-- for the moment not public --
local function zerostrippedconcat(t,separator)
- local f, l = 1, #t
+ local f = 1
+ local l = #t
for i=f,l do
if t[i] == 0 then
f = f + 1
@@ -307,7 +310,8 @@ local synchronizepage = function(r) -- bah ... will move
return synchronizepage(r)
end
-function lists.enhance(n)
+local function enhancelist(specification)
+ local n = specification.n
local l = cached[n]
if not l then
report_lists("enhancing %a, unknown internal",n)
@@ -348,6 +352,8 @@ function lists.enhance(n)
end
end
+lists.enhance = enhancelist
+
-- we can use level instead but we can also decide to remove level from the metadata
local nesting = { }
@@ -847,18 +853,22 @@ end
function lists.userdata(name,r,tag) -- to tex (todo: xml)
local result = lists.result[r]
if result then
- local userdata, metadata = result.userdata, result.metadata
+ local userdata = result.userdata
local str = userdata and userdata[tag]
if str then
- return str, metadata
+ return str, result.metadata
end
end
end
function lists.uservalue(name,r,tag,default) -- to lua
local str = lists.result[r]
- str = str and str.userdata
- str = str and str[tag]
+ if str then
+ str = str.userdata
+ end
+ if str then
+ str = str[tag]
+ end
return str or default
end
@@ -1071,8 +1081,19 @@ implement {
implement {
name = "enhancelist",
- actions = lists.enhance,
- arguments = "integer"
+ arguments = "integer",
+ actions = function(n)
+ enhancelist { n = n }
+ end
+}
+
+implement {
+ name = "deferredenhancelist",
+ arguments = "integer",
+ protected = true, -- for now, pre 1.09
+ actions = function(n)
+ ctx_latelua { action = enhancelist, n = n }
+ end,
}
implement {
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-lst.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-lst.mkvi
index 153d879b791..7bc859b670b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-lst.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-lst.mkvi
@@ -145,8 +145,9 @@
{\endgroup}
% \unexpanded
-\def\strc_lists_inject_enhance#listindex#internal%
- {\normalexpanded{\ctxlatecommand{enhancelist(\number#listindex)}}}
+
+\def\strc_lists_inject_enhance#listindex%
+ {\expandafter\clf_deferredenhancelist\number#listindex\relax}
\unexpanded\def\strc_lists_inject_yes[#settings][#userdata]% can be used directly
{\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let...
@@ -168,16 +169,16 @@
userdata {\detokenize\expandafter{\normalexpanded{#userdata}}}
\relax
\edef\currentlistnumber{\the\scratchcounter}%
-\setxvalue{\??listlocations\currentlist}{\the\locationcount}%
+ \setxvalue{\??listlocations\currentlist}{\the\locationcount}%
\ifx\p_location\v!here
% this branch injects nodes !
- \strc_lists_inject_enhance{\currentlistnumber}{\the\locationcount}%
+ \strc_lists_inject_enhance{\currentlistnumber}%
\clf_setinternalreference
internal \locationcount
view {\interactionparameter\c!focus}%
\relax % this will change
\xdef\currentstructurelistattribute{\the\lastdestinationattribute}%
- \dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo
+ \dontleavehmode\hpack attr \destinationattribute \lastdestinationattribute{}% todo
\else
% and this one doesn't
\clf_enhancelist\currentlistnumber\relax
@@ -467,7 +468,7 @@
\relax}
\def\firststructureelementinlist#list% expandable
- {\clf_firstinset{#list}}
+ {\firstinset{#list}}
\def\structurelistsize
{\clf_listsize}
@@ -871,7 +872,7 @@
\appendtoks
\dontcomplain
- \letinteractionparameter\c!width\zeropoint % a weird one
+ % \letinteractionparameter\c!width\zeropoint % a weird one
\to \t_lists_every_renderingsetup
\appendtoks
@@ -1091,7 +1092,7 @@
\fi
\ifconditional\c_lists_has_page
\ifconditional\c_lists_show_page
- \setbox\b_strc_lists_page\hbox {
+ \setbox\b_strc_lists_page\hpack {
\scratchdimen\listalternativeparameter\c!width
\hbox \strc_lists_get_reference_attribute\v!pagenumber \ifdim\scratchdimen>\zeropoint to \scratchdimen\fi {
\hfill
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-mar.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-mar.lua
index 24a7fd4919f..0221b9b8f19 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-mar.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-mar.lua
@@ -13,78 +13,82 @@ local insert, concat = table.insert, table.concat
local tostring, next, rawget, type = tostring, next, rawget, type
local lpegmatch = lpeg.match
-local context = context
-local commands = commands
+local context = context
+local commands = commands
-local implement = interfaces.implement
+local implement = interfaces.implement
-local allocate = utilities.storage.allocate
-local setmetatableindex = table.setmetatableindex
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-local nuts = nodes.nuts
-local tonut = nuts.tonut
+local nuts = nodes.nuts
+local tonut = nuts.tonut
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getattr = nuts.getattr
-local getbox = nuts.getbox
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getattr = nuts.getattr
+local getbox = nuts.getbox
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+local nextnode = nuts.traversers.node
-local nodecodes = nodes.nodecodes
-local glyph_code = nodecodes.glyph
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
+local nodecodes = nodes.nodecodes
+local whatsitcodes = nodes.whatsitcodes
-local texsetattribute = tex.setattribute
+local glyph_code = nodecodes.glyph
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local whatsit_code = nodecodes.whatsit
-local a_marks = attributes.private("structure","marks")
+local lateluawhatsit_code = whatsitcodes.latelua
-local trace_marks_set = false trackers.register("marks.set", function(v) trace_marks_set = v end)
-local trace_marks_get = false trackers.register("marks.get", function(v) trace_marks_get = v end)
-local trace_marks_all = false trackers.register("marks.detail", function(v) trace_marks_all = v end)
+local texsetattribute = tex.setattribute
-local report_marks = logs.reporter("structure","marks")
+local a_marks = attributes.private("structure","marks")
-local variables = interfaces.variables
+local trace_marks_set = false trackers.register("marks.set", function(v) trace_marks_set = v end)
+local trace_marks_get = false trackers.register("marks.get", function(v) trace_marks_get = v end)
+local trace_marks_all = false trackers.register("marks.detail", function(v) trace_marks_all = v end)
-local v_first = variables.first
-local v_last = variables.last
-local v_previous = variables.previous
-local v_next = variables.next
-local v_top = variables.top
-local v_bottom = variables.bottom
-local v_current = variables.current
-local v_default = variables.default
-local v_page = variables.page
-local v_all = variables.all
-local v_keep = variables.keep
+local report_marks = logs.reporter("structure","marks")
-local v_nocheck_suffix = ":" .. variables.nocheck
+local variables = interfaces.variables
-local v_first_nocheck = variables.first .. v_nocheck_suffix
-local v_last_nocheck = variables.last .. v_nocheck_suffix
-local v_previous_nocheck = variables.previous .. v_nocheck_suffix
-local v_next_nocheck = variables.next .. v_nocheck_suffix
-local v_top_nocheck = variables.top .. v_nocheck_suffix
-local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix
+local v_first = variables.first
+local v_last = variables.last
+local v_previous = variables.previous
+local v_next = variables.next
+local v_top = variables.top
+local v_bottom = variables.bottom
+local v_current = variables.current
+local v_default = variables.default
+local v_page = variables.page
+local v_all = variables.all
+local v_keep = variables.keep
-local structures = structures
-local marks = structures.marks
-local lists = structures.lists
+local v_nocheck_suffix = ":" .. variables.nocheck
-local settings_to_array = utilities.parsers.settings_to_array
+local v_first_nocheck = variables.first .. v_nocheck_suffix
+local v_last_nocheck = variables.last .. v_nocheck_suffix
+local v_previous_nocheck = variables.previous .. v_nocheck_suffix
+local v_next_nocheck = variables.next .. v_nocheck_suffix
+local v_top_nocheck = variables.top .. v_nocheck_suffix
+local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix
-local boxes_too = false -- at some point we can also tag boxes or use a zero char
+local structures = structures
+local marks = structures.marks
+local lists = structures.lists
+
+local settings_to_array = utilities.parsers.settings_to_array
+
+local boxes_too = false -- at some point we can also tag boxes or use a zero char
directives.register("marks.boxestoo", function(v) boxes_too = v end)
-marks.data = marks.data or allocate()
+local data = marks.data or allocate()
+marks.data = data
storage.register("structures/marks/data", marks.data, "structures.marks.data")
-local data = marks.data
local stack, topofstack = { }, 0
local ranges = {
@@ -116,9 +120,9 @@ end
-- identify range
local function sweep(head,first,last)
- for n in traverse(head) do
- local id = getid(n)
- if id == glyph_code then
+ for n, id, subtype in nextnode, head do
+ -- we need to handle empty heads so we test for latelua
+ if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then
local a = getattr(n,a_marks)
if not a then
-- next
@@ -433,7 +437,8 @@ local function resolve(name,first,last,strict,quitonfalse,notrace)
if trace_marks_get and not notrace then
report_marks("found chain [ % => T ]",fullchain)
end
- local chaindata, chainlength = { }, #fullchain
+ local chaindata = { }
+ local chainlength = #fullchain
for i=1,chainlength do
local cname = fullchain[i]
if data[cname].set > 0 then
@@ -509,7 +514,8 @@ local methods = { }
local function doresolve(name,rangename,swap,df,dl,strict)
local range = ranges[rangename] or ranges[v_page]
- local first, last = range.first, range.last
+ local first = range.first
+ local last = range.last
if trace_marks_get then
report_marks("action %a, name %a, range %a, swap %a, first %a, last %a, df %a, dl %a, strict %a",
"resolving",name,rangename,swap or false,first,last,df,dl,strict or false)
@@ -638,7 +644,10 @@ function marks.tracers.showtable()
context.tabulaterowbold("name","parent","chain","children","fullchain")
context.ML()
for k, v in table.sortedpairs(data) do
- local parent, chain, children, fullchain = v.parent or "", v.chain or "", v.children or { }, v.fullchain or { }
+ local parent = v.parent or ""
+ local chain = v.chain or ""
+ local children = v.children or { }
+ local fullchain = v.fullchain or { }
table.sort(children) -- in-place but harmless
context.tabulaterowtyp(k,parent,chain,concat(children," "),concat(fullchain," "))
end
@@ -647,28 +656,49 @@ end
-- pushing to context:
-local separator = context.nested.markingseparator
-local command = context.nested.markingcommand
-local ctxconcat = context.concat
-
-local function fetchonemark(name,range,method)
- context(command(name,fetched(name,range,method)))
-end
+-- local separator = context.nested.markingseparator
+-- local command = context.nested.markingcommand
+-- local ctxconcat = context.concat
+
+-- local function fetchonemark(name,range,method)
+-- context(command(name,fetched(name,range,method)))
+-- end
+
+-- local function fetchtwomarks(name,range)
+-- ctxconcat( {
+-- command(name,fetched(name,range,v_first)),
+-- command(name,fetched(name,range,v_last)),
+-- }, separator(name))
+-- end
+
+-- local function fetchallmarks(name,range)
+-- ctxconcat( {
+-- command(name,fetched(name,range,v_previous)),
+-- command(name,fetched(name,range,v_first)),
+-- command(name,fetched(name,range,v_last)),
+-- }, separator(name))
+-- end
+
+ local ctx_separator = context.markingseparator
+ local ctx_command = context.markingcommand
+
+ local function fetchonemark(name,range,method)
+ ctx_command(name,fetched(name,range,method))
+ end
-local function fetchtwomarks(name,range)
- ctxconcat( {
- command(name,fetched(name,range,v_first)),
- command(name,fetched(name,range,v_last)),
- }, separator(name))
-end
+ local function fetchtwomarks(name,range)
+ ctx_command(name,fetched(name,range,v_first))
+ ctx_separator(name)
+ ctx_command(name,fetched(name,range,v_last))
+ end
-local function fetchallmarks(name,range)
- ctxconcat( {
- command(name,fetched(name,range,v_previous)),
- command(name,fetched(name,range,v_first)),
- command(name,fetched(name,range,v_last)),
- }, separator(name))
-end
+ local function fetchallmarks(name,range)
+ ctx_command(name,fetched(name,range,v_previous))
+ ctx_separator(name)
+ ctx_command(name,fetched(name,range,v_first))
+ ctx_separator(name)
+ ctx_command(name,fetched(name,range,v_last))
+ end
function marks.fetch(name,range,method) -- chapter page first | chapter column:1 first
if trace_marks_get then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-mat.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-mat.mkiv
index 775d2aca157..0b80a26cd63 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-mat.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-mat.mkiv
@@ -208,9 +208,9 @@
\c!reference=#1,\c!title=\namedformulaentry,\c!bookmark=]%
[#2]%
\glet\namedformulaentry\empty % \relax
- \globallet#3\m_strc_counters_last_registered_index
- \globallet#4\m_strc_counters_last_registered_synchronize
- \globallet#5\m_strc_counters_last_registered_attribute}
+ \glet#3\m_strc_counters_last_registered_index
+ \glet#4\m_strc_counters_last_registered_synchronize
+ \glet#5\m_strc_counters_last_registered_attribute}
% modes: 0=unset, 1=forced, 2=none, 3=reference
@@ -880,6 +880,9 @@
\par
\fi
\bgroup % HERE
+ \iftrialtypesetting\else
+ \global\advance\c_strc_formulas_n\plusone
+ \fi
\def\currentformula{#1}%
\strc_math_set_split
\dostarttaggedchained\t!formula\currentformula\??formula
@@ -896,7 +899,7 @@
{\edef\p_option{\formulaparameter\c!option}%
\edef\p_option{\ifx\p_option\empty\else\p_option,\fi#2}}%
\else
- \edef\p_option{\formulaparameter\c!option}
+ \edef\p_option{\formulaparameter\c!option}%
\fi
\ifx\p_option\empty \else
\rawprocesscommacommand[\p_option]\strc_formulas_option
@@ -922,10 +925,15 @@
% tagging of formulanumbers is not ok (we get two display maths blobs)
+\newcount\c_strc_formulas_n
+
+\ifdefined\dotagregisterformula \else \let\dotagregisterformula\gobbleoneargument \fi
+
\unexpanded\def\strc_formulas_stop_formula
{\strc_formulas_place_number % in case it hasn't happened yet
\strc_formulas_flush_number % in case we are in native mode
\dostarttagged\t!formulacontent\empty
+ \dotagregisterformula\c_strc_formulas_n
\csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname
\dostoptagged
\dostoptagged
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-not.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-not.lua
index bb9d64beb57..b2c8106e153 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-not.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-not.lua
@@ -247,15 +247,38 @@ end
notes.internal = internal
notes.ordered = ordered
+-- local function onsamepageasprevious(tag)
+-- local same = false
+-- local n = getn(tag,n)
+-- local current = get(tag,n)
+-- local previous = get(tag,n-1)
+-- if current and previous then
+-- local cr = current.references
+-- local pr = previous.references
+-- same = cr and pr and cr.realpage == pr.realpage
+-- end
+-- return same and true or false
+-- end
+
local function onsamepageasprevious(tag)
- local same = false
- local n = getn(tag,n)
- local current, previous = get(tag,n), get(tag,n-1)
- if current and previous then
- local cr, pr = current.references, previous.references
- same = cr and pr and cr.realpage == pr.realpage
+ local n = getn(tag,n)
+ local current = get(tag,n)
+ if not current then
+ return false
+ end
+ local cr = current.references
+ if not cr then
+ return false
+ end
+ local previous = get(tag,n-1)
+ if not previous then
+ return false
+ end
+ local pr = previous.references
+ if not pr then
+ return false
end
- return same and true or false
+ return cr.realpage == pr.realpage
end
notes.doifonsamepageasprevious = onsamepageasprevious
@@ -471,7 +494,7 @@ local texsetglue = tex.setglue
local function check_spacing(n,i)
local gn, pn, mn = texgetglue(n)
local gi, pi, mi = texgetglue(i > 1 and "s_strc_notes_inbetween" or "s_strc_notes_before")
- local gt, pt, mt = gn+gi, pn+pi, mn+mi
+ local gt, pt, mt = gn + gi, pn + pi, mn + mi
if trace_insert then
report_insert("%s %i: %p plus %p minus %p","always ",n,gn,pn,mn)
report_insert("%s %i: %p plus %p minus %p",i > 1 and "inbetween" or "before ",n,gi,pi,mi)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-not.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-not.mkvi
index 8952f0e9c2c..3ce01ef3454 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-not.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-not.mkvi
@@ -456,7 +456,7 @@
\edef\currentnotenumber{\clf_storenote{\currentnote}\currentconstructionlistentry}%
\settrue\processingnote
\ifconditional\c_strc_notes_skip
- \globallet\lastnotesymbol\strc_notes_inject_symbol_nop
+ \glet\lastnotesymbol\strc_notes_inject_symbol_nop
\else
\iftypesettinglines % otherwise problems with \type {xxx}
\ignorelines % makes footnotes work in \startlines ... \stoplines
@@ -465,7 +465,7 @@
\strc_notes_inject_symbol_yes
\else
\unskip\unskip
- \globallet\lastnotesymbol\strc_notes_inject_symbol_yes
+ \glet\lastnotesymbol\strc_notes_inject_symbol_yes
\fi
\fi
\ifconditional\postponingnotes % todo: per note class
@@ -734,7 +734,7 @@
\dostoptagged
\egroup
\endgroup
- \globallet\lastnotesymbol\relax}
+ \glet\lastnotesymbol\relax}
\unexpanded\def\strc_notes_inject_dummy % temp hack
{\removeunwantedspaces
@@ -745,7 +745,7 @@
\fi
\nobreak
\hpack to .5\emwidth{}%
- \globallet\lastnotesymbol\relax}
+ \glet\lastnotesymbol\relax}
\unexpanded\def\strc_notes_inject_separator % patch by WS due to request on list
{\edef\p_textseparator{\noteparameter\c!textseparator}%
@@ -1057,18 +1057,6 @@
\newskip \s_strc_notes_distance % we need to implement stretch
\newcount\c_strc_notes_columns
-% \def\strc_notes_set_distance
-% {\begingroup
-% \setbox\scratchbox\vbox % no reuse as it can mirror
-% {\forgetall
-% \restoreglobalbodyfont % really needed
-% \dontcomplain
-% \noteparameter\c!before
-% \placenoterule
-% \noteparameter\c!after}%
-% \expandafter\endgroup\expandafter
-% \s_strc_notes_distance\the\htdp\scratchbox\relax} % also dp now
-
\newskip \s_strc_notes_before
\newskip \s_strc_notes_inbetween
\newconditional\c_strc_notes_first_flushed
@@ -1382,19 +1370,22 @@
\fi}
\appendtoks
- \strc_notes_set_penalties
- \forgetall % again
- \strc_notes_set_bodyfont
- \redoconvertfont % to undo \undo calls in in headings etc
- \splittopskip\strutht % not actually needed here
- \splitmaxdepth\strutdp % not actually needed here
- % not:
-% \leftmargindistance \noteparameter\c!margindistance
-% \rightmargindistance\leftmargindistance
-% \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
-% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
-% \fi
- %
+ \strc_notes_set_penalties
+ \forgetall % again
+ \strc_notes_set_bodyfont
+ \redoconvertfont % to undo \undo calls in in headings etc
+ \splittopskip\strutht % not actually needed here
+ \splitmaxdepth\strutdp % not actually needed here
+ %
+ % not:
+ %
+ % \leftmargindistance \noteparameter\c!margindistance
+ % \rightmargindistance\leftmargindistance
+ % \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
+ % \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
+ % \fi
+ %
+ \pickupattributes
\to \everyinsidenoteinsert
% maybe but better use [scope=local] here
@@ -1551,7 +1542,7 @@
\unexpanded\def\postponenotes
{\ifconditional\postponingnotes\else
\global\settrue\postponingnotes
- \global\let\flushnotes\doflushnotes
+ \glet\flushnotes\doflushnotes
\clf_postponenotes
\fi}
@@ -1560,7 +1551,7 @@
\unexpanded\def\startpostponingnotes % experimental, page-mix
{\ifconditional\postponingnotes\else
\global\settrue\postponingnotes
- %\global\let\flushnotes\doflushnotes
+ %\glet\flushnotes\doflushnotes
\clf_postponenotes
\fi}
@@ -1581,7 +1572,7 @@
\clf_flushpostponednotes% this also resets the states !
\global\setfalse\postponednote
\global\setfalse\postponingnotes
- \global\let\flushnotes\relax
+ \glet\flushnotes\relax
\endgroup
\fi}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-num.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-num.lua
index e1a133f4a30..25e575a56f7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-num.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-num.lua
@@ -273,7 +273,7 @@ end
function counters.compact(name,level,onlynumbers)
local cd = counterdata[name]
if cd then
- local data = cd.data
+ local data = cd.data
local compact = { }
for i=1,level or #data do
local d = data[i]
@@ -541,22 +541,26 @@ function counters.converted(name,spec) -- name can be number and reference to st
local cd
if type(name) == "number" then
cd = specials.retrieve("counter",name)
- cd = cd and cd.counter
+ if cd then
+ cd = cd.counter
+ end
else
cd = counterdata[name]
end
if cd then
- local spec = spec or { }
- local numbers, ownnumbers = { }, { }
- local reverse = spec.order == v_reverse
- local kind = spec.type or "number"
- local data = cd.data
+ local spec = spec or { }
+ local numbers = { }
+ local ownnumbers = { }
+ local reverse = spec.order == v_reverse
+ local kind = spec.type or "number"
+ local data = cd.data
for k=1,#data do
local v = data[k]
-- somewhat messy, what if subnr? only last must honour kind?
local vn
if v.own then
- numbers[k], ownnumbers[k] = v.number, v.own
+ numbers[k] = v.number
+ ownnumbers[k] = v.own
else
if kind == v_first then
vn = v.first
@@ -577,13 +581,14 @@ function counters.converted(name,spec) -- name can be number and reference to st
end
end
end
- numbers[k], ownnumbers[k] = vn or v.number, nil
+ numbers[k] = vn or v.number
+ ownnumbers[k] = nil
end
end
- cd.numbers = numbers
+ cd.numbers = numbers
cd.ownnumbers = ownnumbers
sections.typesetnumber(cd,'number',spec)
- cd.numbers = nil
+ cd.numbers = nil
cd.ownnumbers = nil
end
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-num.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-num.mkiv
index be35e7671ef..747df29a563 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-num.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-num.mkiv
@@ -578,9 +578,9 @@
\xdef\currentstructurecomponentlist {#2\c!list}%
\xmlstopraw
\ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \glet\currentstructurecomponentlist\currentstructurecomponenttitle
\fi
- \globallet\currentstructurecomponentcoding\s!xml
+ \glet\currentstructurecomponentcoding\s!xml
\else
\ifx\currentstructurecomponentexpansion\v!yes
\xdef\currentstructurecomponenttitle {#2\c!title}%
@@ -600,9 +600,9 @@
\fi \fi
\fi
\ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \glet\currentstructurecomponentlist\currentstructurecomponenttitle
\fi
- \globallet\currentstructurecomponentcoding\s!tex
+ \glet\currentstructurecomponentcoding\s!tex
\fi
%
\setnextinternalreference
@@ -669,11 +669,9 @@
%}
\relax
\xdef\m_strc_counters_last_registered_index{\the\scratchcounter}%
- \clf_setinternalreference
- internal \locationcount
- \relax
- \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}%
- \xdef\m_strc_counters_last_registered_synchronize{\strc_lists_inject_enhance{\m_strc_counters_last_registered_index}{\the\locationcount}}}
+ \setstructurecomponentsynchronization\m_strc_counters_last_registered_index
+ \glet\m_strc_counters_last_registered_attribute \currentstructurecomponentattribute
+ \glet\m_strc_counters_last_registered_synchronize\currentstructurecomponentsynchronize}
\let\m_strc_counters_last_registered_index \relax
\let\m_strc_counters_last_registered_attribute \relax
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-pag.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-pag.lua
index dcd35fc20b7..ee1b245b99b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-pag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-pag.lua
@@ -113,8 +113,9 @@ end
-- end
function pages.number(realdata,pagespec)
- local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock()
- local numberspec = realdata.numberdata
+ local userpage = realdata.number
+ local block = realdata.block or "" -- sections.currentblock()
+ local numberspec = realdata.numberdata
local conversionset = (pagespec and pagespec.conversionset ~= "" and pagespec.conversionset) or (numberspec and numberspec.conversionset ~= "" and numberspec.conversionset) or ""
local conversion = (pagespec and pagespec.conversion ~= "" and pagespec.conversion ) or (numberspec and numberspec.conversion ~= "" and numberspec.conversion ) or ""
local starter = (pagespec and pagespec.starter ~= "" and pagespec.starter ) or (numberspec and numberspec.starter ~= "" and numberspec.starter ) or ""
@@ -212,9 +213,11 @@ end
function helpers.prefixlastpage(data,prefixspec,pagespec)
if data then
- local r = data.references
- local ls, lr = r.section, r.realpage
- r.section, r.realpage = r.lastsection or r.section, r.lastrealpage or r.realpage
+ local r = data.references
+ local ls = r.section
+ local lr = r.realpage
+ r.section = r.lastsection or r.section
+ r.realpage = r.lastrealpage or r.realpage
helpers.prefixpage(data,prefixspec,pagespec)
r.section, r.realpage = ls, lr
end
@@ -227,7 +230,8 @@ function helpers.analyze(entry,specification)
if not entry then
return false, false, "no entry"
end
- local yes, no = variables.yes, variables.no
+ local yes = variables.yes
+ local no = variables.no
-- section data
local references = entry.references
if not references then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-pag.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-pag.mkiv
index d56f0de544e..01361e2c53b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-pag.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-pag.mkiv
@@ -152,7 +152,7 @@
\setupsubpagenumber
[\c!way=\v!by\v!part,
- \c!state=\v!stop]
+ \c!state=\v!start] % was stop but start looks better in logging
% Counters
@@ -263,7 +263,7 @@
\def\currentpage{\the\realpageno}% rather useless
\appendtoks
- \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage \fi
+ \ifnum\realpageno>\lastpage \glet\lastpage\lastrealpage \fi
\to \everyinitializepagecounters
% States:
@@ -309,6 +309,8 @@
% some day ifsinglesided and ifdoublesided will become obsolete
+\newtoks\everysidedswitch
+
\appendtoks
\singlesidedfalse \setfalse\layoutisdoublesided
\doublesidedfalse \setfalse\layoutissinglesided
@@ -317,13 +319,7 @@
\processallactionsinset[\directpagenumberingparameter\c!alternative]
[ \v!singlesided=>\setsystemmode\v!singlesided\singlesidedtrue\settrue\layoutissinglesided,
\v!doublesided=>\setsystemmode\v!doublesided\doublesidedtrue\settrue\layoutisdoublesided]%
- \ifdefined\trackingmarginnotestrue
- \ifdoublesided
- \trackingmarginnotestrue
- \else
- \trackingmarginnotesfalse
- \fi
- \fi
+ \the\everysidedswitch
\pageduplexmode
\ifsinglesided
\ifdoublesided\plustwo\else\zerocount\fi
@@ -334,6 +330,16 @@
\strc_pagenumbers_set_location
\to \everysetuppagenumbering
+\appendtoks
+ \ifdefined\trackingmarginnotestrue
+ \ifdoublesided
+ \trackingmarginnotestrue
+ \else
+ \trackingmarginnotesfalse
+ \fi
+ \fi
+\to \everysidedswitch
+
\ifdefined \page_backgrounds_recalculate \else
\let\page_backgrounds_recalculate\relax
\fi
@@ -401,11 +407,10 @@
\unexpanded\def\strc_pagenumbers_check_state_change#1#2%
{\edef\m_strc_pagenumbers_state_new{\namedcounterparameter#1\c!state}%
\ifx\m_strc_pagenumbers_state_new\m_strc_pagenumbers_state_old \else
- \doifelse\m_strc_pagenumbers_state_new\v!start
- {#2\plustwo}%
- {#2\zerocount}%
+ #2\ifx\m_strc_pagenumbers_state_new\v!start\plustwo\else\zerocount\fi
\fi}
+
\appendtoks % todo: set state: none, start, stop, reset
\strc_pagenumbers_check_state_change\s!realpage\c_strc_pagenumbers_state_realpage
\to \everysetuprealpagenumber
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-ref.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.lua
index f20d931619b..e01bacaac32 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-ref.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.lua
@@ -52,6 +52,8 @@ local context = context
local commands = commands
local implement = interfaces.implement
+local ctx_latelua = context.latelua
+
local texgetcount = tex.getcount
local texsetcount = tex.setcount
local texconditionals = tex.conditionals
@@ -72,6 +74,7 @@ local lists = structures.lists
local counters = structures.counters
local jobpositions = job.positions
+local getpos = jobpositions.getpos
-- some might become local
@@ -137,6 +140,7 @@ storage.register("structures/references/defined", references.defined, "structure
local initializers = { }
local finalizers = { }
+local somefound = false -- so we don't report missing when we have a fresh start
function references.registerinitializer(func) -- we could use a token register instead
initializers[#initializers+1] = func
@@ -162,6 +166,7 @@ local function initializer() -- can we use a tobesaved as metatable for collecte
end
end
end
+ somefound = next(collected)
end
local function finalizer()
@@ -370,6 +375,8 @@ implement {
arguments = "2 strings",
}
+local reported = setmetatableindex("table")
+
function references.set(data)
local references = data.references
local reference = references.reference
@@ -388,16 +395,23 @@ function references.set(data)
if ref == "" then
-- skip
elseif check_duplicates and pd[ref] then
- if prefix and prefix ~= "" then
- report_references("redundant reference %a in namespace %a",ref,prefix)
- else
- report_references("redundant reference %a",ref)
+ if not prefix then
+ prefix = ""
+ end
+ if not reported[prefix][ref] then
+ if prefix ~= "" then
+ report_references("redundant reference %a in namespace %a",ref,prefix)
+ else
+ report_references("redundant reference %a",ref)
+ end
+ reported[prefix][ref] = true
end
else
n = n + 1
pd[ref] = data
local r = data.references
ctx_dofinishreference(prefix or "",ref or "",r and r.internal or 0)
+ -- ctx_latelua(function() structures.references.enhance(prefix or ref,ref or "") end)
end
end
process_settings(reference,action)
@@ -411,8 +425,6 @@ end
-- end
-- end
-local getpos = function() getpos = backends.codeinjections.getpos return getpos () end
-
local function synchronizepage(reference) -- non public helper
reference.realpage = texgetcount("realpageno")
if jobpositions.used then
@@ -422,17 +434,30 @@ end
references.synchronizepage = synchronizepage
-function references.enhance(prefix,tag)
- local l = tobesaved[prefix][tag]
+local function enhancereference(specification)
+ local l = tobesaved[specification.prefix][specification.tag]
if l then
synchronizepage(l.references)
end
end
+references.enhance = enhancereference
+
+-- implement {
+-- name = "enhancereference",
+-- arguments = "2 strings",
+-- actions = function(prefix,tag)
+-- enhancereference { prefix = prefix, tag = tag }
+-- end,
+-- }
+
implement {
- name = "enhancereference",
- actions = references.enhance,
+ name = "deferredenhancereference",
arguments = "2 strings",
+ protected = true,
+ actions = function(prefix,tag)
+ ctx_latelua { action = enhancereference, prefix = prefix, tag = tag }
+ end,
}
-- -- -- related to strc-ini.lua -- -- --
@@ -1004,9 +1029,9 @@ local function loadexternalreferences(name,utilitydata)
local pages = struc.pages.collected -- pagenumber data
-- a bit weird one, as we don't have the externals in the collected
for prefix, set in next, external do
-if prefix == "" then
- prefix = name -- this can clash!
-end
+ if prefix == "" then
+ prefix = name -- this can clash!
+ end
for reference, data in next, set do
if trace_importing then
report_importing("registering %a reference, kind %a, name %a, prefix %a, reference %a",
@@ -1034,9 +1059,9 @@ end
if kind and realpage then
references.pagedata = pages[realpage]
local prefix = references.prefix or ""
-if prefix == "" then
- prefix = name -- this can clash!
-end
+ if prefix == "" then
+ prefix = name -- this can clash!
+ end
local target = external[prefix]
if not target then
target = { }
@@ -1468,7 +1493,7 @@ local function identify_inner(set,var,prefix,collected,derived)
end
end
-- we now ignore the split prefix and treat the whole inner as a potential
- -- referenice into the global list
+ -- reference into the global list
local i = collected[prefix]
if i then
i = i[inner]
@@ -1524,6 +1549,17 @@ local function identify_outer(set,var,i)
end
return v
end
+-- weird too (we really need to check how this table is build
+ local v = identify_inner(set,var,var.outer,external)
+ if v then
+ v.kind = "outer with inner"
+ set.external = true
+ if trace_identifying then
+ report_identify_outer(set,v,i,"2c")
+ end
+ return v
+ end
+--
-- somewhat rubish: we use outer as first step in the externals table so it makes no
-- sense to have it as prefix so the next could be an option
local external = external[""]
@@ -1798,8 +1834,7 @@ local nofidentified = 0
local function identify(prefix,reference)
if not reference then
- prefix = ""
- reference = prefix
+ prefix, reference = "", prefix
end
local set = resolve(prefix,reference)
local bug = false
@@ -1847,7 +1882,9 @@ function references.valid(prefix,reference,specification)
local str = f_valid(prefix,reference)
local u = unknowns[str]
if not u then
- interfaces.showmessage("references",1,str) -- 1 = unknown, 4 = illegal
+ if somefound then
+ interfaces.showmessage("references",1,str) -- 1 = unknown, 4 = illegal
+ end
unknowns[str] = 1
nofunknowns = nofunknowns + 1
else
@@ -1964,13 +2001,14 @@ local function setinternalreference(specification)
local internal = specification.internal
local destination = unsetvalue
if innermethod == v_auto or innermethod == v_name then
- local t, tn = { }, 0 -- maybe add to current (now only used for tracing)
+ local t = { } -- maybe add to current (now only used for tracing)
+ local tn = 0
local reference = specification.reference
local view = specification.view
if reference then
local prefix = specification.prefix
if prefix and prefix ~= "" then
- prefix = prefix .. ":" -- watch out, : here
+ local prefix = prefix .. ":" -- watch out, : here
local function action(ref)
tn = tn + 1
t[tn] = prefix .. ref
@@ -1987,7 +2025,7 @@ local function setinternalreference(specification)
-- ugly .. later we decide to ignore it when we have a real one
-- but for testing we might want to see them all
if internal then
- if innermethod ~= v_name then -- so page and auto
+ if innermethod ~= v_name then -- innermethod == v_auto
-- we don't want too many #1 #2 #3 etc
tn = tn + 1
t[tn] = internal -- when number it's internal
@@ -2064,7 +2102,7 @@ function references.setandgetattribute(data) -- maybe do internal automatically
local done = references.set(data) -- we had kind i.e .item -> full
if done then
attr = setinternalreference {
- prefix = prefix,
+ prefix = rdat.prefix,
reference = rdat.reference,
internal = rdat.internal,
view = rdat.view
@@ -2285,7 +2323,8 @@ genericfilters.default = genericfilters.text
function genericfilters.page(data,prefixspec,pagespec)
local pagedata = data.pagedata
if pagedata then
- local number, conversion = pagedata.number, pagedata.conversion
+ local number = pagedata.number
+ local conversion = pagedata.conversion
if not number then
-- error
elseif conversion then
@@ -2527,10 +2566,19 @@ local function referencepagestate(position,detail,spread)
if not actions then
return 0
else
- if not actions.pagestate then
+ local pagestate = actions.pagestate
+ for i=1,#actions do
+ local a = actions[i]
+ if a.outer then
+ pagestate = 0
+ actions.pagestate = pagestate
+ break
+ end
+ end
+ if not pagestate then
references.analyze(actions,position,spread) -- delayed unless explicitly asked for
+ pagestate = actions.pagestate
end
- local pagestate = actions.pagestate
if detail then
return pagestate
elseif pagestate == 4 then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi
index d0752407c90..c7f20481592 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi
@@ -29,7 +29,7 @@
\registerctxluafile{strc-rsc}{}
\registerctxluafile{strc-ref}{}
-\registerctxluafile{node-ref}{}
+\registerctxluafile{node-ref}{optimize}
\unprotect
@@ -45,19 +45,18 @@
% \definespecial\dosetexecuteJScode
% ...
-%D This module deals with referencing. In \CONTEXT\ referencing is one of
-%D the core features, although at a first glance probably nobody will
-%D notice. This is good, because referencing should be as hidden as possible.
+%D This module deals with referencing. In \CONTEXT\ referencing is one of the core
+%D features, although at a first glance probably nobody will notice. This is good,
+%D because referencing should be as hidden as possible.
%D
-%D Before we start implementing functionality we provide a way to set
-%D up this mechanism.
+%D Before we start implementing functionality we provide a way to set up this
+%D mechanism.
%D
%D \showsetup{setupreferencing}
%D
-%D In interactive documents verbose references don't always
-%D make sense (what is a page number in an unnumbered
-%D document). By setting the \type{interaction} variable, one
-%D can influences the way interactive references are set.
+%D In interactive documents verbose references don't always make sense (what is a
+%D page number in an unnumbered document). By setting the \type{interaction}
+%D variable, one can influences the way interactive references are set.
\let\referenceprefix\empty
@@ -122,20 +121,19 @@
\dosetdirectpagereference\m_strc_references_asked
\fi}
-%D Actually there is not much difference between a text and a
-%D full reference, but it's the concept that counts. The low
-%D level implementation is:
+%D Actually there is not much difference between a text and a full reference, but
+%D it's the concept that counts. The low level implementation is:
\newcount\lastreferenceattribute
\newcount\lastdestinationattribute
\def\strc_references_finish#prefix#reference#internal%
- {\normalexpanded{\ctxlatecommand{enhancereference("#prefix","#reference")}}}
+ {\normalexpanded{\clf_deferredenhancereference{#prefix}{#reference}}}
\let\dofinishreference\strc_references_finish % used at lua end
-% This is somewhat tricky: we want to keep the reference with the following word but
-% that word should also hyphenate. We need to find a better way.
+%D This is somewhat tricky: we want to keep the reference with the following word but
+%D that word should also hyphenate. We need to find a better way.
% 0 = nothing
% 1 = bind to following word
@@ -167,6 +165,32 @@
\unhbox\b_strc_destination_nodes
\fi}
+\def\strc_references_placeholder
+ {\ifx\dotaggedplaceholder\empty\else
+ \attribute\destinationattribute\lastdestinationattribute
+ \dotaggedplaceholder
+ \fi}
+
+\unexpanded\def\strc_references_destination_point_yes
+ {\strc_references_inject_before % new
+ \dostarttagged\t!reference\empty
+ \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup
+ \strc_references_flush_destination_nodes
+ \strc_references_placeholder
+ \egroup
+ \dostoptagged
+ \strc_references_inject_after}
+
+\unexpanded\def\strc_references_destination_point_nop
+ {\strc_references_inject_before % new
+ \dostarttagged\t!reference\empty
+ \dontleavehmode\hbox \bgroup
+ \strc_references_flush_destination_nodes
+ \strc_references_placeholder
+ \egroup
+ \dostoptagged
+ \strc_references_inject_after}
+
\unexpanded\def\strc_references_start_destination_nodes % messy but we need the delay
{\setbox\b_strc_destination_nodes\hbox\bgroup} % also sets lastdestinationattribute
@@ -188,14 +212,14 @@
\xmlstartraw
\xdef\currentreferencedata{#text}% data, no text else conflict
\xmlstopraw
- \globallet\currentreferencecoding\s!xml
+ \glet\currentreferencecoding\s!xml
\else
\ifx\currentreferenceexpansion\v!yes
\xdef\currentreferencedata{#text}%
\else
\xdef\currentreferencedata{\detokenize{#text}}%
\fi
- \globallet\currentreferencecoding\s!tex
+ \glet\currentreferencecoding\s!tex
\fi
% beware, the structures.references.set writes a
\setnextinternalreference
@@ -240,17 +264,9 @@
\xdef\currentdestinationattribute{\number\lastdestinationattribute}%
% will become an option:
\ifnum\lastdestinationattribute>\zerocount
- \strc_references_inject_before % new
- \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup
- \strc_references_flush_destination_nodes
- \egroup
- \strc_references_inject_after % new
+ \strc_references_destination_point_yes
\else\ifvoid\b_strc_destination_nodes\else
- \strc_references_inject_before % new
- \dontleavehmode\hbox \bgroup
- \strc_references_flush_destination_nodes
- \egroup
- \strc_references_inject_after % new
+ \strc_references_destination_point_nop
\fi\fi}
\def\strc_references_set_page_only_destination_attribute#labels% could in fact be fully expandable
@@ -324,17 +340,9 @@
\xdef\currentdestinationattribute{\number\lastdestinationattribute}%
% will become an option:
\ifnum\lastdestinationattribute>\zerocount
- \strc_references_inject_before % new
- \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup
- \strc_references_flush_destination_nodes
- \egroup
- \strc_references_inject_after % new
+ \strc_references_destination_point_yes
\else\ifvoid\b_strc_destination_nodes\else
- \strc_references_inject_before % new
- \dontleavehmode\hbox \bgroup
- \strc_references_flush_destination_nodes
- \egroup
- \strc_references_inject_after % new
+ \strc_references_destination_point_nop
\fi\fi}
\unexpanded\def\strc_references_direct_full
@@ -479,10 +487,10 @@
{\scratchwidth \wd\nextbox
\scratchheight\ht\nextbox
\scratchdepth \dp\nextbox
- \setbox\nextbox\hbox % \hpack ?
+ \setbox\nextbox\hpack
{\framed[\c!frame=\v!off,#2]{\box\nextbox}}%
\strc_references_set_simple_reference{#1}%
- \setbox\nextbox\hbox attr \destinationattribute \currentdestinationattribute % \hpack ?
+ \setbox\nextbox\hpack attr \destinationattribute \currentdestinationattribute % \hpack ?
{\strc_references_flush_destination_nodes
\box\nextbox}%
\setbox\nextbox\hpack{\box\nextbox}%
@@ -494,7 +502,7 @@
\def\strc_references_content_nop_finish#1#2%
{\strc_references_set_simple_reference{#1}%
- \hbox attr \destinationattribute \currentdestinationattribute % \hpack ?
+ \hpack attr \destinationattribute \currentdestinationattribute % \hpack ?
{\strc_references_flush_destination_nodes
\box\nextbox}%
\egroup}
@@ -502,34 +510,31 @@
%D \macros
%D {everyreference}
%D
-%D For rather tricky purposes, one can assign sanitizing
-%D macros to \type{\everyreference} (no longer that relevant).
+%D For rather tricky purposes, one can assign sanitizing macros to \type
+%D {\everyreference} (no longer that relevant).
\newevery \everyreference \relax
-%D This is really needed, since for instance Polish has a
-%D different alphabet and needs accented entries in registers.
+%D This is really needed, since for instance Polish has a different alphabet and
+%D needs accented entries in registers.
\appendtoks
\cleanupfeatures
\to \everyreference
-%D We did not yet discuss prefixing. Especially in interactive
-%D documents, it's not always easy to keep track of duplicate
-%D references. The prefix mechanism, which we will describe
-%D later on, solves this problem. By (automatically) adding a
-%D prefix one keeps references local, but the global ones in
-%D view. To enable this feature, we explictly split the prefix
-%D from the reference.
+%D We did not yet discuss prefixing. Especially in interactive documents, it's not
+%D always easy to keep track of duplicate references. The prefix mechanism, which we
+%D will describe later on, solves this problem. By (automatically) adding a prefix
+%D one keeps references local, but the global ones in view. To enable this feature,
+%D we explictly split the prefix from the reference.
\let\referenceprefix\empty
-%D For a long time the only way to access an external file was
-%D to use the file prefix (\type {somefile::}. However, when
-%D you split up a document, redefining the references may be
-%D such a pain, that another approach is feasible. By setting
-%D the \type {autofile} variable to \type {yes} or \type
-%D {page}, you can access the reference directly.
+%D For a long time the only way to access an external file was to use the file
+%D prefix (\type {somefile::}. However, when you split up a document, redefining the
+%D references may be such a pain, that another approach is feasible. By setting the
+%D \type {autofile} variable to \type {yes} or \type {page}, you can access the
+%D reference directly.
%D
%D \starttabulate[||||]
%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR
@@ -540,9 +545,9 @@
\unexpanded\def\usereferences[#filename]{} % obsolete
-%D As mentioned we will also use the cross reference mechanism
-%D for navigational purposes. The main reason for this is that
-%D we want to treat both categories alike:
+%D As mentioned we will also use the cross reference mechanism for navigational
+%D purposes. The main reason for this is that we want to treat both categories
+%D alike:
%D
%D \starttyping
%D \goto{go back}[PreviousJump]
@@ -553,15 +558,13 @@
%D \type{colofon page} reference is, apart from hyperlinking, a
%D rather normal reference.
%D
-%D We already saw that cross refences are written to and read
-%D from a file. The pure navigational ones don't need to be
-%D written to file, but both for fast processing and
-%D transparant integration, they are saved internally as a sort
-%D of reference. We can easily distinguish such system
-%D references from real cross reference ones by their tag.
+%D We already saw that cross refences are written to and read from a file. The pure
+%D navigational ones don't need to be written to file, but both for fast processing
+%D and transparant integration, they are saved internally as a sort of reference. We
+%D can easily distinguish such system references from real cross reference ones by
+%D their tag.
%D
-%D We also use the odd/even characteristic to determine the
-%D page state.
+%D We also use the odd/even characteristic to determine the page state.
\let\currentrealreference \empty
\let\currentpagereference \empty
@@ -576,11 +579,10 @@
%
% 0 = no page ref, 1=same page, 2=before, 3=after
-%D Cross references appear as numbers (figure~1.1, chapter~2)
-%D or pagenumbers (page~2, page 3--2), and are called with
-%D \type{\in} and \type{\at}. In interactive documents we also
-%D have \type{\goto}, \type{\button} and alike. These are more
-%D versatile and look like:
+%D Cross references appear as numbers (figure~1.1, chapter~2) or pagenumbers
+%D (page~2, page 3--2), and are called with \type {\in} and \type {\at}. In
+%D interactive documents we also have \type {\goto}, \type {\button} and alike.
+%D These are more versatile and look like:
%D
%D \starttyping
%D \goto[reference]
@@ -592,23 +594,19 @@
%D \goto[action{argument}]
%D \stoptyping
%D
-%D The first one is a normal reference, the second and third
-%D are references to a file or \URL. The brace delimited
-%D references for instance refer to a \JAVASCRIPT. The last
-%D example shows that we can pass arguments to the actions.
+%D The first one is a normal reference, the second and third are references to a
+%D file or \URL. The brace delimited references for instance refer to a \JAVASCRIPT.
+%D The last example shows that we can pass arguments to the actions.
%D
-%D Now we've come to the testing step. As we can see below,
-%D this macro does bit more than testing: it also resolves
-%D the reference. This means that whenever we test for the
-%D existance of a reference at an outer level, we have all the
-%D relevant properties of that reference avaliable inside the
-%D true branche~(\type{#2}).
+%D Now we've come to the testing step. As we can see below, this macro does bit more
+%D than testing: it also resolves the reference. This means that whenever we test
+%D for the existance of a reference at an outer level, we have all the relevant
+%D properties of that reference avaliable inside the true branche~(\type {#2}).
%D
-%D The prefix has to do with localizing references. When a
-%D prefix is set, looking for a reference comes to looking for
-%D the prefixed one, and when not found, looking for the non
-%D prefixed one. Consider for instance the prefix set to
-%D \type{sidetrack}.
+%D The prefix has to do with localizing references. When a prefix is set, looking
+%D for a reference comes to looking for the prefixed one, and when not found,
+%D looking for the non prefixed one. Consider for instance the prefix set to \type
+%D {sidetrack}.
%D
%D \starttyping
%D \pagereference[important]
@@ -625,17 +623,15 @@
%D ...{sidetrack}{important}...
%D \stoptyping
%D
-%D Now when we call for \type{unimportant}, we will indeed get
-%D the pagenumber associated to this reference. But when we
-%D call for \type{important}, while the prefix is still set, we
-%D will get the pagenumber bound to the prefixed one.
+%D Now when we call for \type{unimportant}, we will indeed get the pagenumber
+%D associated to this reference. But when we call for \type{important}, while the
+%D prefix is still set, we will get the pagenumber bound to the prefixed one.
%D
%D {\em Some day, when processing time and memory are no longer
%D performance factors, we will introduce multi||level
%D prefixes.}
%D
-%D Before we start analyzing, I introduce a general
-%D definition macro. Consider:
+%D Before we start analyzing, I introduce a general definition macro. Consider:
%D
%D \starttyping
%D \goto{do}[JS(My_Script{"test",123}),titlepage]
@@ -652,8 +648,7 @@
%D
%D \showsetup{definereference}
%D
-%D We can trace references by setting the next switch to
-%D true.
+%D We can trace references by setting the next switch to true.
\unexpanded\def\definereference
{\dodoubleempty\strc_references_define_reference}
@@ -673,23 +668,22 @@
%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)]
%D \stoptyping
%D
-%D Actually supporting chains is up to the special driver. Here
-%D we only provide the hooks.
+%D Actually supporting chains is up to the special driver. Here we only provide the
+%D hooks.
%D \macros
%D {highlighthyperlinks}
%D
-%D The next switch can be used to make user hyperlinks are
-%D not highlighted when clicked on.
+%D The next switch can be used to make user hyperlinks are not highlighted when
+%D clicked on.
\newconditional\highlighthyperlinks \settrue\highlighthyperlinks
%D \macros
%D {gotonewwindow}
%D
-%D To make the {\em goto previous jump} feature more
-%D convenient when using more than one file, it makes sense
-%D to force the viewer to open a new window for each file
+%D To make the {\em goto previous jump} feature more convenient when using more than
+%D one file, it makes sense to force the viewer to open a new window for each file
%D opened.
\newconditional\gotonewwindow \setfalse\gotonewwindow
@@ -708,13 +702,11 @@
\let\doifreferencefoundelse \doifelsereferencefound
-%D The tester only splits the reference in components but does
-%D not look into them. The following macro does a preroll and
-%D determines for instance the current real reference pagenumber.
-%D The \type {\currentrealreference} macro does the same so unless
-%D one wants to use the pagestate the next macro seldom needs to
-%D be called.
-
+%D The tester only splits the reference in components but does not look into them.
+%D The following macro does a preroll and determines for instance the current real
+%D reference pagenumber. The \type {\currentrealreference} macro does the same so
+%D unless one wants to use the pagestate the next macro seldom needs to be called.
+%D
%D The inner case is simple. Only two cases have to be taken
%D care of:
%D
@@ -723,8 +715,8 @@
%D \goto{some text}[prefix:reference]
%D \stoptyping
%D
-%D References to other files however are treated strict or
-%D tolerant, depending on their loading and availability:
+%D References to other files however are treated strict or tolerant, depending on
+%D their loading and availability:
%D
%D \starttyping
%D \useexternaldocument[somefile][filename][a nice description]
@@ -734,72 +726,61 @@
%D \goto{unchecked reference}[anotherfile::reference]
%D \stoptyping
%D
-%D An unknown reference is reported on the screen, in the log
-%D file and, when enabled, in the left margin of the text.
+%D An unknown reference is reported on the screen, in the log file and, when
+%D enabled, in the left margin of the text.
\let\unknownreference\gobbleoneargument
-%D When a reference is not found, we typeset a placeholder
-%D (two glyphs are often enough to represent the reference
-%D text).
+%D When a reference is not found, we typeset a placeholder (two glyphs are often
+%D enough to represent the reference text).
\def\dummyreference{{\tttf ??}}
\def\emptyreference{{\tttf !!}}
-%D To prevent repetitive messages concerning a reference
-%D being defined, we set such an unknown reference to an empty
-%D one after the first encounter.
-
-%D Apart from cross references supplied by the user, \CONTEXT\
-%D generates cross references itself. Most of them are not
-%D saved as a reference, but stored with their source, for
-%D instance a list or an index entry. Such automatically
-%D generated, for the user invisible, references are called
-%D {\em internal references}. The user supplied ones are
-%D labeled as {\em external references}.
-%D
-%D A second important characteristic is that when we want to
-%D support different backends (viewers), we need to support
-%D named destinations as well as page numbers. I invite readers
-%D to take a glance at the special driver modules to understand
-%D the fine points of this. As a result we will deal with {\em
-%D locations} as well as {\em real page numbers}. We explictly
-%D call this pagenumber a real one, because it is independant
-%D of the page numbering scheme used in the document.
-%D
-%D One of the reasons for \CONTEXT\ being the first \TEX\ base
-%D macropackage to support sophisticated interactive \PDF\
-%D files, lays in the mere fact that real page numbers are
-%D available in most two pass data, like references, list data
-%D and index entries.
-%D
-%D We will speak of \type{thisis...} when we are marking a
-%D location, and \type{goto...} when we point to such a
-%D location. The latter one can be seen as a hyperlink to the
-%D former one. In the next macros one we use constructs like:
+%D To prevent repetitive messages concerning a reference being defined, we set such
+%D an unknown reference to an empty one after the first encounter.
+%D
+%D Apart from cross references supplied by the user, \CONTEXT\ generates cross
+%D references itself. Most of them are not saved as a reference, but stored with
+%D their source, for instance a list or an index entry. Such automatically
+%D generated, for the user invisible, references are called {\em internal
+%D references}. The user supplied ones are labeled as {\em external references}.
+%D
+%D A second important characteristic is that when we want to support different
+%D backends (viewers), we need to support named destinations as well as page
+%D numbers. I invite readers to take a glance at the special driver modules to
+%D understand the fine points of this. As a result we will deal with {\em locations}
+%D as well as {\em real page numbers}. We explictly call this pagenumber a real one,
+%D because it is independant of the page numbering scheme used in the document.
+%D
+%D One of the reasons for \CONTEXT\ being the first \TEX\ base macropackage to
+%D support sophisticated interactive \PDF\ files, lays in the mere fact that real
+%D page numbers are available in most two pass data, like references, list data and
+%D index entries.
+%D
+%D We will speak of \type {thisis...} when we are marking a location, and
+%D \type {goto...} when we point to such a location. The latter one can be seen as a
+%D hyperlink to the former one. In the next macros one we use constructs like:
%D
%D \starttyping
%D \dostart...
%D \dostop...
%D \stoptyping
%D
-%D Such macros are used to invoke the relevant specials from
-%D the special driver modules (see \type{spec-ini}). The flag
-%D \type{\iflocation} signals if we're in interactive mode.
+%D The flag \type {\iflocation} signals if we're in interactive mode.
\ifdefined\buttonheight \else \newdimen\buttonheight \fi
\ifdefined\buttonwidth \else \newdimen\buttonwidth \fi
-%D Internal references can best be set using the next few
-%D macros. Setting such references to unique values is
-%D completely up to the macros that call them.
+%D Internal references can best be set using the next few macros. Setting such
+%D references to unique values is completely up to the macros that call them.
%D
%D \starttyping
%D \thisissomeinternal{tag}{identifier}
%D \gotosomeinternal {tag}{identifier}{pagenumber}{text}
%D \stoptyping
-
-%D We could do this in lua ...
+%D
+%D We could do this in \LUA\ \unknown
\newif \iflocation
\newcount\locationcount
@@ -823,7 +804,7 @@
\clf_setinternalreference
reference {#kind:#name}% no view
\relax
- \hbox attr \destinationattribute\lastdestinationattribute{}%
+ \hpack attr \destinationattribute\lastdestinationattribute{}%
\endgroup}
\installcorenamespace{savedinternalreference}
@@ -845,12 +826,10 @@
\def\gotonextinternal#text#target%
{\directgoto{#text}[internal(#target)]}
-%D In this module we define three system references: one for
-%D handling navigational, viewer specific, commands, another
-%D for jumping to special pages, like the first or last one,
-%D and a third reference for linking tree like lists, like
-%D tables of contents. The latter two adapt themselves to the
-%D current state.
+%D In this module we define three system references: one for handling navigational,
+%D viewer specific, commands, another for jumping to special pages, like the first
+%D or last one, and a third reference for linking tree like lists, like tables of
+%D contents. The latter two adapt themselves to the current state.
%D
%D An example of an action is:
%D
@@ -863,11 +842,10 @@
%D \starttyping
%D \goto{some text}[\v!action(PreviousJump]
%D \stoptyping
-
-%D One can also activate an automatic prefix mechanism. By
-%D setting the \type{\prefix} variable to \type{+}, the prefix
-%D is incremented, when set to \type{-} or empty, the prefix is
-%D reset. Other values become the prefix.
+%D
+%D One can also activate an automatic prefix mechanism. By setting the
+%D \type {\prefix} variable to \type {+}, the prefix is incremented, when set to
+%D \type {-} or empty, the prefix is reset. Other values become the prefix.
\newcount\prefixcounter
@@ -892,13 +870,6 @@
\unexpanded\def\setupglobalreferenceprefix[#prefix]%
{\xdef\referenceprefix{#prefix}}
-% \unexpanded\def\pushreferenceprefix#prefix%
-% {\pushmacro\referenceprefix
-% \xdef\referenceprefix{#prefix}} % global
-
-% \unexpanded\def\popreferenceprefix
-% {\popmacro\referenceprefix}
-
\unexpanded\def\globalpushreferenceprefix#prefix%
{\xdef\referenceprefix{\clf_pushreferenceprefix{#prefix}}}
@@ -935,16 +906,14 @@
\setupreferenceprefix[\referencingparameter\c!prefix]
\to \everysetupreferencing
-%D We can typeset a reference using \type{\in}, \type{\at} and
-%D \type{\about} and goto specific locations using
-%D \type{\goto}. The last one does not make that much sense in
-%D a paper document. To complicate things, \PLAIN\ \TEX\ also
-%D implements an \type {\in} but fortunately that one only
-%D makes sense in math mode.
+%D We can typeset a reference using \type {\in}, \type {\at} and \type {\about} and
+%D goto specific locations using \type {\goto}. The last one does not make that much
+%D sense in a paper document. To complicate things, \PLAIN\ \TEX\ also implements an
+%D \type {\in} but fortunately that one only makes sense in math mode.
%D
-%D Typesetting the reference is a bit more complicated than one
-%D would at first sight expect. This is due to the fact that we
-%D distinguish three (five) alternative calls:
+%D Typesetting the reference is a bit more complicated than one would at first sight
+%D expect. This is due to the fact that we distinguish three (five) alternative
+%D calls:
%D
%D \placefigure
%D [here][three calls]
@@ -971,25 +940,11 @@
%D \getbuffer
%D \stoplines
%D
-%D The dual \type{{}} results in a split reference. In a
-%D document meant for paper, one is tempted to use the last
-%D (most straightforward) alternative. When a document is also
-%D meant voor electronic distribution, the former alternatives
-%D have preference, because everything between the \type{\in}
-%D and~\type{[} becomes active (and when asked for, typeset
-%D in a different color and typeface).
-
-% \unexpanded\def\in {\mathortext\donormalmathin \strc_references_in}
-% \unexpanded\def\at {\mathortext\donormalmathat \strc_references_at}
-% \unexpanded\def\about{\mathortext\donormalmathabout\strc_references_about}
-% \unexpanded\def\from {\mathortext\donormalmathfrom \strc_references_from}
-% \unexpanded\def\over {\mathortext\donormalmathover \strc_references_about}
-
-% \definecommand in {\strc_references_in}
-% \definecommand at {\strc_references_at}
-% \definecommand about {\strc_references_about}
-% \definecommand from {\strc_references_from}
-% \definecommand over {\strc_references_about} % needed here, else math problems
+%D The dual \type {{}} results in a split reference. In a document meant for paper,
+%D one is tempted to use the last (most straightforward) alternative. When a
+%D document is also meant voor electronic distribution, the former alternatives have
+%D preference, because everything between the \type {\in} and~\type {[} becomes
+%D active (and when asked for, typeset in a different color and typeface).
\appendtoks
\ifdefined\in \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \strc_references_in } \else \let\in \strc_references_in \fi
@@ -1009,8 +964,7 @@
\def\currentreferencedefault {\clf_filterreference{default}}
\def\currentreferencerealpage{\clf_filterreference{realpage}}
-%D The most straightforward way of retrieving references is
-%D using \type{\ref}.
+%D The most straightforward way of retrieving references is using \type {\ref}.
\unexpanded\def\getreference % checking, unexpanded
{\dodoubleargument\strc_references_get_reference}
@@ -1040,12 +994,11 @@
\referencingparameter\c!right
\endgroup}
-%D The previously discussed setup macro lets us specify the
-%D representation of references. A symbol reference does not
-%D show the specific data, like the number of a figure, but
-%D shows one of: \hbox {$^\goforwardcharacter$
-%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending
-%D on the direction to go.
+%D The previously discussed setup macro lets us specify the representation of
+%D references. A symbol reference does not show the specific data, like the number
+%D of a figure, but shows one of: \hbox {$^\goforwardcharacter$
+%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending on the direction to
+%D go.
%D
%D \starttyping
%D ... \somewhere{backward text}{forward text}[someref] ...
@@ -1141,7 +1094,7 @@
\expandafter\sixthofsixarguments \fi}
\unexpanded\def\referencesymbol
- {\hbox\bgroup
+ {\hpack\bgroup
\strut
\markreferencepage
\high
@@ -1210,17 +1163,23 @@
\newtoks\defaultleftreferencetoks
\newtoks\defaultrightreferencetoks
-\def\leftofreferencecontent {\nobreakspace} % we cannot do \definereferenceformat[at] .. so we need this
+%def\leftofreferencecontent {\nobreakspace} % we cannot do \definereferenceformat[at] .. so we need this
\let\rightofreferencecontent \empty
\let\leftofreference \empty
\let\rightofreference \empty
+\unexpanded\def\leftofreferencecontent
+ {\removeunwantedspaces
+ \nonbreakablespace
+ \ignorespaces}
+
\installcorenamespace{referencinginteraction}
\def\strc_references_interaction_all
{\the\leftreferencetoks
\doifelsesometoks\leftreferencetoks \leftofreferencecontent \donothing
\leftofreference
+ \doifelsesometoks\leftreferencetoks\onlynonbreakablespace\relax % new, replace space by nonbreakable if present
\currentreferencecontent
\rightofreference
\doifelsesometoks\rightreferencetoks\rightofreferencecontent\donothing
@@ -1242,15 +1201,6 @@
\setvalue{\??referencinginteraction\v!symbol}%
{\referencesymbol}
-% \def\referencesequence
-% {\csname\??referencinginteraction
-% \ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname
-% \referencingparameter\c!interaction
-% \else
-% \v!all
-% \fi
-% \endcsname}
-
\def\referencesequence
{\ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname
\expandafter\lastnamedcs
@@ -1311,9 +1261,8 @@
%D \macros
%D {definereferenceformat}
%D
-%D The next few macros were made for for David Arnold and Taco
-%D Hoekwater. They can be used for predefining reference
-%D texts, and thereby stimulate efficiency.
+%D The next few macros were made for for David Arnold and Taco Hoekwater. They can
+%D be used for predefining reference texts, and thereby stimulate efficiency.
%D
%D \starttyping
%D \definereferenceformat[informula] [left=(,right=),text=formula]
@@ -1328,11 +1277,11 @@
%D the \informulas [b] \andformula [for:c]
%D \stoptyping
%D
-%D Instead of a text, one can specify a label, which should
-%D be defined with \type {\setuplabeltext}.
+%D Instead of a text, one can specify a label, which should be defined with \type
+%D {\setuplabeltext}.
%D
-%D Watch out: the second argument is somewhat special and mostly
-%D meant for a suffix to a number:
+%D Watch out: the second argument is somewhat special and mostly meant for a suffix
+%D to a number:
%D
%D \startbuffer
%D \definereferenceformat [intesta] [left=(,right=),text=Whatever~]
@@ -1437,21 +1386,18 @@
%
% \definereferenceformat[hellup][text=Hellup ,setups=referenceformat:numberplustext]
-%D In interactive documents going to a specific location is not
-%D bound to cross references. The \type{\goto} commands can be
-%D used to let users access another part of the document. In
-%D this respect, interactive tables of contents and registers
-%D can be considered goto's. Because in fact a \type{\goto} is
-%D just a reference without reference specific data, the
-%D previous macros are implemented using the goto
-%D functionality.
+%D In interactive documents going to a specific location is not bound to cross
+%D references. The \type {\goto} commands can be used to let users access another
+%D part of the document. In this respect, interactive tables of contents and
+%D registers can be considered goto's. Because in fact a \type {\goto} is just a
+%D reference without reference specific data, the previous macros are implemented
+%D using the goto functionality.
%D
%D \showsetup{goto}
%D
-%D One important characteristic is that the first argument of
-%D \type{\goto} (and therefore \type{\at} and \type{\in} is
-%D split at spaces. This means that, although hyphenation is
-%D prevented, long references can cross line endings.
+%D One important characteristic is that the first argument of \type {\goto} (and
+%D therefore \type {\at} and \type {\in} is split at spaces. This means that,
+%D although hyphenation is prevented, long references can cross line endings.
% \starttext
% \setupinteraction[state=start]
@@ -1740,21 +1686,19 @@
\clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
{\clf_injectcurrentreference
\global\lastsavedreferenceattribute\lastreferenceattribute
- \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}
+ \hpack attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}
{\box\scratchbox}%
\endgroup}
-%D An reference to another document can be specified as a file
-%D or as an \URL. Both are handled by the same mechanism and
-%D can be issued by saying something like:
+%D An reference to another document can be specified as a file or as an \URL. Both
+%D are handled by the same mechanism and can be issued by saying something like:
%D
%D \starttyping
%D \goto[dictionary::the letter a]
%D \stoptyping
%D
-%D One can imagine that many references to such a dictionary
-%D are made, so in most cases such a document reference in an
-%D indirect one.
+%D One can imagine that many references to such a dictionary are made, so in most
+%D cases such a document reference in an indirect one.
%D
%D \showsetup{useexternaldocument}
%D
@@ -1766,8 +1710,8 @@
%D [The Famous English Dictionary]
%D \stoptyping
%D
-%D The next macro implements these relations, and also take
-%D care of loading the document specific references.
+%D The next macro implements these relations, and also take care of loading the
+%D document specific references.
%D
%D The \URL\ alternative takes four arguments:
%D
@@ -1789,9 +1733,8 @@
%D \useURL [id] [url]
%D \stoptyping
%D
-%D This time we don't load the references when no file is
-%D specified. This is logical when one keeps in mind that a
-%D valid \URL\ can also be a mail address.
+%D This time we don't load the references when no file is specified. This is logical
+%D when one keeps in mind that a valid \URL\ can also be a mail address.
\unexpanded\def\useurl {\doquadrupleempty\strc_references_use_url } % so that they can be used in expanded arguments
\unexpanded\def\usefile{\dotripleargument\strc_references_use_file} % so that they can be used in expanded arguments
@@ -1814,8 +1757,7 @@
%D \macros
%D {url,setupurl}
%D
-%D We also have: \type{\url} for directly calling the
-%D description. So we can say:
+%D We also have: \type {\url} for directly calling the description. So we can say:
%D
%D \starttyping
%D \useURL [one] [http://www.test.nl]
@@ -1843,8 +1785,8 @@
\hyphenatedurl{\clf_geturl{#label}}%
\endgroup}
-%D This macro is hooked into a support macro, and thereby
-%D \URL's break ok, according to the setting of a switch,
+%D This macro is hooked into a support macro, and thereby \URL's break ok, according
+%D to the setting of a switch,
%D
%D \startbuffer
%D \useURL
@@ -1858,9 +1800,8 @@
%D
%D \getbuffer
-%D When defining the external source of information, one can
-%D also specify a suitable name (the last argument). This name
-%D can be called upon with:
+%D When defining the external source of information, one can also specify a suitable
+%D name (the last argument). This name can be called upon with:
%D
%D \showsetup{from}
%D
@@ -1895,9 +1836,8 @@
%D \goto{some text}[identifier::location]
%D \stoptyping
-%D A special case of references are those to programs. These,
-%D very system dependant references are implemented by abusing
-%D some of the previous macros.
+%D A special case of references are those to programs. These, very system dependant
+%D references are implemented by abusing some of the previous macros.
%D
%D \showsetup{setupprograms}
%D \showsetup{defineprogram}
@@ -1918,15 +1858,14 @@
\def\strc_references_define_program[#name][#program][#description]%
{\clf_defineprogram{#name}{#program}{#description}}
-\def\program[#name]% incompatible, more consistent, hardy used anyway
+\unexpanded\def\program[#name]% incompatible, more consistent, hardy used anyway
{\dontleavehmode
\begingroup
\useprogramsstyleandcolor\c!style\c!color
\clf_getprogram{#name}%
\endgroup}
-%D As we can see, we directly use the special reference
-%D mechanism, which means that
+%D As we can see, we directly use the special reference mechanism, which means that
%D
%D \starttyping
%D \goto{some text}[program(name{args})]
@@ -1934,11 +1873,10 @@
%D
%D is valid.
-%D The next macro provides access to the actual pagenumbers.
-%D When documenting and sanitizing the original reference
-%D macros, I decided to keep the present meaning as well as to
-%D make this meaning available as a special reference method.
-%D So now one can use:
+%D The next macro provides access to the actual pagenumbers. When documenting and
+%D sanitizing the original reference macros, I decided to keep the present meaning
+%D as well as to make this meaning available as a special reference method. So now
+%D one can use:
%D
%D \starttyping
%D \gotopage{some text}[location]
@@ -1967,8 +1905,7 @@
\def\gotopage#text[#target]%
{\goto{#text}[\v!page(#target)]}
-%D The previous definitions are somewhat obsolete so we don't
-%D use it here.
+%D The previous definitions are somewhat obsolete so we don't use it here.
%D We can cross link documents by using:
%D
@@ -1980,16 +1917,14 @@
%D \coupledocument[print][somefile][chapter,section]
%D \stoptyping
%D
-%D After which when applicable, we have available the
-%D references:
+%D After which when applicable, we have available the references:
%D
%D \starttyping
%D \goto{print version}[print::chapter]
%D \stoptyping
%D
-%D and alike. The title placement definition macros have a
-%D key \type{file}, which is interpreted as the file to jump
-%D to, that is, when one clicks on the title.
+%D and alike. The title placement definition macros have a key \type {file}, which
+%D is interpreted as the file to jump to, that is, when one clicks on the title.
\def\coupledocument
{\doquadrupleempty\strc_references_couple_document}
@@ -2002,8 +1937,8 @@
%D \macros
%D {dotextprefix}
%D
-%D In previous macros we used \type {\dotextprefix} to
-%D generate a space between a label and a number.
+%D In previous macros we used \type {\dotextprefix} to generate a space between
+%D a label and a number.
%D
%D \starttyping
%D \dotextprefix{text}
@@ -2026,9 +1961,8 @@
\fi
\endgroup}
-%D In the next settings we see some variables that were not
-%D used here and that concern the way the pagenumbers refered
-%D to are typeset.
+%D In the next settings we see some variables that were not used here and that
+%D concern the way the pagenumbers refered to are typeset.
\setupreferencing
[\c!state=\v!start,
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-reg.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-reg.lua
index 2c667fba3cc..47ba1c5338b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-reg.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-reg.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['strc-reg'] = {
}
local next, type, tonumber = next, type, tonumber
-local format, gmatch = string.format, string.gmatch
+local char, format, gmatch = string.char, string.format, string.gmatch
local equal, concat, remove = table.are_equal, table.concat, table.remove
local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct
local allocate = utilities.storage.allocate
@@ -38,6 +38,7 @@ local texgetcount = tex.getcount
local variables = interfaces.variables
local v_forward = variables.forward
local v_all = variables.all
+local v_no = variables.no
local v_yes = variables.yes
local v_packed = variables.packed
local v_current = variables.current
@@ -47,7 +48,7 @@ local v_last = variables.last
local v_text = variables.text
local context = context
-local commands = commands
+local ctx_latelua = context.latelua
local implement = interfaces.implement
@@ -81,10 +82,12 @@ local ctx_startregisterpages = context.startregisterpages
local ctx_stopregisterpages = context.stopregisterpages
local ctx_startregisterseewords = context.startregisterseewords
local ctx_stopregisterseewords = context.stopregisterseewords
+
local ctx_registerentry = context.registerentry
local ctx_registerseeword = context.registerseeword
local ctx_registerpagerange = context.registerpagerange
local ctx_registeronepage = context.registeronepage
+
local ctx_registerpacked = context.registerpacked
-- possible export, but ugly code (overloads)
@@ -452,23 +455,6 @@ local tagged = { }
local function preprocessentries(rawdata)
local entries = rawdata.entries
if entries then
- --
- -- local e = entries[1] or ""
- -- local k = entries[2] or ""
- -- local et, kt, entryproc, pageproc
- -- if type(e) == "table" then
- -- et = e
- -- else
- -- entryproc, e = splitprocessor(e)
- -- et = lpegmatch(entrysplitter,e)
- -- end
- -- if type(k) == "table" then
- -- kt = k
- -- else
- -- pageproc, k = splitprocessor(k)
- -- kt = lpegmatch(entrysplitter,k)
- -- end
- --
local processors = rawdata.processors
local et = entries.entries
local kt = entries.keys
@@ -533,6 +519,7 @@ local function storeregister(rawdata) -- metadata, references, entries
metadata.kind = "entry"
end
--
+ --
if not metadata.catcodes then
metadata.catcodes = tex.catcodetable -- get
end
@@ -581,17 +568,20 @@ local function storeregister(rawdata) -- metadata, references, entries
return #entries
end
-registers.store = storeregister
-
-function registers.enhance(name,n)
- local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name]
+local function enhanceregister(specification)
+ local name = specification.name
+ local n = specification.n
+ local saved = tobesaved[name]
+ local data = saved.metadata.notsaved and collected[name] or saved
local entry = data.entries[n]
if entry then
entry.references.realpage = texgetcount("realpageno")
end
end
-function registers.extend(name,tag,rawdata) -- maybe do lastsection internally
+-- This can become extendregister(specification)!
+
+local function extendregister(name,tag,rawdata) -- maybe do lastsection internally
if type(tag) == "string" then
tag = tagged[tag]
end
@@ -635,6 +625,10 @@ function registers.extend(name,tag,rawdata) -- maybe do lastsection internally
end
end
+registers.store = storeregister
+registers.enhance = enhanceregister
+registers.extend = extendregister
+
function registers.get(tag,n)
local list = tobesaved[tag]
return list and list.entries[n]
@@ -642,13 +636,24 @@ end
implement {
name = "enhanceregister",
- actions = registers.enhance,
arguments = { "string", "integer" },
+ actions = function(name,n)
+ enhanceregister { name = name, n = n } -- todo: move to scanner
+ end,
+}
+
+implement {
+ name = "deferredenhanceregister",
+ arguments = { "string", "integer" },
+ protected = true,
+ actions = function(name,n)
+ ctx_latelua { action = enhanceregister, name = name, n = n }
+ end,
}
implement {
name = "extendregister",
- actions = registers.extend,
+ actions = extendregister,
arguments = "2 strings",
}
@@ -714,7 +719,8 @@ function registers.compare(a,b)
local ka = a.metadata.kind
local kb = b.metadata.kind
if ka == kb then
- local page_a, page_b = a.references.realpage, b.references.realpage
+ local page_a = a.references.realpage
+ local page_b = b.references.realpage
if not page_a or not page_b then
return 0
elseif page_a < page_b then
@@ -739,7 +745,7 @@ local seeindex = 0
-- meerdere loops, seewords, dan words, anders seewords
-local function crosslinkseewords(result) -- all words
+local function crosslinkseewords(result,check) -- all words
-- collect all seewords
local seewords = { }
for i=1,#result do
@@ -783,24 +789,17 @@ local function crosslinkseewords(result) -- all words
local seeparent = seeparents[text]
if seeparent then
local seeindex = seewords[text]
- local s, ns, d, w, l = { }, 0, data.split, seeparent.split, data.list
- -- trick: we influence sorting by adding fake subentries
- for i=1,#d do
- ns = ns + 1
- s[ns] = d[i] -- parent
- end
- for i=1,#w do
- ns = ns + 1
- s[ns] = w[i] -- see
- end
- data.split = s
- -- we also register a fake extra list entry so that the
- -- collapser works okay
- l[#l+1] = { text, "" }
data.references.seeindex = seeindex
if trace_registers then
report_registers("see crosslink %03i: %s",seeindex,text)
end
+ seeword.valid = true
+ elseif check then
+ report_registers("invalid crosslink : %s, %s",text,"ignored")
+ seeword.valid = false
+ else
+ report_registers("invalid crosslink : %s, %s",text,"passed")
+ seeword.valid = true
end
end
end
@@ -824,17 +823,22 @@ local function removeemptyentries(result)
end
end
-function registers.prepare(data)
+function registers.prepare(data,options)
-- data has 'list' table
local strip = sorters.strip
local splitter = sorters.splitters.utf
local result = data.result
if result then
+ local seeprefix = char(0)
for i=1, #result do
local entry = result[i]
local split = { }
local list = entry.list
if list then
+ if entry.seeword then
+ -- we can have multiple seewords, only two levels supported
+ list[#list+1] = { seeprefix .. strip(entry.seeword.text) }
+ end
for l=1,#list do
local ll = list[l]
local word = ll[1]
@@ -848,7 +852,7 @@ function registers.prepare(data)
entry.split = split
end
removeemptyentries(result)
- crosslinkseewords(result)
+ crosslinkseewords(result,options.check ~= v_no)
end
end
@@ -861,7 +865,9 @@ function registers.sort(data,options)
end
function registers.unique(data,options)
- local result, nofresult, prev = { }, 0, nil
+ local result = { }
+ local nofresult = 0
+ local prev = nil
local dataresult = data.result
for k=1,#dataresult do
local v = dataresult[k]
@@ -873,7 +879,8 @@ function registers.unique(data,options)
elseif pr.realpage ~= vr.realpage then
-- ok
else
- local pl, vl = pr.lastrealpage, vr.lastrealpage
+ local pl = pr.lastrealpage
+ local vl = vr.lastrealpage
if pl or vl then
if not vl then
-- ok
@@ -901,7 +908,11 @@ end
function registers.finalize(data,options) -- maps character to index (order)
local result = data.result
data.metadata.nofsorted = #result
- local split, nofsplit, lasttag, done, nofdone = { }, 0, nil, nil, 0
+ local split = { }
+ local nofsplit = 0
+ local lasttag = nil
+ local done = nil
+ local nofdone = 0
local firstofsplit = sorters.firstofsplit
for k=1,#result do
local v = result[k]
@@ -922,8 +933,46 @@ function registers.finalize(data,options) -- maps character to index (order)
data.result = split
end
+-- local function analyzeregister(class,options)
+-- local data = collected[class]
+-- if data and data.entries then
+-- options = options or { }
+-- sorters.setlanguage(options.language,options.method,options.numberorder)
+-- registers.filter(data,options) -- filter entries into results (criteria)
+-- registers.prepare(data,options) -- adds split table parallel to list table
+-- registers.sort(data,options) -- sorts results
+-- registers.unique(data,options) -- get rid of duplicates
+-- registers.finalize(data,options) -- split result in ranges
+-- data.metadata.sorted = true
+-- return data.metadata.nofsorted or 0
+-- else
+-- return 0
+-- end
+-- end
+
local function analyzeregister(class,options)
- local data = collected[class]
+ local data = rawget(collected,class)
+ if not data then
+ local list = utilities.parsers.settings_to_array(class)
+ local entries = { }
+ local metadata = false
+ for i=1,#list do
+ local l = list[i]
+ local d = collected[l]
+ local e = d.entries
+ for i=1,#e do
+ entries[#entries+1] = e[i]
+ end
+ if not metadata then
+ metadata = d.metadata
+ end
+ end
+ data = {
+ metadata = metadata or { },
+ entries = entries,
+ }
+ collected[class] = data
+ end
if data and data.entries then
options = options or { }
sorters.setlanguage(options.language,options.method,options.numberorder)
@@ -973,8 +1022,10 @@ implement {
-- todo: ownnumber
local function pagerange(f_entry,t_entry,is_last,prefixspec,pagespec)
- local fer, ter = f_entry.references, t_entry.references
+ local fer = f_entry.references
+ local ter = t_entry.references
ctx_registerpagerange(
+ f_entry.metadata.name or "",
f_entry.processors and f_entry.processors[2] or "",
fer.internal or 0,
fer.realpage or 0,
@@ -996,6 +1047,7 @@ end
local function pagenumber(entry,prefixspec,pagespec)
local er = entry.references
ctx_registeronepage(
+ entry.metadata.name or "",
entry.processors and entry.processors[2] or "",
er.internal or 0,
er.realpage or 0,
@@ -1004,7 +1056,8 @@ local function pagenumber(entry,prefixspec,pagespec)
end
local function packed(f_entry,t_entry)
- local fer, ter = f_entry.references, t_entry.references
+ local fer = f_entry.references
+ local ter = t_entry.references
ctx_registerpacked(
fer.internal or 0,
ter.internal or 0
@@ -1013,8 +1066,12 @@ end
local function collapsedpage(pages)
for i=2,#pages do
- local first, second = pages[i-1], pages[i]
- local first_first, first_last, second_first, second_last = first[1], first[2], second[1], second[2]
+ local first = pages[i-1]
+ local second = pages[i]
+ local first_first = first[1]
+ local first_last = first[2]
+ local second_first = second[1]
+ local second_last = second[2]
local first_last_pn = first_last .references.realpage
local second_first_pn = second_first.references.realpage
local second_last_pn = second_last .references.realpage
@@ -1110,7 +1167,8 @@ function registers.flush(data,options,prefixspec,pagespec)
done[i] = false
end
local data = sublist.data
- local d, n = 0, 0
+ local d = 0
+ local n = 0
ctx_startregistersection(sublist.tag)
for d=1,#data do
local entry = data[d]
@@ -1126,6 +1184,7 @@ function registers.flush(data,options,prefixspec,pagespec)
end
-- ok, this is tricky: we use e[i] delayed so we need it to be local
-- but we don't want to allocate too many entries so there we go
+
while d < #data do
d = d + 1
local entry = data[d]
@@ -1164,8 +1223,8 @@ function registers.flush(data,options,prefixspec,pagespec)
started = false
end
if n == i then
--- ctx_stopregisterentries()
--- ctx_startregisterentries(n)
+ -- ctx_stopregisterentries()
+ -- ctx_startregisterentries(n)
else
while n > i do
n = n - 1
@@ -1186,127 +1245,131 @@ function registers.flush(data,options,prefixspec,pagespec)
ctx_startregisterentry(0) -- will become a counter
started = true
if metadata then
- ctx_registerentry(processor,internal,seeparent,function() h_title(e[i],metadata) end)
+ ctx_registerentry(metadata.name or "",processor,internal,seeparent,function() h_title(e[i],metadata) end)
else
-- can this happen?
- ctx_registerentry(processor,internal,seeindex,e[i])
+ ctx_registerentry("",processor,internal,seeindex,e[i])
end
end
end
- if kind == 'entry' then
- if show_page_number then
- ctx_startregisterpages()
- if collapse_singles or collapse_ranges then
- -- we collapse ranges and keep existing ranges as they are
- -- so we get prebuilt as well as built ranges
- local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0
- while dd < #data do
- dd = dd + 1
- local next = data[dd]
- if next and next.metadata.kind == "see" then
- dd = dd - 1
- break
- else
- local el, nl = entry.list, next.list
- if not equal(el,nl) then
- dd = dd - 1
- --~ first = nil
- break
- elseif next.references.lastrealpage then
- nofpages = nofpages + 1
- pages[nofpages] = first and { first, last or first } or { entry, entry }
- nofpages = nofpages + 1
- pages[nofpages] = { next, next }
- first, last, prev = nil, nil, nil
- elseif not first then
- first, prev = next, next
- elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ?
- last, prev = next, next
- else
- nofpages = nofpages + 1
- pages[nofpages] = { first, last or first }
- first, last, prev = next, nil, next
- end
- end
- end
- if first then
+
+ local function case_1()
+ -- we collapse ranges and keep existing ranges as they are
+ -- so we get prebuilt as well as built ranges
+ local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0
+ while dd < #data do
+ dd = dd + 1
+ local next = data[dd]
+ if next and next.metadata.kind == "see" then
+ dd = dd - 1
+ break
+ else
+ local el, nl = entry.list, next.list
+ if not equal(el,nl) then
+ dd = dd - 1
+ --~ first = nil
+ break
+ elseif next.references.lastrealpage then
+ nofpages = nofpages + 1
+ pages[nofpages] = first and { first, last or first } or { entry, entry }
+ nofpages = nofpages + 1
+ pages[nofpages] = { next, next }
+ first, last, prev = nil, nil, nil
+ elseif not first then
+ first, prev = next, next
+ elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ?
+ last, prev = next, next
+ else
nofpages = nofpages + 1
pages[nofpages] = { first, last or first }
+ first, last, prev = next, nil, next
end
- if collapse_ranges and nofpages > 1 then
- nofpages = collapsepages(pages)
- end
- if nofpages > 0 then -- or 0
- d = dd
- for p=1,nofpages do
- local first, last = pages[p][1], pages[p][2]
- if first == last then
- if first.references.lastrealpage then
- pagerange(first,first,true,prefixspec,pagespec)
- else
- pagenumber(first,prefixspec,pagespec)
- end
- elseif last.references.lastrealpage then
- pagerange(first,last,true,prefixspec,pagespec)
- else
- pagerange(first,last,false,prefixspec,pagespec)
- end
+ end
+ end
+ if first then
+ nofpages = nofpages + 1
+ pages[nofpages] = { first, last or first }
+ end
+ if collapse_ranges and nofpages > 1 then
+ nofpages = collapsepages(pages)
+ end
+ if nofpages > 0 then -- or 0
+ d = dd
+ for p=1,nofpages do
+ local first, last = pages[p][1], pages[p][2]
+ if first == last then
+ if first.references.lastrealpage then
+ pagerange(first,first,true,prefixspec,pagespec)
+ else
+ pagenumber(first,prefixspec,pagespec)
end
- elseif entry.references.lastrealpage then
- pagerange(entry,entry,true,prefixspec,pagespec)
+ elseif last.references.lastrealpage then
+ pagerange(first,last,true,prefixspec,pagespec)
else
- pagenumber(entry,prefixspec,pagespec)
+ pagerange(first,last,false,prefixspec,pagespec)
end
- elseif collapse_packed then
- local first = nil
- local last = nil
- while true do
- if not first then
- first = entry
- end
- last = entry
- if d == #data then
- break
- else
- d = d + 1
- local next = data[d]
- if next.metadata.kind == "see" or not equal(entry.list,next.list) then
- d = d - 1
- break
- else
- entry = next
- end
- end
+ end
+ elseif entry.references.lastrealpage then
+ pagerange(entry,entry,true,prefixspec,pagespec)
+ else
+ pagenumber(entry,prefixspec,pagespec)
+ end
+ end
+
+ local function case_2()
+ local first = nil
+ local last = nil
+ while true do
+ if not first then
+ first = entry
+ end
+ last = entry
+ if d == #data then
+ break
+ else
+ d = d + 1
+ local next = data[d]
+ if next.metadata.kind == "see" or not equal(entry.list,next.list) then
+ d = d - 1
+ break
+ else
+ entry = next
end
- packed(first,last) -- returns internals
+ end
+ end
+ packed(first,last) -- returns internals
+ end
+
+ local function case_3()
+ while true do
+ if entry.references.lastrealpage then
+ pagerange(entry,entry,true,prefixspec,pagespec)
else
- while true do
- if entry.references.lastrealpage then
- pagerange(entry,entry,true,prefixspec,pagespec)
- else
- pagenumber(entry,prefixspec,pagespec)
- end
- if d == #data then
- break
- else
- d = d + 1
- local next = data[d]
- if next.metadata.kind == "see" or not equal(entry.list,next.list) then
- d = d - 1
- break
- else
- entry = next
- end
- end
+ pagenumber(entry,prefixspec,pagespec)
+ end
+ if d == #data then
+ break
+ else
+ d = d + 1
+ local next = data[d]
+ if next.metadata.kind == "see" or not equal(entry.list,next.list) then
+ d = d - 1
+ break
+ else
+ entry = next
end
end
- ctx_stopregisterpages()
end
- elseif kind == 'see' then
- local t, nt = { }, 0
+ end
+
+ local function case_4()
+ local t = { }
+ local nt = 0
while true do
- nt = nt + 1
- t[nt] = entry
+ if entry.seeword and entry.seeword.valid then
+ nt = nt + 1
+ t[nt] = entry
+ end
if d == #data then
break
else
@@ -1320,19 +1383,36 @@ function registers.flush(data,options,prefixspec,pagespec)
end
end
end
- ctx_startregisterseewords()
for i=1,nt do
- local entry = t[i]
+ local entry = t[i]
local seeword = entry.seeword
local seetext = seeword.text or ""
local processor = seeword.processor or (entry.processors and entry.processors[1]) or ""
local seeindex = entry.references.seeindex or ""
- -- ctx_registerseeword(i,nt,processor,0,seeindex,seetext)
- ctx_registerseeword(i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end)
+ ctx_registerseeword(metadata.name or "",i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end)
end
+ end
+
+ if kind == "entry" then
+ if show_page_number then
+ ctx_startregisterpages()
+ if collapse_singles or collapse_ranges then
+ case_1()
+ elseif collapse_packed then
+ case_2()
+ else
+ case_3()
+ end
+ ctx_stopregisterpages()
+ end
+ elseif kind == "see" then
+ ctx_startregisterseewords()
+ case_4()
ctx_stopregisterseewords()
end
+
end
+
if started then
ctx_stopregisterentry()
started = false
@@ -1373,6 +1453,7 @@ implement {
{ "numberorder" },
{ "compress" },
{ "criterium" },
+ { "check" },
{ "pagenumber", "boolean" },
},
{
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-reg.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-reg.mkiv
index 04fdef9adc2..559e1bd4231 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-reg.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-reg.mkiv
@@ -83,6 +83,7 @@
\c!pagestyle=\v!slanted,
\c!indicator=\v!yes,
\c!criterium=\v!all,
+ \c!check=\v!yes, % check for weird see usage
%\c!command=,
\c!referencing=\v!on,
\c!location=\v!middle,
@@ -159,8 +160,8 @@
%D Registering:
-\global\let\currentregistername \empty
-\global\let\currentregisternumber\!!zerocount
+\glet\currentregistername \empty
+\glet\currentregisternumber\!!zerocount
\def\strc_registers_register_page_entry
{\iftrialtypesetting
@@ -175,33 +176,33 @@
\xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml}
+ \glet\currentregistercoding\s!xml}
\def\strc_registers_register_page_expand_yes_entries
{\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
\xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_nop_entries
{\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
\xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_xml
{\xmlstartraw
\xdef\currentregisterentries{\registerparameter\c!entries}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml}
+ \glet\currentregistercoding\s!xml}
\def\strc_registers_register_page_expand_yes
{\xdef\currentregisterentries{\registerparameter\c!entries}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_nop
{\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_xml_keys
{\xmlstartraw
@@ -304,7 +305,7 @@
\ifx\currentregisterownnumber\v!yes
\glet\currentregistersynchronize\relax
\else
- \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}%
+ \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
\fi
\currentregistersynchronize % here?
% needs thinking ... bla\index{bla}. will break before the . but adding a
@@ -340,7 +341,7 @@
% internal \locationcount
% view {\interactionparameter\c!focus}%
\relax % this will change
- \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}%
+ \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
\currentregistersynchronize % here?
\dostarttagged\t!registerlocation\currentregister
\attribute\destinationattribute\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
@@ -352,16 +353,46 @@
\unexpanded\def\strc_registers_insert_entry[#1][#2]%
{\def\currentregister{#1}%
- \doifelse{\registerparameter\c!ownnumber}\v!yes
- \strc_registers_insert_entry_yes
- \strc_registers_insert_entry_nop
- {#2}}
+ \edef\p_ownnumber{\registerparameter\c!ownnumber}%
+ \ifx\p_ownnumber\v!yes
+ \expandafter\strc_registers_insert_entry_yes
+ \else
+ \expandafter\strc_registers_insert_entry_nop
+ \fi{#2}}
+
+% \def\strc_registers_insert_entry_nop#1#2%
+% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
+%
+% \def\strc_registers_insert_entry_yes#1#2#3%
+% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
+%
+% less tokens passed (nicer for tracing) .. could become installable
+
+\def\strc_registers_insert_entry_nop
+ {\ifvmode
+ \expandafter\strc_registers_insert_entry_nop_par
+ \else
+ \expandafter\strc_registers_insert_entry_nop_txt
+ \fi}
+
+\def\strc_registers_insert_entry_yes
+ {\ifvmode
+ \expandafter\strc_registers_insert_entry_yes_par
+ \else
+ \expandafter\strc_registers_insert_entry_yes_txt
+ \fi}
+
+\def\strc_registers_insert_entry_nop_par#1#2%
+ {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
-\def\strc_registers_insert_entry_nop#1#2%
- {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
+\def\strc_registers_insert_entry_yes_par#1#2#3%
+ {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
-\def\strc_registers_insert_entry_yes#1#2#3%
- {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
+\def\strc_registers_insert_entry_nop_txt#1#2%
+ {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}
+
+\def\strc_registers_insert_entry_yes_txt#1#2#3%
+ {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}
\unexpanded\def\startregister{\doquadrupleempty\strc_registers_start_entry}
\unexpanded\def\stopregister {\dodoubleargument\strc_registers_stop_entry}
@@ -403,14 +434,14 @@
\xmlstartraw
\xdef\currentregisterentries{\registerparameter\c!entries}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \glet\currentregistercoding\s!xml
\else
\ifx\currentregisterexpansion\v!yes
\xdef\currentregisterentries{\registerparameter\c!entries}%
\else
\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
\fi
- \globallet\currentregistercoding\s!tex
+ \glet\currentregistercoding\s!tex
\fi
% I hate this kind of mess ... but it's a user request.
\ifx\currentregisterentries\empty
@@ -493,7 +524,7 @@
\xdef\currentregisterentries{\detokenize{#3}}% not ok yet
\xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
\xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \glet\currentregistercoding\s!xml
\else
\ifx\currentregisterexpansion\v!yes
\xdef\currentregisterentries{#3}% not ok yet
@@ -502,7 +533,7 @@
\xdef\currentregisterentries{\detokenize{#3}}% not ok yet
\xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
\fi
- \globallet\currentregistercoding\s!tex
+ \glet\currentregistercoding\s!tex
\fi
\setnextinternalreference
% we could consider storing register entries in list
@@ -544,8 +575,8 @@
\def\strc_registers_determine_characteristics[#1][#2]%
{\begingroup
- \edef\currentregister{#1}%
- \setupregister[\currentregister][#2]%
+ \setupregister[#1][#2]%
+ \edef\currentregister{\firstinset{#1}}%
\normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\clf_analyzeregister
{\currentregister}%
{%
@@ -569,6 +600,8 @@
\dontcomplain
\to \everyplaceregister
+\newconditional\c_strc_registers_text_interaction
+
\unexpanded\def\placeregister
{\dodoubleempty\strc_registers_place}
@@ -576,30 +609,29 @@
{\iffirstargument
\begingroup
%\forgetall
- \edef\currentregister{#1}%
- \setupregister[\currentregister][#2]%
+ \setupregister[#1][#2]% can be a list
+ \edef\currentregister{\firstinset{#1}}%
\the\everyplaceregister
\ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone
\startmixedcolumns[\currentregister]
- \strc_registers_place_indeed
+ \strc_registers_place_indeed{#1}%
\stopmixedcolumns
\else
- \strc_registers_place_indeed
+ \strc_registers_place_indeed{#1}%
\fi
\endgroup
\fi}
-\newconditional\c_strc_registers_text_interaction
-
-\def\strc_registers_place_indeed
+\def\strc_registers_place_indeed#1%
{\doifelse{\registerparameter\c!interaction}\v!text
\settrue\setfalse\c_strc_registers_text_interaction
\clf_processregister
- {\currentregister}%
+ {#1}%
{%
language {\registerparameter\s!language}%
method {\registerparameter\c!method}%
numberorder {\registerparameter\c!numberorder}%
+ check {\registerparameter\c!check}%
compress {\registerparameter\c!compress}%
criterium {\registerparameter\c!criterium}%
pagenumber \ifx\registerpageseparatorsymbol\empty false\else true\fi
@@ -639,9 +671,9 @@
\def\strc_registers_complete[#1][#2]%
{\iffirstargument
\begingroup
- \edef\currentregister{#1}%
+ \edef\currentregister{\firstinset{#1}}%
\normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\currentregister}},reference=\currentregister]}%
- \placeregister[\currentregister][#2]%
+ \placeregister[#1][#2]%
\page[\v!yes]%
\stopnamedsection
\endgroup
@@ -835,15 +867,16 @@
\unexpanded\def\startregisterpages
{\begingroup
\dostarttagged\t!registerpages\empty
- \useregisterstyleandcolor\c!pagestyle\c!pagecolor}
+ \useregisterstyleandcolor\c!pagestyle\c!pagecolor
+ \registerparameter\c!pageleft}
\unexpanded\def\stopregisterpages
- {\dostoptagged
+ {\registerparameter\c!pageright
+ \dostoptagged
\endgroup}
\unexpanded\def\startregisterseewords
- {%\par % \ifhmode\crlf\fi % otherwise wrong level
- \begingroup
+ {\begingroup
\dostarttagged\t!registerpage\empty
\useregisterstyleandcolor\c!pagestyle\c!pagecolor}
@@ -876,46 +909,69 @@
% \fi}
\unexpanded\def\withregisterpagecommand#1#2#3#4%
- {\def\currentregisterpageindex{#2}%
- \iflocation
- \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
+ {\ifcase#3\relax
+ {\tt [entry\space not\space flushed]}%
\else
- \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
+ \def\currentregisterpageindex{#2}%
+ \iflocation
+ \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
+ \else
+ \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
+ \fi
\fi}
-\unexpanded\def\registeronepage#1#2#3#4% #1:processor content
- {\registerpageseparator
- \global\setconstant\c_strc_registers_page_state\plusone
- \dostarttagged\t!registerpage\empty
- \withregisterpagecommand{#1}{#2}{#3}{#4}%
- \dostoptagged}
-
-\unexpanded\def\registerpagerange#1#2#3#4#5#6#7% #1:processor content, content todo: -- configurable
- {\registerpageseparator
- \global\setconstant\c_strc_registers_page_state\plusone
- \dostarttagged\t!registerpagerange\empty
- \dostarttagged\t!registerfrompage\empty
- \withregisterpagecommand{#1}{#2}{#3}{#4}%
- \dostoptagged
- \registeronepagerangeseparator
- \dostarttagged\t!registertopage\empty
- \withregisterpagecommand{#1}{#5}{#6}{#7}%
- \dostoptagged
- \dostoptagged}
+\unexpanded\def\pushcurrentregister#1%
+ {\let\m_current_register\currentregister
+ \edef\currentregister{#1}}
+
+\unexpanded\def\popcurrentregister
+ {\let\currentregister\m_current_register}
+
+\unexpanded\def\registeronepage#1#2#3#4#5% #1:class #2:processor content
+ {\pushcurrentregister{#1}%
+ \edef\p_pagenumber{\registerparameter\c!pagenumber}%
+ \ifx\p_pagenumber\v!no\else
+ \registerpageseparator
+ \global\setconstant\c_strc_registers_page_state\plusone
+ \dostarttagged\t!registerpage\empty
+ \withregisterpagecommand{#2}{#3}{#4}{#5}%
+ \dostoptagged
+ \fi
+ \popcurrentregister}
+
+\unexpanded\def\registerpagerange#1#2#3#4#5#6#7#8% #1:class #2:processor content, content todo: -- configurable
+ {\pushcurrentregister{#1}%
+ \edef\p_pagenumber{\registerparameter\c!pagenumber}%
+ \ifx\p_pagenumber\v!no\else
+ \registerpageseparator
+ \global\setconstant\c_strc_registers_page_state\plusone
+ \dostarttagged\t!registerpagerange\empty
+ \dostarttagged\t!registerfrompage\empty
+ \withregisterpagecommand{#2}{#3}{#4}{#5}%
+ \dostoptagged
+ \registeronepagerangeseparator
+ \dostarttagged\t!registertopage\empty
+ \withregisterpagecommand{#2}{#6}{#7}{#8}%
+ \dostoptagged
+ \dostoptagged
+ \fi
+ \popcurrentregister}
-\unexpanded\def\defaultregisterentry#1#2#3#4% #1:processor #2:internal #3:seeindex #4:word
- {\def\currentregisterpageindex{#2}%
+\unexpanded\def\defaultregisterentry#1#2#3#4#5% #1:class #2:processor #3:internal #4:seeindex #5:word
+ {\pushcurrentregister{#1}%
+ \def\currentregisterpageindex{#3}%
\iflocation
- \def\currentregisterseeindex{#3}%
+ \def\currentregisterseeindex{#4}%
\ifconditional\c_strc_registers_text_interaction
- \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#1}{#4}}[internal(#2)]%
+ \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#2}{#5}}[internal(#3)]%
\else
- \doapplyregisterentrycommand{#1}{#4}%
+ \doapplyregisterentrycommand{#2}{#5}%
\fi
\else
\let\currentregisterseeindex\empty
- \doapplyregisterentrycommand{#1}{#4}%
- \fi}
+ \doapplyregisterentrycommand{#2}{#5}%
+ \fi
+ \popcurrentregister}
\unexpanded\def\doapplyregisterentrycommand#1#2% processor text
{\dostarttagged\t!registercontent\empty
@@ -935,25 +991,29 @@
\applyprocessor{#1}{#2}%
\fi\fi}
-\unexpanded\def\defaultregisterseeword#1#2#3#4#5#6% i n #3:processor #4:internal #5:seeindex #6:word
- {\registerpageseparator
+\unexpanded\def\defaultregisterseeword#1#2#3#4#5#6#7% class i n #3:processor #4:internal #5:seeindex #6:word
+ {\pushcurrentregister{#1}%
+ \ifnum#2=\plusone
+ \registerpageseparator
+ \fi
\global\setconstant\c_strc_registers_page_state\plustwo
- \def\currentregisterpageindex{#4}%
+ \def\currentregisterpageindex{#5}%
\dostarttagged\t!registersee\empty
\settrue\c_strc_registers_page_done
\iflocation
- \def\currentregisterseeindex{#5}%
+ \def\currentregisterseeindex{#6}%
\else
\let\currentregisterseeindex\empty
\fi
- \ifnum#1=\plusone
- \labeltexts\v!see{\doapplyregisterseecommand{#3}{#6}}%
- \else\ifnum#1=#2\relax
- \labeltexts\v!and{\doapplyregisterseecommand{#3}{#6}}%
+ \ifnum#2=\plusone
+ \labeltexts\v!see{\doapplyregisterseecommand{#4}{#7}}%
+ \else\ifnum#2=#3\relax
+ \labeltexts\v!and{\doapplyregisterseecommand{#4}{#7}}%
\else
- ,\space\doapplyregisterseecommand{#3}{#6}%
+ ,\space\doapplyregisterseecommand{#4}{#7}%
\fi\fi
- \dostoptagged}
+ \dostoptagged
+ \popcurrentregister}
\let\registerseeword \defaultregisterseeword
\let\registerentry \defaultregisterentry
@@ -993,18 +1053,18 @@
\setvalue{\??registersymbol\v!none}%
{\let\registerpageseparatorsymbol\empty
- \let\registeronepage \gobblefourarguments
- \let\registerpagerange \gobblesevenarguments}
+ \let\registeronepage \gobblefivearguments
+ \let\registerpagerange\gobbleeightarguments}
\setvalue{\??registersymbol 1}%
{\let\registerpageseparatorsymbol\space
- \def\registeronepage {\symbol[1]\gobblefourarguments}%
- \def\registerpagerange{\symbol[1]\gobblesevenarguments}}
+ \def\registeronepage {\symbol[1]\gobblefivearguments}%
+ \def\registerpagerange{\symbol[1]\gobbleeightarguments}}
\setvalue{\??registersymbol 2}%
{\let\registerpageseparatorsymbol\space
- \def\registeronepage {\registerpagebuttonsymbol\gobblefourarguments}%
- \def\registerpagerange{\registerpagebuttonsymbol\gobblesevenarguments}}
+ \def\registeronepage {\registerpagebuttonsymbol\gobblefivearguments}%
+ \def\registerpagerange{\registerpagebuttonsymbol\gobbleeightarguments}}
\unexpanded\def\setregisterpagerendering
{\doifelse{\registerparameter\c!pagenumber}\v!no
@@ -1016,8 +1076,8 @@
\csname\??registersymbol\currentregisterpagesymbol\endcsname
\else
\let\registerpageseparatorsymbol\space
- \def\registeronepage{\registerparameter\c!symbol\gobblefourarguments}%
- \def\registerpagerange{\registerparameter\c!symbol\gobblesevenarguments}%
+ \def\registeronepage {\registerparameter\c!symbol\gobblefivearguments}%
+ \def\registerpagerange{\registerparameter\c!symbol\gobbleeightarguments}%
\fi\fi}
\appendtoks
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-ren.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-ren.mkiv
index 89aa6f55a1a..01464ad8649 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-ren.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-ren.mkiv
@@ -120,7 +120,7 @@
\setheadmarking
\doresetstructureheadnumbercontent
\ifconditional\c_strc_sectioning_empty
- \setbox\b_strc_rendering_head\hbox \headreferenceattributes to \zeropoint{\strut}%
+ \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}%
\else
\docheckheadreference
\setbox\b_strc_rendering_head\hbox \headreferenceattributes
@@ -139,7 +139,7 @@
\dosetstructureheadnumbercontent
\doresetstructureheadnumbercontent
\ifconditional\c_strc_sectioning_empty
- \setbox\b_strc_rendering_head\hbox \headreferenceattributes to \zeropoint{\strut}%
+ \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}%
\else % = needed
\docheckheadreference
\setbox\b_strc_rendering_head\hbox \headreferenceattributes
@@ -151,7 +151,7 @@
\strc_rendering_stop_placement}
\unexpanded\def\strc_rendering_place_head_empty
- {\hbox\headreferenceattributes{\getheadsyncs}} % \hpack ?
+ {\hpack\headreferenceattributes{\getheadsyncs}}
%D \starttyping
%D \def\StretchedBox#1%
@@ -197,14 +197,13 @@
\def\strc_rendering_start_placement
{\bgroup
\setsystemmode\currenthead
- %
\strc_rendering_initialize_alternatives
\strc_rendering_initialize_dimensions
- %
\strc_rendering_initialize_line_state
\reseteverypar % needed indeed
\noindent % ipv \whitespace elders, na \forgetall !
\bgroup
+ \synctexpushline
\edef\p_aligntitle{\headparameter\c!aligntitle}%
\ifx\p_aligntitle\v!yes
\strc_rendering_initialize_hsize_local
@@ -325,7 +324,9 @@
% kind of special, we want to snap heads also according to local specs local
\setbox\b_strc_rendering_head\hbox
{\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax
- \box\b_strc_rendering_head}%
+ \box\b_strc_rendering_head
+ \getheadsyncs % a latelua why not in the box
+ }%
\ifgridsnapping
\applygridmethod
{\headparameter\c!grid}%
@@ -345,14 +346,14 @@
\nointerlineskip
\dosomebreak\nobreak
\fi
- \getheadsyncs
+% \getheadsyncs % a latelua why not in the box
\else
% somehow this goes ok even when we push in the margin probably because we gobble pars
% in the process of collecting index entries etc
\strut
\flushnotes % new, here since we're in par mode
\unhbox\b_strc_rendering_head
- \getheadsyncs
+ \getheadsyncs % a latelua
\ifconditional\headissomewhere
\strc_sectioning_stay_on_this_line % test case: alternative=margintext and \startparagraph ..
\else
@@ -370,6 +371,7 @@
\fi
\fi
\fi
+ \synctexpopline
\egroup
\egroup
\ifconditional\headisdisplay
@@ -528,8 +530,14 @@
\def\fakedheadnumber{\vphantom{0}} % needed for mathplus
+% \unexpanded\def\fakeheadnumbercontent
+% {\hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}}
+
\unexpanded\def\fakeheadnumbercontent
- {\hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}}
+ {\edef\p_hidenumber{\headparameter\c!hidenumber}%
+ \ifx\p_hidenumber\v!yes\else
+ \hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}%
+ \fi}
\unexpanded\def\strc_rendering_inject_number_and_text
{\edef\p_command{\headparameter\c!command}% assumes \unexpanded definition
@@ -777,18 +785,18 @@
\startsetups[\??headrenderings:\v!bottom]
\ifconditional\headshownumber
- \setbox0\hbox {
+ \setbox\scratchboxone\hbox {
\headnumbercontent
}
- \setbox2\vbox {
+ \setbox\scratchboxtwo\vbox {
\headsetupspacing
- \advance\hsize-\wd0\relax
+ \advance\hsize-\wd\scratchboxone\relax
\headtextcontent
}
\hbox {
- \box0
+ \box\scratchboxone
\hskip\headnumberdistance
- \box2
+ \box\scratchboxtwo
}
\else
\vbox {
@@ -806,18 +814,18 @@
\startsetups[\??headrenderings:\v!top]
\ifconditional\headshownumber
- \setbox0\hbox {
+ \setbox\scratchboxone\hbox {
\headnumbercontent
}
- \setbox2\vtop {
+ \setbox\scratchboxtwo\vtop {
\headsetupspacing
- \advance\hsize-\wd0\relax
+ \advance\hsize-\wd\scratchboxone\relax
\headtextcontent
}
\hbox {
- \box0
+ \box\scratchboxone
\hskip\headnumberdistance
- \box2
+ \box\scratchboxtwo
}
\else
\vtop{
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-sbe.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-sbe.mkiv
index 9f1d214cfda..005f03df3ae 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-sbe.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-sbe.mkiv
@@ -45,7 +45,7 @@
\def\strc_sectionblock_define[#1][#2][#3]% singular plural settings
{\strc_sectionblock_define_normal[#1][#3]%
- \expandafter\newif\csname if#2\endcsname % obsolete
+ %\expandafter\newif\csname if#2\endcsname % obsolete
\strc_sectionblock_set_environment{#1}\empty
\setuvalue{\e!start#2}{\startsectionblock[#1]}%
\setuvalue{\e!stop #2}{\stopsectionblock}}
@@ -98,7 +98,7 @@
\clf_pushsectionblock{#1}
bookmark {\sectionblockparameter\c!bookmark}%
\relax
- \csname #1true\endcsname % obsolete
+ %\csname #1true\endcsname % obsolete
\setsystemmode\currentsectionblock
\the\everybeforesectionblock\relax
\showmessage\m!structures1\currentsectionblock}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-sec.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-sec.mkiv
index 4e5115a7d36..4066a1f38c8 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-sec.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-sec.mkiv
@@ -35,6 +35,7 @@
\c!label=,
\c!coupling=,
\c!ownnumber=,
+ % \c!interaction=\v!list,
\c!sectionseparatorset=\s!default,
\c!sectionconversionset=\s!default,
\c!sectionstopper=,
@@ -53,6 +54,10 @@
\def\m_strc_references_prefix_yes{+}
\def\m_strc_references_prefix_nop{-}
+\let\currentstructurereferenceprefix\empty
+
+\installglobalmacrostack\currentstructurereferenceprefix
+
\def\strc_sectioning_set_reference_prefix
{\ifx\currentstructurereferenceprefix\empty
% nothing
@@ -64,7 +69,7 @@
\else
\setupglobalreferenceprefix[\currentstructurereferenceprefix]%
\fi\fi\fi
- \let\currentstructurereferenceprefix\referenceprefix}
+ \glet\currentstructurereferenceprefix\referenceprefix}
% why xdef ?
@@ -108,9 +113,10 @@
\def\strc_sectioning_autobookmark#1%
{\begingroup
+ % \settrialtypesetting
\the\everypreroll
\nodestostring\tempstring{#1}%
- \globallet\currentstructurebookmark\tempstring
+ \glet\currentstructurebookmark\tempstring
\endgroup}
% zeros:
@@ -150,9 +156,9 @@
\strc_sectioning_autobookmark\currentstructuretitle
\fi \fi \fi
\ifx\currentstructurelist\empty
- \globallet\currentstructurelist\currentstructuretitle
+ \glet\currentstructurelist\currentstructuretitle
\fi
- \globallet\currentstructurecoding\s!xml
+ \glet\currentstructurecoding\s!xml
\else
\ifx\currentstructureexpansion\v!yes
\xdef\currentstructuretitle {\structureparameter\c!title}%
@@ -179,9 +185,9 @@
\fi \fi
\fi
\ifx\currentstructurelist\empty
- \globallet\currentstructurelist\currentstructuretitle
+ \glet\currentstructurelist\currentstructuretitle
\fi
- \globallet\currentstructurecoding\s!tex
+ \glet\currentstructurecoding\s!tex
\fi
\setnextinternalreference
\storeinternalreference\currentstructurename{\the\locationcount}%
@@ -249,7 +255,7 @@
userdata {\detokenize{#3}}% will be converted to table at the lua end
\relax
\xdef\currentstructurelistnumber{\clf_currentsectiontolist}%
- % \currentstructuresynchronize has to be called someplace, since it introduces a node
+ % \currentstructuresynchronize has to be called someplace, since it introduces a node
\setstructuresynchronization\currentstructurelistnumber
\endgroup}
@@ -340,6 +346,9 @@
\installcommandhandler \??head {head} \??head
+\installmacrostack\currenthead
+\installmacrostack\currentheadparent
+
\setuphead [%
%\c!after=,
%\c!align=,
@@ -479,16 +488,18 @@
\to \everysetuphead
\unexpanded\def\doredefinehead#1#2% called at lua end
- {\pushmacro\currenthead
- \pushmacro\currentheadparent
+ {\push_macro_currenthead
+ \push_macro_currentheadparent
\edef\currenthead{#1}%
\edef\currentheadparent{#2}%
\the\everyredefinehead\relax
- \popmacro\currentheadparent
- \popmacro\currenthead}
+ \pop_macro_currentheadparent
+ \pop_macro_currenthead}
\let\currentnamedsection\empty
+\installmacrostack\currentnamedsection
+
\unexpanded\def\startnamedsection
{\dotripleempty\strc_sectioning_start_named_section}
@@ -577,7 +588,7 @@
\fi}
\def\strc_sectioning_setup_indeed[#1][#2][#3]%
- {\pushmacro\currenthead
+ {\push_macro_currenthead
\ifthirdargument
\edef\currenthead{#1#2}% % not used at any more in mkiv (sets now)
\setupcurrenthead[#3]%
@@ -585,7 +596,7 @@
\edef\currenthead{#1}%
\setupcurrenthead[#2]%
\fi
- \popmacro\currenthead}
+ \pop_macro_currenthead}
% we share the parameters as sections are roots of heads so eventually we can
% consider \definesection -> \definehead with one argument
@@ -638,7 +649,8 @@
{\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title --
\unexpanded\def\strc_sectioning_start_named_section[#1][#2][#3]% for the moment no grouping, too annoying with page breaks
- {\pushmacro\currentnamedsection
+ {\push_macro_currentnamedsection
+ \push_macro_currentstructurereferenceprefix
\edef\currentnamedsection{#1}%
\setfalse\currentstructureown
%\globalpushmacro\currenthead % this does not work out well
@@ -659,7 +671,8 @@
\headparameter\c!aftersection
\the\everyafterhead
\resetsystemmode\currenthead
- \popmacro\currentnamedsection} % new, also here now
+ \pop_macro_currentstructurereferenceprefix
+ \pop_macro_currentnamedsection} % new, also here now
\let\dostarthead\strc_sectioning_start % used at lua end
\let\dostophead \strc_sectioning_stop % used at lua end
@@ -755,15 +768,25 @@
\setfalse\headshownumber
\fi}
+% Beware, we do need some node for anchoring marks and normally a zwnj will
+% do but it interferes so we deal with it at the \LUA\ end.
+
\newtoks\everyheadsynchronization
+% \appendtoks
+% \currentstructuresynchronize
+% \to \everyheadsynchronization
+
+\let\currentstructuresynchronize\donothing
+
\appendtoks
\currentstructuresynchronize
+ \glet\currentstructuresynchronize\donothing
\to \everyheadsynchronization
\unexpanded\def\theheadsynchonization
- {\the\everyheadsynchronization
- \currentstructuresynchronize}
+ {% no, interferes: \signalcharacter
+ \the\everyheadsynchronization}
% BEWARE: \marking[section]{my text} does not work as we use list indices instead
% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)
@@ -802,6 +825,17 @@
\let\currentheadlevel \!!zerocount
\let\currentheadcounter \!!zerocount
+\let\strc_show_used\relax
+
+\installtextracker
+ {structures.showused}
+ {\let\strc_show_used\clf_showstructure}
+ {\let\strc_show_used\relax}
+
+\appendtoks
+ \strc_show_used
+\to \everystoptext
+
\unexpanded\def\placeheadtext {\dosingleempty\strc_sectioning_place_head_text } % use with care
\unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care
@@ -842,6 +876,9 @@
\ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi
+\newtoks\everybeforesectionheadhandle
+\newtoks\everyaftersectionheadhandle
+
\def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller)
{\xdef\currenthead {#1}%
\xdef\currentheadcoupling{\sectionheadcoupling\currenthead}%
@@ -855,7 +892,7 @@
\strc_sectioning_initialize_placement
\strc_sectioning_initialize_number
%
- \flushingcolumnfloatsfalse
+ \the\everybeforesectionheadhandle
%
% todo: also mark (for header)
%
@@ -941,7 +978,9 @@
\strc_sectioning_after_nop
\fi\fi
\fi
- \flushingcolumnfloatstrue
+ %
+ \the\everyaftersectionheadhandle
+ %
\setfalse\c_strc_sectioning_ignore_page
% ignorespaces prevents spaces creeping in when after=\dontleavehmode
\dostarttagged\t!sectioncontent\empty
@@ -983,8 +1022,8 @@
\unexpanded\def\strc_rendering_place_head_section % see hidden below
{\global\setbox\b_sectioning_delayed\hpack\bgroup
\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
- \hpack\headreferenceattributes{}%
- \currentstructuresynchronize
+ \hpack\headreferenceattributes{}% also does the mark
+ \theheadsynchonization
\egroup}
\unexpanded\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
@@ -994,7 +1033,7 @@
{\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax
\noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
\hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
- \currentstructuresynchronize}} % and it's a node anyway
+ \theheadsynchonization}} % and it's a node anyway
\def\synchronizehead #1{\csname\??hiddenheadsync#1\endcsname}
\def\theheadreferenceattributes#1{\csname\??hiddenheadattr#1\endcsname}
@@ -1003,6 +1042,26 @@
\unexpanded\def\placerawheadtext [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}}
\unexpanded\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}}
+\unexpanded\def\repeathead[#1]%
+ {\begingroup
+ \setupinteraction[\c!state=\v!stop]%
+ \def\currenthead{#1}
+ \strc_sectioning_initialize_placement
+ \strc_sectioning_initialize_number
+ \dostarttagged\t!sectioncaption\empty
+ \let\getheadsyncs \relax
+ \def\getheadtitle {\getmarking[#1]}
+ \def\getheadnumber{\getmarking[#1\v!number]}
+ \strc_sectioning_before_yes
+ \ifconditional\headshownumber
+ \strc_rendering_place_head_number_and_text
+ \else
+ \strc_rendering_place_head_text
+ \fi
+ \dostoptagged
+ \strc_sectioning_after_yes
+ \endgroup}
+
% \setuphead[chapter][placehead=hidden]
% \chapter {test}
%
@@ -1154,7 +1213,7 @@
\else
\strc_sectioning_check_layout
\fi
- \globallet\previoushead\currenthead}
+ \glet\previoushead\currenthead}
\def\strc_sectioning_handle_page_yes
{\ifconditional\c_strc_sectioning_ignore_page
@@ -1178,7 +1237,7 @@
\fi
\global\c_strc_sectioning_preceding_level\currentheadlevel
\fi
- \globallet\previoushead\currenthead}
+ \glet\previoushead\currenthead}
\unexpanded\def\strc_sectioning_prevent_page_break#1% see strc-con
{\ifconditional\c_strc_sectioning_auto_break
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-syn.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-syn.mkiv
index 1fb079f04a8..7f71e88f52f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-syn.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-syn.mkiv
@@ -114,14 +114,14 @@
\xmlstartraw
\xdef#2{#4}%
\xmlstopraw
- \globallet#3\s!xml
+ \glet#3\s!xml
\else
\ifx#1\v!yes
\xdef#2{#4}%
\else
\xdef#2{\detokenize{#4}}%
\fi
- \globallet#3\s!tex
+ \glet#3\s!tex
\fi}
%D We now use a simple list variant:
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua
index 649465a6ada..0453640ca00 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua
@@ -15,7 +15,6 @@ local type, next = type, next
local insert, remove, unpack, concat, merge = table.insert, table.remove, table.unpack, table.concat, table.merge
local find, topattern, format = string.find, string.topattern, string.format
local lpegmatch, P, S, C, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Cc
-local texattribute = tex.attribute
local allocate = utilities.storage.allocate
local settings_to_hash = utilities.parsers.settings_to_hash
local setmetatableindex = table.setmetatableindex
@@ -24,34 +23,44 @@ local trace_tags = false trackers.register("structures.tags", function(v) trace
local report_tags = logs.reporter("structure","tags")
-local attributes = attributes
-local structures = structures
-local implement = interfaces.implement
-
-local a_tagged = attributes.private('tagged')
-
-local unsetvalue = attributes.unsetvalue
-local codeinjections = backends.codeinjections
-
-local taglist = allocate() -- access by attribute
-local specifications = allocate() -- access by fulltag
-local labels = allocate()
-local stack = { }
-local chain = { }
-local ids = { }
-local enabled = false
-local tagcontext = { }
-local tagpatterns = { }
-local lasttags = { }
-local stacksize = 0
-local metadata = nil -- applied to the next element
-local documentdata = { }
-
-local tags = structures.tags
-tags.taglist = taglist -- can best be hidden
-tags.labels = labels
-tags.patterns = tagpatterns
-tags.specifications = specifications
+local attributes = attributes
+local structures = structures
+local implement = interfaces.implement
+
+local a_tagged = attributes.private('tagged')
+
+local unsetvalue = attributes.unsetvalue
+local codeinjections = backends.codeinjections
+
+local texgetattribute = tex.getattribute
+local texsetattribute = tex.setattribute
+
+local taglist = allocate() -- access by attribute
+local specifications = allocate() -- access by fulltag
+local labels = allocate()
+local stack = { }
+local chain = { }
+local ids = { }
+local enabled = false
+local tagcontext = { }
+local tagpatterns = { }
+local lasttags = { }
+local stacksize = 0
+local metadata = nil -- applied to the next element
+local documentdata = { }
+local extradata = false
+
+local tags = structures.tags
+tags.taglist = taglist -- can best be hidden
+tags.labels = labels
+tags.patterns = tagpatterns
+tags.specifications = specifications
+
+function tags.current()
+ if stacksize > 0 then
+ return stack[stacksize] -- maybe copy or proxy
+ end
+end
-- Tags are internally stored as:
--
@@ -126,6 +135,7 @@ local properties = allocate { -- todo: more "record = true" to improve forma
listcontent = { pdf = "P", nature = "mixed" },
listdata = { pdf = "P", nature = "mixed" },
listpage = { pdf = "Reference", nature = "mixed" },
+ listtext = { pdf = "Span", nature = "inline" },
delimitedblock = { pdf = "BlockQuote", nature = "display" },
delimited = { pdf = "Quote", nature = "inline" },
@@ -157,9 +167,11 @@ local properties = allocate { -- todo: more "record = true" to improve forma
subformula = { pdf = "Div", nature = "display" },
link = { pdf = "Link", nature = "inline" },
+ reference = { pdf = "Span", nature = "inline" },
margintextblock = { pdf = "Span", nature = "inline" },
margintext = { pdf = "Span", nature = "inline" },
+ marginanchor = { pdf = "Span", nature = "inline" },
math = { pdf = "Div", nature = "inline" }, -- no display
mn = { pdf = "Span", nature = "mixed" },
@@ -204,6 +216,14 @@ local properties = allocate { -- todo: more "record = true" to improve forma
combinationpair = { pdf = "Span", nature = "display" },
combinationcontent = { pdf = "Span", nature = "mixed" },
combinationcaption = { pdf = "Span", nature = "mixed" },
+
+ publications = { pdf = "Div", nature = "display" },
+ publication = { pdf = "Div", nature = "mixed" },
+ pubfld = { pdf = "Span", nature = "inline" },
+
+ block = { pdf = "Div", nature = "display" },
+ userdata = { pdf = "Div", nature = "display" },
+
}
tags.properties = properties
@@ -215,7 +235,7 @@ local patterns = setmetatableindex(function(t,tag)
end)
function tags.locatedtag(tag)
- local attribute = texattribute[a_tagged]
+ local attribute = texgetattribute(a_tagged)
if attribute >= 0 then
local specification = taglist[attribute]
if specification then
@@ -235,7 +255,7 @@ function tags.locatedtag(tag)
end
function structures.atlocation(str)
- local specification = taglist[texattribute[a_tagged]]
+ local specification = taglist[texgetattribute(a_tagged)]
if specification then
if list then
local taglist = specification.taglist
@@ -287,6 +307,20 @@ function tags.getmetadata()
return documentdata or { }
end
+function tags.registerextradata(name,serializer)
+ if type(serializer) == "function" then
+ if extradata then
+ extradata[name] = serializer
+ else
+ extradata = { [name] = serializer }
+ end
+ end
+end
+
+function tags.getextradata()
+ return extradata
+end
+
function tags.start(tag,specification)
if not enabled then
codeinjections.enabletags()
@@ -349,7 +383,7 @@ function tags.start(tag,specification)
specification.metadata = documentdata
end
--
- texattribute[a_tagged] = attribute
+ texsetattribute(a_tagged,attribute)
return attribute
end
@@ -364,7 +398,7 @@ function tags.restart(attribute)
taglist[attribute] = { taglist = { unpack(chain,1,stacksize) } }
end
stack[stacksize] = attribute
- texattribute[a_tagged] = attribute
+ texsetattribute(a_tagged,attribute)
return attribute
end
@@ -374,12 +408,12 @@ function tags.stop()
end
local t = stack[stacksize]
if not t then
- -- if trace_tags then
+ if trace_tags then
report_tags("ignoring end tag, previous chain: %s",stacksize > 0 and concat(chain," ",1,stacksize) or "none")
- -- end
+ end
t = unsetvalue
end
- texattribute[a_tagged] = t
+ texsetattribute(a_tagged,t)
return t
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-tag.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-tag.mkiv
index 2ee71d67c21..84e11a63235 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/strc-tag.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-tag.mkiv
@@ -107,6 +107,7 @@
\def\t!listcontent {listcontent} % P
\def\t!listdata {listdata} % P
\def\t!listpage {listpage} % Reference
+\def\t!listtext {listtext} % Span
\def\t!delimitedblock {delimited} % BlockQuote
\def\t!delimited {delimited} % Quote
@@ -136,9 +137,11 @@
\def\t!subformula {subformula} % Div
\def\t!link {link} % Link
+\def\t!reference {reference} % Span
\def\t!margintext {margintext} % Span
\def\t!margintextblock {margintextblock} % Div
+\def\t!marginanchor {marginanchor} % Span
% we might opt for verbose variants so this is experimental:
@@ -162,6 +165,13 @@
\def\t!combinationcontent {combinationcontent} % Span
\def\t!combinationcaption {combinationcaption} % Span
+\def\t!publications {publications} % Span
+\def\t!publication {publication} % Span
+\def\t!pubfld {pubfld} % Span
+
+\def\t!block {block} % Div
+\def\t!userdata {userdata} % Div
+
% \setuptaglabeltext
% [en]
% [\t!document=document]
@@ -180,42 +190,51 @@
\unexpanded\def\strc_tags_set_aspect_nop#1#2{}
\unexpanded\def\strc_tags_set_aspect_yes#1#2{\clf_settagaspect{#1}{#2}} % todo: ignore when no export / also \let
+\unexpanded\def\ignoretagsinexport[#1]%
+ {\clf_ignoretagsinexport{#1}}
+
\installcorenamespace{tagging}
\installsetuponlycommandhandler \??tagging {tagging}
+% it makes no sense to have labels ... maybe some day as a last 'replace' in the export
+% which might be more efficient then ... okay, we now cannot overload but who cares
+
\unexpanded\def\strc_tags_element_start_yes{\dodoubleempty\strc_tags_element_start_yes_indeed}
\unexpanded\def\strc_tags_element_start_nop{\dodoubleempty\strc_tags_element_start_nop_indeed}
\unexpanded\def\strc_tags_element_start_yes_indeed
{\iftrialtypesetting
- \expandafter\strc_tags_element_start_nop_indeed
+ \expandafter\strc_tags_element_start_yes_indeed_nop
\else
\expandafter\strc_tags_element_start_yes_indeed_yes
\fi}
-\unexpanded\def\strc_tags_element_stop
- {\iftrialtypesetting
- \expandafter\strc_tags_element_stop_nop
- \else
- \expandafter\strc_tags_element_stop_yes
- \fi}
-
-% it makes no sense to have labels ... maybe some day as a last 'replace' in the export
-% which might be more efficient then ... okay, we now cannot overload but who cares
+\unexpanded\def\strc_tags_element_start_yes_indeed_nop[#1][#2]%
+ {}
\unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]%
{\clf_starttag_u{#1}{#2}}
\unexpanded\def\strc_tags_element_stop_yes
- {\clf_stoptag}
+ {\iftrialtypesetting
+ \expandafter\strc_tags_element_stop_yes_indeed_nop
+ \else
+ \expandafter\strc_tags_element_stop_yes_indeed_yes
+ \fi}
-\unexpanded\def\strc_tags_element_start_nop_indeed[#1][#2]%
+\unexpanded\def\strc_tags_element_stop_nop
{}
-\unexpanded\def\strc_tags_element_stop_nop
+\unexpanded\def\strc_tags_element_stop_yes_indeed_nop
{}
+\unexpanded\def\strc_tags_element_stop_yes_indeed_yes
+ {\clf_stoptag}
+
+\let\strc_tags_element_start_nop_indeed\strc_tags_element_start_yes_indeed_nop
+\let\strc_tags_element_stop_nop_indeed \strc_tags_element_stop_yes_indeed_nop
+
\def\strc_tags_report_hyphen#1%
{\writestatus\m!languages{setting #1 to U+00AD}}
@@ -293,12 +312,18 @@
% \dostarttaggedchained % {tag} {detail} \??hash
% \dostarttaggednodetail % {tag}
-% \unexpanded\def\strc_tags_enable
-% {\let\dostarttagged\strc_tags_start_yes
-% \let\dostoptagged \strc_tags_stop_yes}
+\newconditional\c_strc_tags_enabled
+
+\let\dotaggedplaceholder\empty
+
+\chardef\strc_tags_placeholder_char\zerocount % "FFFC
\unexpanded\def\strc_tags_enable
- {\let\dostarttagged \strc_tags_enabled_start_detail
+ {% once enable one is toast
+ \global\settrue\c_strc_tags_enabled
+ % and gets:
+ \let\dotaggedplaceholder \strc_tags_placeholder_char
+ \let\dostarttagged \strc_tags_enabled_start_detail
\let\dostarttaggednodetail\strc_tags_enabled_start_no_detail
\let\dostarttaggedchained \strc_tags_enabled_start_chained
\let\dostoptagged \strc_tags_enabled_stop
@@ -306,12 +331,23 @@
\let\dostopignoretagging \strc_tags_stop_yes_ignore}
\unexpanded\def\strc_tags_disable
- {\let\dostarttagged \strc_tags_start_nop_detail
- \let\dostarttaggednodetail\strc_tags_start_nop_no_detail
- \let\dostarttaggedchained \strc_tags_start_nop_chained
- \let\dostoptagged \strc_tags_stop_nop
- \let\dostartignoretagging \strc_tags_start_nop_ignore
- \let\dostopignoretagging \strc_tags_stop_nop_ignore}
+ {\ifconditional\c_strc_tags_enabled
+ % so now all are artifacts
+ \let\dotaggedplaceholder \strc_tags_placeholder_char
+ \let\dostarttagged \strc_tags_start_nop_detail
+ \let\dostarttaggednodetail\strc_tags_start_nop_no_detail
+ \let\dostarttaggedchained \strc_tags_start_nop_chained
+ \let\dostoptagged \strc_tags_stop_nop_ignore
+ \else
+ % initial
+ \let\dotaggedplaceholder \empty
+ \let\dostarttagged \strc_tags_start_nop_detail
+ \let\dostarttaggednodetail\strc_tags_start_nop_no_detail
+ \let\dostarttaggedchained \strc_tags_start_nop_chained
+ \let\dostoptagged \strc_tags_stop_nop_ignore
+ \let\dostartignoretagging \strc_tags_start_nop_ignore
+ \let\dostopignoretagging \strc_tags_stop_nop_ignore
+ \fi}
% for luigi (beware: fully expandable):
@@ -468,13 +504,27 @@
%D This will only work well with sane use.
-\appendtoks
- \dostartignoretagging
-\to \everybeforepagebody
+% \appendtoks
+% {%
+% \doglobal\appendtoks
+% \strc_tags_start_yes_ignore
+% \to \everybeforepagebody
+% \doglobal\appendtoks
+% \strc_tags_stop_yes_ignore
+% \to \everyafterpagebody
+% }%
+% \to \everyenableelements
+
+% This doesn't work well either, so instead we handle the ornaments in the
+% tagging in a different way (see attr -> false code).
-\appendtoks
- \dostopignoretagging
-\to \everyafterpagebody
+% \appendtoks
+% \dostartignoretagging
+% \to \everybeforepagebody
+%
+% \appendtoks
+% \dostopignoretagging
+% \to \everyafterpagebody
% \doifelseinelement{structure:section} {yes} {no}
% \doifelseinelement{structure:chapter} {yes} {no}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-usr.lua b/Master/texmf-dist/tex/context/base/mkiv/strc-usr.lua
new file mode 100644
index 00000000000..f121fe296a7
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-usr.lua
@@ -0,0 +1,29 @@
+if not modules then modules = { } end modules ['strc-usr'] = {
+ version = 1.000,
+ comment = "companion to strc-usr.mkiv",
+ author = "Wolfgang Schuster",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- The following is copied from \type {tabl-xtb.lua} to make the userdata environment
+-- work with \LUA\ documents.
+
+local context = context
+local ctxcore = context.core
+
+local startuserdata = ctxcore.startuserdata
+local stopuserdata = ctxcore.stopuserdata
+
+local startcollecting = context.startcollecting
+local stopcollecting = context.stopcollecting
+
+function ctxcore.startuserdata(...)
+ startcollecting()
+ startuserdata(...)
+end
+
+function ctxcore.stopuserdata()
+ stopuserdata()
+ stopcollecting()
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-usr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/strc-usr.mkiv
new file mode 100644
index 00000000000..97b656fa087
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/strc-usr.mkiv
@@ -0,0 +1,180 @@
+%D \module
+%D [ file=strc-bkm,
+%D version=2009.04.01,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Bookmarks,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Userdata}
+
+\registerctxluafile{strc-usr}{}
+
+%D It's a bit like blocks that also use buffers but more lightweight and with
+%D inplace settings.
+%D
+%D \starttyping
+%D \defineuserdata [test] [style=italic]
+%D
+%D \samplefile{klein}
+%D
+%D \startuserdata [before=\blank,after=\blank,color=red]
+%D \samplefile{greenfield}
+%D \stopuserdata
+%D
+%D \samplefile{sapolsky}
+%D
+%D \startuserdata [test]
+%D \samplefile{bryson}
+%D \stopuserdata
+%D
+%D \samplefile{jojomayer}
+%D
+%D \startuserdata [test] [before=\blank,after=\blank,color=red]
+%D \samplefile{linden}
+%D \stopuserdata
+%D
+%D \samplefile{montgomery}
+%D \stoptyping
+%D
+%D Or from \LUA:
+%D
+%D \starttyping
+%D \startluacode
+%D context.startuserdata({color="blue"})
+%D context.samplefile("klein")
+%D context.stopuserdata()
+%D \stopluacode
+%D \stoptyping
+%D
+%D An example of an alternative:
+%D
+%D \starttyping
+%D \defineuserdataalternative [epigraph] [renderingsetup=userdata:epigraph]
+%D
+%D \startsetups [userdata:epigraph]
+%D \startframedtext [location=right,frame=off,align={flushleft,broad},style=\tfx,offset=.25ex,width=.5\textwidth]
+%D \begstrut\inlinebuffer[userdata]\endstrut
+%D \hairline
+%D \wordright{\userdataparameter{author}}
+%D \stopframedtext
+%D \stopsetups
+%D
+%D \defineuserdata
+%D [epigraph]
+%D [alternative=epigraph]
+%D
+%D \startuserdata [epigraph] [author={Sean B. Carrol}]
+%D The fraction of fossil olfactory receptor genes is significantly higher in
+%D all species with full color vision. This suggests that the evolution of
+%D trichromatic vision --- which allows these primates to detect food, mates,
+%D and danger with visual cues --- has reduced their reliance on the sense of
+%D smell.
+%D \stopuserdata
+%D
+%D \startuserdata [epigraph] [author={Sean B. Carrol}]
+%D \samplefile{carrol}
+%D \stopuserdata
+%D \stoptyping
+
+\unprotect
+
+\installnamespace {userdata}
+\installnamespace {userdataalternative}
+\installnamespace {userdatarenderings}
+
+\installcommandhandler \????userdata {userdata} \????userdata
+\installcommandhandler \????userdataalternative {userdataalternative} \????userdataalternative
+
+\unexpanded\def\startuserdata
+ {\begingroup
+ \let\currentuserdata\empty
+ \doifelsenextoptionalcs\userdata_start_delayed\userdata_start_indeed}
+
+% This variant works only when the userdata instance exists while the assignment check
+% can also be used with undefined instances which falls back to the global settings.
+%
+% \def\userdata_start_delayed[#1]%
+% {\ifcsname\nameduserdatahash{\detokenize\expandafter{\normalexpanded{#1}}}\s!parent\endcsname
+% \expandafter\userdata_start_delayed_name
+% \else
+% \expandafter\userdata_start_delayed_parameters
+% \fi[#1]}
+
+\def\userdata_start_delayed[#1]%
+ {\doifelseassignmentcs{#1}%
+ \userdata_start_delayed_parameters
+ \userdata_start_delayed_name
+ [#1]}
+
+\def\userdata_start_delayed_parameters[#1]%
+ {\setupcurrentuserdata[#1]%
+ \userdata_start_indeed}
+
+\def\userdata_start_delayed_name[#1]%
+ {\edef\currentuserdata{#1}%
+ \checkuserdataparent
+ \doifelsenextoptionalcs\userdata_start_delayed_parameters\userdata_start_indeed}
+
+\def\userdata_start_indeed
+ {\grabbufferdatadirect\s!userdata{\csstring\startuserdata}{\csstring\stopuserdata}}
+
+% \unexpanded\def\stopuserdata
+% {\useuserdatastyleandcolor\c!style\c!color
+% \usealignparameter\userdataparameter
+% \edef\currentuserdataalternative{\userdataparameter\c!alternative}%
+% \ifcsname\currentuserdataalternativehash\s!parent\endcsname \else
+% \let\currentuserdataalternative\s!default
+% \fi
+% \edef\p_renderingsetup{\userdataalternativeparameter\c!renderingsetup}%
+% \directsetup\p_renderingsetup
+% \endgroup}
+
+\unexpanded\def\stopuserdata
+ {\userdataparameter\c!before % HH: moved, so we obey the outer spacing
+ \dostarttagged\t!userdata\currentuserdata % HH: added, maybe move up ?
+ \begingroup
+ \useuserdatastyleandcolor\c!style\c!color
+ \usealignparameter\userdataparameter % HH: added
+ \edef\currentuserdataalternative{\userdataparameter\c!alternative}%
+ \ifcsname\currentuserdataalternativehash\s!parent\endcsname \else
+ \let\currentuserdataalternative\s!default
+ \fi
+ \usesetupsparameter\userdataparameter
+ \edef\p_renderingsetup{\userdataalternativeparameter\c!renderingsetup}%
+ \directsetup\p_renderingsetup
+ \endgroup
+ \dostoptagged
+ \userdataparameter\c!after % HH: moved
+ \endgroup}
+
+\unexpanded\def\getuserdata
+ {\getbufferdata[\s!userdata]}
+
+\unexpanded\def\getinlineuserdata
+ {\inlinebuffer[\s!userdata]}
+
+\defineuserdataalternative
+ [\s!default]
+ [\c!renderingsetup=\????userdatarenderings:\s!default]
+
+% \startsetups[\????userdatarenderings:\s!default]
+% \userdataparameter\c!before
+% \usesetupsparameter\userdataparameter
+% \getbufferdata[\s!userdata]
+% \userdataparameter\c!after
+% \stopsetups
+
+\startsetups[\????userdatarenderings:\s!default]
+ \getuserdata
+\stopsetups
+
+\setupuserdata
+ [\c!alternative=\s!default]
+
+\protect
diff --git a/Master/texmf-dist/tex/context/base/mkiv/supp-box.lua b/Master/texmf-dist/tex/context/base/mkiv/supp-box.lua
index 40047167c3c..1f31f768130 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/supp-box.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/supp-box.lua
@@ -20,63 +20,67 @@ local nodes = nodes
local implement = interfaces.implement
-local nodecodes = nodes.nodecodes
-
-local disc_code = nodecodes.disc
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local glue_code = nodecodes.glue
-local glyph_code = nodecodes.glyph
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-
------ getfield = nuts.getfield
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getboth = nuts.getboth
-local getdisc = nuts.getdisc
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getattribute = nuts.getattribute
-local getbox = nuts.getbox
-local getdir = nuts.getdir
-local getwidth = nuts.getwidth
-local takebox = nuts.takebox
-
------ setfield = nuts.setfield
-local setlink = nuts.setlink
-local setboth = nuts.setboth
-local setnext = nuts.setnext
-local setbox = nuts.setbox
-local setlist = nuts.setlist
-local setdisc = nuts.setdisc
-local setwidth = nuts.setwidth
-local setheight = nuts.setheight
-local setdepth = nuts.setdepth
-
-local flush_node = nuts.flush_node
-local flush_list = nuts.flush_list
-local copy_node = nuts.copy
-local copy_list = nuts.copy_list
-local find_tail = nuts.tail
-local traverse_id = nuts.traverse_id
-local list_dimensions = nuts.dimensions
-local hpack = nuts.hpack
-
-local listtoutf = nodes.listtoutf
-
-local nodepool = nuts.pool
-local new_penalty = nodepool.penalty
-local new_hlist = nodepool.hlist
-local new_glue = nodepool.glue
-
-local setlistcolor = nodes.tracers.colors.setlist
-
-local texget = tex.get
-local texgetbox = tex.getbox
-local texsetdimen = tex.setdimen
+local nodecodes = nodes.nodecodes
+
+local disc_code = nodecodes.disc
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glue_code = nodecodes.glue
+local glyph_code = nodecodes.glyph
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+----- getfield = nuts.getfield
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getboth = nuts.getboth
+local getdisc = nuts.getdisc
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getattribute = nuts.getattribute
+local getbox = nuts.getbox
+local getdirection = nuts.getdirection
+local getwidth = nuts.getwidth
+local takebox = nuts.takebox
+
+----- setfield = nuts.setfield
+local setlink = nuts.setlink
+local setboth = nuts.setboth
+local setnext = nuts.setnext
+local setbox = nuts.setbox
+local setlist = nuts.setlist
+local setdisc = nuts.setdisc
+local setwidth = nuts.setwidth
+local setheight = nuts.setheight
+local setdepth = nuts.setdepth
+local setshift = nuts.setshift
+
+local flush_node = nuts.flush_node
+local flush_list = nuts.flush_list
+local copy_node = nuts.copy
+local copy_list = nuts.copy_list
+local find_tail = nuts.tail
+local getdimensions = nuts.dimensions
+local hpack = nuts.hpack
+
+local nextdisc = nuts.traversers.disc
+local nextdir = nuts.traversers.dir
+local nexthlist = nuts.traversers.hlist
+
+local listtoutf = nodes.listtoutf
+
+local nodepool = nuts.pool
+local new_penalty = nodepool.penalty
+local new_hlist = nodepool.hlist
+local new_glue = nodepool.glue
+
+local setlistcolor = nodes.tracers.colors.setlist
+
+local texget = tex.get
+local texgetbox = tex.getbox
+local texsetdimen = tex.setdimen
local function hyphenatedlist(head,usecolor)
local current = head and tonut(head)
@@ -127,7 +131,7 @@ implement {
-- local function hyphenatedhack(head,pre)
-- pre = tonut(pre)
--- for n in traverse_id(disc_code,tonut(head)) do
+-- for n in nextdisc, tonut(head) do
-- local hyphen = getfield(n,"pre")
-- if hyphen then
-- flush_list(hyphen)
@@ -361,10 +365,12 @@ implement {
}
local function getnaturaldimensions(n)
- local w, h, d = 0, 0, 0
+ local w = 0
+ local h = 0
+ local d = 0
local l = getlist(getbox(n))
if l then
- w, h, d = list_dimensions(l)
+ w, h, d = getdimensions(l)
end
texsetdimen("lastnaturalboxwd",w)
texsetdimen("lastnaturalboxht",h)
@@ -391,10 +397,12 @@ interfaces.implement {
name = "getnaturalwd",
arguments = "integer",
actions = function(n)
- local w, h, d = 0, 0, 0
+ local w = 0
+ local h = 0
+ local d = 0
local l = getlist(getbox(n))
if l then
- w, h, d = list_dimensions(l)
+ w, h, d = getdimensions(l)
end
context("\\dimexpr%i\\scaledpoint\\relax",w)
end
@@ -416,46 +424,60 @@ interfaces.implement {
nodes.setboxtonaturalwd = setboxtonaturalwd
-local function firstdirinbox(n)
- local b = getbox(n)
- if b then
- local l = getlist(b)
- if l then
- for h in traverse_id(hlist_code,l) do
- return getdir(h)
+local doifelse = commands.doifelse
+
+do
+
+ local dirvalues = nodes.dirvalues
+ local lefttoright_code = dirvalues.lefttoright
+ local righttoleft_code = dirvalues.righttoleft
+
+ local function firstdirinbox(n)
+ local b = getbox(n)
+ if b then
+ local l = getlist(b)
+ if l then
+ for d in nextdir, l do
+ return getdirection(d)
+ end
+ for h in nexthlist, l do
+ return getdirection(h)
+ end
end
end
+ return lefttoright_code
end
-end
-nodes.firstdirinbox = firstdirinbox
+ nodes.firstdirinbox = firstdirinbox
-local doifelse = commands.doifelse
+ interfaces.implement {
+ name = "doifelserighttoleftinbox",
+ arguments = "integer",
+ actions = function(n)
+ doifelse(firstdirinbox(n) == righttoleft_code)
+ end
+ }
-interfaces.implement {
- name = "doifelserighttoleftinbox",
- arguments = "integer",
- actions = function(n)
- doifelse(firstdirinbox(n) == "TRT")
- end
-}
+end
-- new (handy for mp) .. might move to its own module
do
- local flush_list = nodes.flush_list
- local copy_list = nodes.copy_list
- local takebox = nodes.takebox
- local texsetbox = tex.setbox
-
- local new_hlist = nodes.pool.hlist
-
- local boxes = { }
- nodes.boxes = boxes
- local cache = table.setmetatableindex("table")
- local report = logs.reporter("boxes","cache")
- local trace = false
+ local nuts = nodes.nuts
+ local tonode = nuts.tonode
+ local takebox = nuts.takebox
+ local flush_list = nuts.flush_list
+ local copy_list = nuts.copy_list
+ local getwhd = nuts.getwhd
+ local setbox = nuts.setbox
+ local new_hlist = nuts.pool.hlist
+
+ local boxes = { }
+ nodes.boxes = boxes
+ local cache = table.setmetatableindex("table")
+ local report = logs.reporter("boxes","cache")
+ local trace = false
trackers.register("nodes.boxes",function(v) trace = v end)
@@ -487,7 +509,9 @@ do
if trace then
report("category %a, name %a, %s (%s)",category,name,"direct",b and "content" or "empty")
end
- return b or nil
+ if b then
+ return tonode(b)
+ end
end
function boxes.restore(category,name,box,copy)
@@ -508,11 +532,9 @@ do
if trace then
report("category %a, name %a, %s (%s)",category,name,"restore",b and "content" or "empty")
end
- texsetbox(box,b or nil)
+ setbox(box,b or nil)
end
- local getwhd = nodes.getwhd
-
function boxes.dimensions(category,name)
name = tonumber(name) or name
local b = cache[category][name]
@@ -592,13 +614,19 @@ do
actions = boxes.reset,
}
- implement {
- name = "lastlinewidth",
- actions = function()
- local head = tex.lists.page_head
- -- list dimensions returns 3 value but we take the first
- context(head and list_dimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0)
- end
- }
-
end
+
+implement {
+ name = "lastlinewidth",
+ actions = function()
+ local head = tex.lists.page_head
+ -- list dimensions returns 3 value but we take the first
+ context(head and getdimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0)
+ end
+}
+
+interfaces.implement {
+ name = "shiftbox",
+ arguments = { "integer", "dimension" },
+ actions = function(n,d) setshift(getbox(n),d) end,
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/supp-box.mkiv b/Master/texmf-dist/tex/context/base/mkiv/supp-box.mkiv
index fb9cbdf5dac..59e7105207b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/supp-box.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/supp-box.mkiv
@@ -15,10 +15,14 @@
\unprotect
-\registerctxluafile{supp-box}{}
+\registerctxluafile{supp-box}{optimize}
% This file is partially cleaned up.
+%D First some defaults:
+
+\fixupboxesmode\plusone
+
% handy to have
%
% \hbox to \hsize
@@ -208,8 +212,8 @@
%D \smashedvbox to ... {...}
%D \stoptyping
-\unexpanded\def\smashedhbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\hbox}
-\unexpanded\def\smashedvbox{\vbox\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\vbox}
+\unexpanded\def\smashedhbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\hbox}
+\unexpanded\def\smashedvbox{\vpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\vbox}
%D First we define a helper. We use a \LUATEX\ feature in order to avoid
%D mathpalettes.
@@ -576,7 +580,7 @@
\unexpanded\def\doifelsetext#1%
{\begingroup
- \setbox\scratchbox\hbox
+ \setbox\scratchbox\hpack
{\settrialtypesetting
\ignorespaces#1\removeunwantedspaces}%
\ifzeropt\wd\scratchbox
@@ -589,7 +593,7 @@
\unexpanded\def\doiftext#1%
{\begingroup
- \setbox\scratchbox\hbox
+ \setbox\scratchbox\hpack
{\settrialtypesetting
\ignorespaces#1\removeunwantedspaces}%
\ifzeropt\wd\scratchbox
@@ -670,7 +674,7 @@
%D \afterassignment\syst_boxes_with_next_box_indeed
%D \else\ifx#2\vbox
%D \afterassignment\syst_boxes_with_next_box_indeed
-%D \else\ifx#2\normalvtop
+%D \else\ifx#2\vtop
%D \afterassignment\syst_boxes_with_next_box_indeed
%D \else\ifx#2\normalvcenter
%D \afterassignment\syst_boxes_with_next_box_indeed
@@ -730,9 +734,9 @@
%D Some well known friends, but we implement them our own
%D way. We want the macros to work in both math and text mode.
-\def\dodorlap{\hpack to \zeropoint{\box\nextbox\normalhss}\endgroup}
-\def\dodollap{\hpack to \zeropoint{\normalhss\box\nextbox}\endgroup}
-\def\dodoclap{\hpack to \zeropoint{\normalhss\box\nextbox\normalhss}\endgroup}
+\def\dodorlap{\hpack to \zeropoint{\box\nextbox\hss}\endgroup}
+\def\dodollap{\hpack to \zeropoint{\hss\box\nextbox}\endgroup}
+\def\dodoclap{\hpack to \zeropoint{\hss\box\nextbox\hss}\endgroup}
\def\dorlap{\begingroup\dowithnextboxcs\dodorlap\hbox}
\def\dollap{\begingroup\dowithnextboxcs\dodollap\hbox}
@@ -746,8 +750,8 @@
\unexpanded\def\llap{\mathortext\domathllap\dollap}
\unexpanded\def\clap{\mathortext\domathclap\doclap}
-\def\dodotlap{\vpack to \zeropoint{\normalvss\box\nextbox}\endgroup}
-\def\dodoblap{\vpack to \zeropoint{\box\nextbox\normalvss}\endgroup}
+\def\dodotlap{\vpack to \zeropoint{\vss\box\nextbox}\endgroup}
+\def\dodoblap{\vpack to \zeropoint{\box\nextbox\vss}\endgroup}
\unexpanded\def\tlap{\begingroup\dowithnextboxcs\dodotlap\vbox}
\unexpanded\def\blap{\begingroup\dowithnextboxcs\dodoblap\vbox}
@@ -1183,8 +1187,8 @@
%D complex macro than needed at first sight.
\def\dodoboundtext#1%
- {\setbox0\hbox{#1}%
- \advance\scratchdimen -\wd0
+ {\setbox\scratchboxone\hbox{#1}%
+ \advance\scratchdimen -\wd\scratchboxone
\ifdim\scratchdimen>\zeropoint\relax#1\fi}%
\def\doboundtext#1#2#3% still used?
@@ -1243,7 +1247,7 @@
\ifdim\wd\nextbox>\scratchdimen
\setbox\scratchbox\hbox{\ifdone\space#2\else#2\space\fi}%
\advance\scratchdimen -\wd\scratchbox
- \setbox0\box\nextbox
+ \setbox\scratchboxone\box\nextbox
\setbox\nextbox\vbox
{\hsize\scratchdimen
\hfuzz\maxdimen
@@ -1254,7 +1258,7 @@
\rightskip\zeropoint
\hskip\zeropoint \s!plus 1\s!fill % \hsize
\fi
- \unhcopy0}%
+ \unhcopy\scratchboxone}%
\ifdim\ht\nextbox>\strutht
\setbox\nextbox\vbox % if omitted: missing brace reported
{\splittopskip\openstrutheight
@@ -1262,7 +1266,7 @@
\setbox\nextbox\vsplit\nextbox to \strutht
\else
\doloop
- {\setbox0\vsplit\nextbox to \strutht
+ {\setbox\scratchboxone\vsplit\nextbox to \strutht
\ifdim\ht\nextbox>\strutht \else \exitloop \fi}%
\fi
\unvbox\nextbox
@@ -1304,13 +1308,13 @@
{%\dontleavehmode
\bgroup
\let\speciallimitatetext\firstoffourarguments
- \setbox0\hbox
+ \setbox\scratchboxone\hbox
{\nohyphens
\normallimitatetext{#1}{+#2}{}#4%
\normallimitatetext{#1}{-#3}{}}%
- \setbox2\hbox
+ \setbox\scratchboxtwo\hbox
{#1}%
- \ifdim\wd2<\wd0 #1\else\unhbox0\fi
+ \ifdim\wd\scratchboxtwo<\wd\scratchboxone #1\else\unhbox\scratchboxone\fi
\egroup}
\unexpanded\def\limitatetext#1#2#3% \expanded added 2003/01/16
@@ -1328,7 +1332,7 @@
%D \stoptyping
\unexpanded\def\limitatefirstline#1#2#3%
- {\hbox\bgroup\strut
+ {\hbox\bgroup\strut % \hpack
\setbox\scratchbox\hbox{\begstrut#1\endstrut}%
\ifdim\wd\scratchbox>#2\relax
\setbox\scratchbox\hbox{#3}%
@@ -1340,7 +1344,7 @@
{\unvbox\scratchbox
\global\setbox\plusone\lastbox
\global\setbox\plusone\hbox{\strut\unhbox\plusone}%
- \hbox % to #2
+ \hbox % to #2 % \hpack
{\ifx\clip\undefined
\box\plusone
\else\ifdim\wd\plusone>\hsize
@@ -1533,7 +1537,7 @@
%D a strut.
\unexpanded\def\struttedbox
- {\hbox\bgroup
+ {\hpack\bgroup
\dowithnextboxcs\syst_boxes_struttedbox_finish\hbox}
\def\syst_boxes_struttedbox_finish
@@ -1550,7 +1554,7 @@
%D equals strutdepth.
\unexpanded\def\topskippedbox
- {\hbox\bgroup\dowithnextboxcs\syst_boxes_topskippedbox_finish\hbox}
+ {\hpack\bgroup\dowithnextboxcs\syst_boxes_topskippedbox_finish\hbox}
\def\syst_boxes_topskippedbox_finish
{\edef\m_boxes_tmp{\ifdim\strutdepth=\dp\nextbox\dp\nextbox\the\dp\nextbox\fi}%
@@ -1606,22 +1610,22 @@
\unexpanded\def\centeredbox#1#% height +/-dimen width +/-dimen
{\bgroup
- \setbox0\vpack to \vsize
+ \setbox\scratchboxone\vpack to \vsize
\bgroup
\dontcomplain
\forgetall
- \setbox0\hbox{\vrule\s!width \zeropoint#1}%
- \setbox2\vbox{\hrule\s!height\zeropoint#1}%
- \advance\vsize \ht2
- \advance\hsize \wd0
+ \setbox\scratchboxone\hpack{\vrule\s!width \zeropoint#1}%
+ \setbox\scratchboxtwo\vpack{\hrule\s!height\zeropoint#1}%
+ \advance\vsize \ht\scratchboxtwo
+ \advance\hsize \wd\scratchboxone
\vpack to \vsize
\bgroup
- \vskip-\ht2
+ \vskip-\ht\scratchboxtwo
\vss
\hpack to \hsize
\bgroup
\dowithnextbox
- {\hskip-\wd0
+ {\hskip-\wd\scratchboxone
\hss
\box\nextbox
\hss
@@ -1629,14 +1633,13 @@
\vss
\egroup
\egroup
- \wd0\hsize
- \ht0\vsize
- \box0
+ \wd\scratchboxone\hsize
+ \ht\scratchboxone\vsize
+ \box\scratchboxone
\egroup}
\hbox}
-%D For those who don't want to deal with \type {\hsize}
-%D and \type {\vsize}, we have:
+%D For those who don't want to deal with \type {\hsize} and \type {\vsize}, we have:
%D
%D \starttyping
%D \centerednextbox width 2bp height 2bp
@@ -1670,9 +1673,9 @@
{\bgroup
\dowithnextbox
{\setlocalhsize
- \setbox\scratchbox\hbox{\vrule\s!width \zeropoint#1}%
+ \setbox\scratchbox\hpack{\vrule\s!width \zeropoint#1}%
\ifzeropt\wd\scratchbox\else\hsize\wd\scratchbox\fi
- \setbox\scratchbox\vbox{\hrule\s!height\zeropoint#1}%
+ \setbox\scratchbox\vpack{\hrule\s!height\zeropoint#1}%
\ifzeropt\ht\scratchbox\else\vsize\ht\scratchbox\fi
\vpack to \vsize{\vss\hpack to \hsize{\hss\box\nextbox\hss}\vss}%
\egroup}%
@@ -1764,7 +1767,7 @@
{\dorecurse\rigidcolumns
{\setbox\scratchbox\vsplit\rigidcolumnbox to \scratchdimen
\dp\scratchbox\openstrutdepth
- \setbox\scratchbox\normalvtop
+ \setbox\scratchbox\vtop
\ifalignrigidcolumns to
\ifstretchrigidcolumns\vsize\else\scratchdimen\fi
\fi
@@ -1874,21 +1877,21 @@
\unexpanded\def\convertvboxtohbox
{\makehboxofhboxes
- \setbox0\hbox{\unhbox0 \removehboxes}%
- \noindent\unhbox0\par}
+ \setbox\scratchboxone\hpack{\unhbox\scratchboxone\removehboxes}% \hpack
+ \noindent\unhbox\scratchboxone\par}
\unexpanded\def\makehboxofhboxes
- {\setbox0\emptyhbox
- \loop % \doloop { .. \exitloop .. }
- \setbox2\lastbox
- \ifhbox2
- \setbox0\hbox{\box2\unhbox0}%
+ {\setbox\scratchboxone\emptyhbox
+ \loop % \doloop { .. \exitloop .. }
+ \setbox\scratchboxtwo\lastbox
+ \ifhbox\scratchboxtwo
+ \setbox\scratchboxone\hpack{\box\scratchboxtwo\unhbox\scratchboxone}%
\repeat}
\unexpanded\def\removehboxes
- {\setbox0\lastbox
- \ifhbox0
- {\removehboxes}\unhbox0
+ {\setbox\scratchboxone\lastbox
+ \ifhbox\scratchboxone
+ {\removehboxes}\unhbox\scratchboxone
\fi}
% And one special for notes:
@@ -1947,7 +1950,7 @@
\doloop
{\setbox\hhbox\vsplit\unhhedbox to \lineheight
\ifvoid\unhhedbox
- \setbox\hhbox\hbox{\strut\hboxofvbox\hhbox}%
+ \setbox\hhbox\hbox{\strut\hboxofvbox\hhbox}% \hpack
\fi
\ht\hhbox\strutht
\dp\hhbox\strutdp
@@ -2129,7 +2132,27 @@
%D
%D \leavevmode\getbuffer
+\def\boxisempty#1%
+ {\ifdim\wd#1=\zeropoint
+ \ifdim\ht#1=\zeropoint
+ \ifdim\dp#1=\zeropoint
+ \zerocount
+ \else
+ \plusone
+ \fi
+ \else
+ \plusone
+ \fi
+ \else
+ \plusone
+ \fi}
+
\def\syst_boxes_overlay_process
+ {\ifcase\boxisempty\nextbox\else
+ \syst_boxes_overlay_process_indeed
+ \fi}
+
+\def\syst_boxes_overlay_process_indeed
{%\removeunwantedspaces % already done
\scratchdepth\dp\ifdim\dp\nextbox>\dp\processbox\nextbox\else\processbox\fi
\ifdim\ht\nextbox>\ht\processbox
@@ -2198,9 +2221,9 @@
\unexpanded\def\cbox#1#{\vbox#1\syst_boxes_lrc_process\raggedcenter}
\unexpanded\def\rbox#1#{\vbox#1\syst_boxes_lrc_process\raggedright }
-\unexpanded\def\ltop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedleft }
-\unexpanded\def\ctop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedcenter}
-\unexpanded\def\rtop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedright }
+\unexpanded\def\ltop#1#{\vtop#1\syst_boxes_lrc_process\raggedleft }
+\unexpanded\def\ctop#1#{\vtop#1\syst_boxes_lrc_process\raggedcenter}
+\unexpanded\def\rtop#1#{\vtop#1\syst_boxes_lrc_process\raggedright }
%D The alternatives \type {\tbox} and \type {\bbox} can be used
%D to properly align boxes, like in:
@@ -2222,8 +2245,8 @@
%D
%D \getbuffer
-\unexpanded\def\tbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_tbox_finish\hbox}
-\unexpanded\def\bbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_bbox_finish\hbox}
+\unexpanded\def\tbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_tbox_finish\hbox}
+\unexpanded\def\bbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_bbox_finish\hbox}
\def\syst_boxes_tbox_finish
{\scratchdepth\dimexpr\ht\nextbox+\dp\nextbox-\ht\strutbox\relax
@@ -2289,7 +2312,7 @@
{\ifx\next\bgroup
\expanded{\egroup#1 to \the\sizeofbox}%
\else
- \@EA\afterassignment\@EA\docommand\@EA\scratchdimen
+ \expandafter\afterassignment\expandafter\docommand\expandafter\scratchdimen
\fi}%
\docommand}
@@ -2337,7 +2360,7 @@
\newbox\fakedboxcursor
-\setbox\fakedboxcursor\hbox
+\setbox\fakedboxcursor\hpack
{\vrule\s!width\zeropoint\s!height\zeropoint\s!depth\zeropoint}
\unexpanded\def\boxcursor % overloaded in core-vis
@@ -2723,7 +2746,7 @@
% vcenter in text, we kunnen vcenter overloaden
\unexpanded\def\halfwaybox
- {\hbox\bgroup
+ {\hpack\bgroup
\dowithnextboxcs\syst_boxes_halfwaybox_finish\hbox}
\def\syst_boxes_halfwaybox_finish
@@ -2732,7 +2755,7 @@
\egroup}
\unexpanded\def\depthonlybox
- {\vtop\bgroup
+ {\tpack\bgroup
\dowithnextboxcs\syst_boxes_depthonlybox_finish\vbox}
\def\syst_boxes_depthonlybox_finish
@@ -2747,12 +2770,7 @@
%D And even rawer:
- \let\naturalvtop \normalvtop
- \let\naturalvcenter\normalvtop
-\unexpanded\def\naturalhbox {\hbox dir TLT}
-\unexpanded\def\naturalvbox {\vbox dir TLT}
-\unexpanded\def\naturalhpack {\hpack dir TLT}
-\unexpanded\def\naturalvpack {\vpack dir TLT}
+\let\naturalvcenter\normalvtop % will go away
%D \macros
%D {vcenter}
@@ -2764,7 +2782,7 @@
\dowithnextboxcs\syst_boxes_vcenter_finish\vbox}
\def\syst_boxes_vcenter_finish
- {\hpack{\normalstartimath\normalvcenter{\box\nextbox}\normalstopimath}%
+ {\hpack{\normalstartimath\vcenter{\box\nextbox}\normalstopimath}%
\egroup}
% could be \everymathematics
@@ -2780,7 +2798,7 @@
%D A not so well unhboxable box can be made with:
\unexpanded\def\frozenhbox
- {\hbox\bgroup
+ {\hpack\bgroup
\dowithnextboxcs\syst_boxes_frozenhbox_finish\hbox}
\def\syst_boxes_frozenhbox_finish
@@ -2837,19 +2855,19 @@
\unexpanded\def\spreadhbox#1% rebuilds \hbox{}
{\bgroup
\ifhbox#1\relax
- \setbox2\emptybox
+ \setbox\scratchboxtwo\emptybox
\unhbox#1%
\doloop
{\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip
- \setbox0\lastbox
- \ifvoid0
+ \setbox\scratchboxone\lastbox
+ \ifvoid\scratchboxone
\exitloop
\else
- \setbox2\hbox
- {\ifhbox0 \spreadhbox0\else\box0\fi
- \ifvoid2 \else\hss\unhbox2\fi}%
+ \setbox\scratchboxtwo\hbox
+ {\ifhbox\scratchboxone \spreadhbox\scratchboxone\else\box\scratchboxone\fi
+ \ifvoid\scratchboxtwo \else\hss\unhbox\scratchboxtwo\fi}%
\fi}%
- \ifvoid2\else\unhbox2\fi
+ \ifvoid\scratchboxtwo\else\unhbox\scratchboxtwo\fi
\else
\box#1%
\fi
@@ -2974,6 +2992,24 @@
% \unexpanded\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox}
% \unexpanded\def\tightvtop{\dowithnextbox{\ht\nextbox\zeropoint\box\nextbox}\vtop}
+%D This one keeps dimensions and sets the shift field (and so it's more for testing
+%D than for real usage):
+
+\unexpanded\def\shiftbox{\clf_shiftbox}
+
+%D This one has been moved from a 2 decade old file. It makes something boxed
+%D sit on the baseline.
+
+\unexpanded\def\linebox
+ {\hpack\bgroup\dowithnextbox
+ {\scratchdimen\dimexpr\dimexpr\htdp\nextbox-\lineheight\relax/2+\dp\strutbox\relax
+ \setbox\nextbox\hpack{\lower\scratchdimen\box\nextbox}%
+ \ht\nextbox\ht\strutbox
+ \dp\nextbox\dp\strutbox
+ \box\nextbox
+ \egroup}
+ \hbox}
+
\protect \endinput
% a bit of test code:
diff --git a/Master/texmf-dist/tex/context/base/mkiv/supp-dir.mkiv b/Master/texmf-dist/tex/context/base/mkiv/supp-dir.mkiv
index 42a0aa37cf8..277f2b7cac2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/supp-dir.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/supp-dir.mkiv
@@ -11,40 +11,44 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D We no longer have the \ETEX\ direction primitives.
-
\unprotect
-% \expanded{\defineactivecharacter \number"2000E} {\textdir TRT\relax}
-% \expanded{\defineactivecharacter \number"2000F} {\textdir TLT\relax}
+\chardef\directionlefttoright\zerocount
+\chardef\directionrighttoleft\plusone
-%D As we have less directions now we can use something
+\edef\??bdir{\ifdefined\bodydir bdir\else direction\fi}
-% \chardef\@@D@@TLT0
-% \chardef\@@D@@TRT1
-% \chardef\@@D@@RTT0
-% \chardef\@@D@@LRL1
-%
-% \def\thetextdir{\csname @@D@@\the\textdir\endcsname}
-%
-% \ifnum\thetextdir=0 L\else R\fi \textdir TRT \ifnum\thetextdir=0 L\else R\fi
+\unexpanded\edef\naturalhbox {\hbox \??bdir\directionlefttoright}
+\unexpanded\edef\naturalvbox {\vbox \??bdir\directionlefttoright}
+\unexpanded\edef\naturalvtop {\vtop \??bdir\directionlefttoright}
+\unexpanded\edef\naturalhpack {\hpack \??bdir\directionlefttoright}
+\unexpanded\edef\naturalvpack {\vpack \??bdir\directionlefttoright}
+\unexpanded\edef\naturaltpack {\tpack \??bdir\directionlefttoright}
-\unexpanded\def\showdirsinmargin
- {\inleft{\normalexpanded{\noexpand\hbox dir TLT{\ttxx[\the\pardir,\the\textdir]}}}}
+\unexpanded\edef\reversehbox {\hbox \??bdir\directionrighttoleft}
+\unexpanded\edef\reversevbox {\vbox \??bdir\directionrighttoleft}
+\unexpanded\edef\reversevtop {\vtop \??bdir\directionrighttoleft}
+\unexpanded\edef\reversehpack {\hpack \??bdir\directionrighttoleft}
+\unexpanded\edef\reversevpack {\vpack \??bdir\directionrighttoleft}
+\unexpanded\edef\reversetpack {\tpack \??bdir\directionrighttoleft}
-\bgroup
- \catcode`L=\othercatcode \gdef\istltdir#1#2#3{\if#2L0\else1\fi}
- \catcode`R=\othercatcode \gdef\istrtdir#1#2#3{\if#2R0\else1\fi}
-\egroup
+\ifdefined\bodydir
+ \let\bodydir \undefined \let\normalbodydir \undefined
+ \let\bodydirection\undefined \let\normalbodydirection\undefined
+\fi
-\def\istlttextdir{\expandafter\istltdir\the\textdir}
-\def\istrttextdir{\expandafter\istrtdir\the\textdir}
+\ifdefined\pagedir
+ \let\pagedir \undefined \let\normalpagedir \undefined
+ \let\pagedirection\undefined \let\normalpagedirection\undefined
+\fi
-\def\istltpardir {\expandafter\istltdir\the\pardir }
-\def\istrtpardir {\expandafter\istrtdir\the\pardir }
+% \expanded{\defineactivecharacter \number"2000E} {\textdirection\directionrighttoleft\relax}
+% \expanded{\defineactivecharacter \number"2000F} {\textdirection\directionlefttoright\relax}
-% \ifcase\istlttextdir Y\else N\fi
-% \ifcase\istltpardir Y\else N\fi
-% \ifcase\istltdir TRT\relax Y\else N\fi
+\def\syst_direction_string#1{\ifcase#1=\plusone r2l\else l2r\fi}
+
+\unexpanded\def\showdirsinmargin
+ {\normalexpanded{\inleft{\naturalhbox
+ {\ttxx[\syst_direction_string\pardirection,\syst_direction_string\textdirection]}}}}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/supp-mat.mkiv b/Master/texmf-dist/tex/context/base/mkiv/supp-mat.mkiv
index 176233ae5b6..f72a0ff89dc 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/supp-mat.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/supp-mat.mkiv
@@ -179,7 +179,7 @@
\popmacro\dodimensionsignal}
\unexpanded\def\nodimension#1%
- {\unskip#1\global\let\dodimensionsignal\relax}
+ {\unskip#1\glet\dodimensionsignal\relax}
%D \macros
%D {cramped}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-emj.lua b/Master/texmf-dist/tex/context/base/mkiv/symb-emj.lua
index 3075e09854f..d6e2aebea6f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-emj.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-emj.lua
@@ -19,32 +19,27 @@ local protectglyphs = nodes.handlers.protectglyphs
local tonodes = nodes.tonodes
local currentfont = font.current
--- fast enough, no need to memoize
-
-local glyph_code = nodes.nodecodes.glyph
-local remove_node = nodes.remove
-local getid = nodes.getid
-local getnext = nodes.getnext
-local getchar = nodes.getchar
+local nuts = nodes.nuts
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+local remove_node = nuts.remove
+local isglyph = nuts.isglyph
local function removemodifiers(head)
+ local head = tonut(head)
local current = head
while current do
- if getid(current) == glyph_code then
- local char = getchar(current) -- using categories is too much
- if char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then
- head, current = remove_node(head,current,true)
- else
- current = getnext(current)
- end
+ local char, id = isglyph(current)
+ if char and char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then
+ head, current = remove_node(head,current,true)
else
current = getnext(current)
end
end
- return head
+ return tonode(head)
end
--- attributes
+-- fast enough, no need to memoize, maybe use attributes
local function checkedemoji(name,id)
local str = resolvedemoji(name)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-fontawesome.mkiv b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
index 145adc46c04..c638998ab75 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
@@ -10,749 +10,786 @@
\definefontsynonym [FontAwesome] [file:FontAwesome.otf]
%def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\utfchar{0x#1}}}
-\def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\tochar{x:#1}}}
+\def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\tochar{n:#1}}}
-\startsymbolset [fontawesome]
+\startsymbolset [fontawesome] [font=fontawesome]
- \definesymbol [500px] [\FontAwesomeSymbol{f26e}]
- \definesymbol [adjust] [\FontAwesomeSymbol{f042}]
- \definesymbol [adn] [\FontAwesomeSymbol{f170}]
- \definesymbol [align-center] [\FontAwesomeSymbol{f037}]
- \definesymbol [align-justify] [\FontAwesomeSymbol{f039}]
- \definesymbol [align-left] [\FontAwesomeSymbol{f036}]
- \definesymbol [align-right] [\FontAwesomeSymbol{f038}]
- \definesymbol [amazon] [\FontAwesomeSymbol{f270}]
- \definesymbol [ambulance] [\FontAwesomeSymbol{f0f9}]
- \definesymbol [american-sign-language-interpreting] [\FontAwesomeSymbol{f2a3}]
- \definesymbol [anchor] [\FontAwesomeSymbol{f13d}]
- \definesymbol [android] [\FontAwesomeSymbol{f17b}]
- \definesymbol [angellist] [\FontAwesomeSymbol{f209}]
- \definesymbol [angle-double-down] [\FontAwesomeSymbol{f103}]
- \definesymbol [angle-double-left] [\FontAwesomeSymbol{f100}]
- \definesymbol [angle-double-right] [\FontAwesomeSymbol{f101}]
- \definesymbol [angle-double-up] [\FontAwesomeSymbol{f102}]
- \definesymbol [angle-down] [\FontAwesomeSymbol{f107}]
- \definesymbol [angle-left] [\FontAwesomeSymbol{f104}]
- \definesymbol [angle-right] [\FontAwesomeSymbol{f105}]
- \definesymbol [angle-up] [\FontAwesomeSymbol{f106}]
- \definesymbol [apple] [\FontAwesomeSymbol{f179}]
- \definesymbol [archive] [\FontAwesomeSymbol{f187}]
- \definesymbol [area-chart] [\FontAwesomeSymbol{f1fe}]
- \definesymbol [arrow-circle-down] [\FontAwesomeSymbol{f0ab}]
- \definesymbol [arrow-circle-left] [\FontAwesomeSymbol{f0a8}]
- \definesymbol [arrow-circle-o-down] [\FontAwesomeSymbol{f01a}]
- \definesymbol [arrow-circle-o-left] [\FontAwesomeSymbol{f190}]
- \definesymbol [arrow-circle-o-right] [\FontAwesomeSymbol{f18e}]
- \definesymbol [arrow-circle-o-up] [\FontAwesomeSymbol{f01b}]
- \definesymbol [arrow-circle-right] [\FontAwesomeSymbol{f0a9}]
- \definesymbol [arrow-circle-up] [\FontAwesomeSymbol{f0aa}]
- \definesymbol [arrow-down] [\FontAwesomeSymbol{f063}]
- \definesymbol [arrow-left] [\FontAwesomeSymbol{f060}]
- \definesymbol [arrow-right] [\FontAwesomeSymbol{f061}]
- \definesymbol [arrow-up] [\FontAwesomeSymbol{f062}]
- \definesymbol [arrows] [\FontAwesomeSymbol{f047}]
- \definesymbol [arrows-alt] [\FontAwesomeSymbol{f0b2}]
- \definesymbol [arrows-h] [\FontAwesomeSymbol{f07e}]
- \definesymbol [arrows-v] [\FontAwesomeSymbol{f07d}]
- \definesymbol [asl-interpreting] [\FontAwesomeSymbol{f2a3}]
- \definesymbol [assistive-listening-systems] [\FontAwesomeSymbol{f2a2}]
- \definesymbol [asterisk] [\FontAwesomeSymbol{f069}]
- \definesymbol [at] [\FontAwesomeSymbol{f1fa}]
- \definesymbol [audio-description] [\FontAwesomeSymbol{f29e}]
- \definesymbol [automobile] [\FontAwesomeSymbol{f1b9}]
- \definesymbol [backward] [\FontAwesomeSymbol{f04a}]
- \definesymbol [balance-scale] [\FontAwesomeSymbol{f24e}]
- \definesymbol [ban] [\FontAwesomeSymbol{f05e}]
- \definesymbol [bank] [\FontAwesomeSymbol{f19c}]
- \definesymbol [bar-chart] [\FontAwesomeSymbol{f080}]
- \definesymbol [bar-chart-o] [\FontAwesomeSymbol{f080}]
- \definesymbol [barcode] [\FontAwesomeSymbol{f02a}]
- \definesymbol [bars] [\FontAwesomeSymbol{f0c9}]
- \definesymbol [battery-0] [\FontAwesomeSymbol{f244}]
- \definesymbol [battery-1] [\FontAwesomeSymbol{f243}]
- \definesymbol [battery-2] [\FontAwesomeSymbol{f242}]
- \definesymbol [battery-3] [\FontAwesomeSymbol{f241}]
- \definesymbol [battery-4] [\FontAwesomeSymbol{f240}]
- \definesymbol [battery-empty] [\FontAwesomeSymbol{f244}]
- \definesymbol [battery-full] [\FontAwesomeSymbol{f240}]
- \definesymbol [battery-half] [\FontAwesomeSymbol{f242}]
- \definesymbol [battery-quarter] [\FontAwesomeSymbol{f243}]
- \definesymbol [battery-three-quarters] [\FontAwesomeSymbol{f241}]
- \definesymbol [bed] [\FontAwesomeSymbol{f236}]
- \definesymbol [beer] [\FontAwesomeSymbol{f0fc}]
- \definesymbol [behance] [\FontAwesomeSymbol{f1b4}]
- \definesymbol [behance-square] [\FontAwesomeSymbol{f1b5}]
- \definesymbol [bell] [\FontAwesomeSymbol{f0f3}]
- \definesymbol [bell-o] [\FontAwesomeSymbol{f0a2}]
- \definesymbol [bell-slash] [\FontAwesomeSymbol{f1f6}]
- \definesymbol [bell-slash-o] [\FontAwesomeSymbol{f1f7}]
- \definesymbol [bicycle] [\FontAwesomeSymbol{f206}]
- \definesymbol [binoculars] [\FontAwesomeSymbol{f1e5}]
- \definesymbol [birthday-cake] [\FontAwesomeSymbol{f1fd}]
- \definesymbol [bitbucket] [\FontAwesomeSymbol{f171}]
- \definesymbol [bitbucket-square] [\FontAwesomeSymbol{f172}]
- \definesymbol [bitcoin] [\FontAwesomeSymbol{f15a}]
- \definesymbol [black-tie] [\FontAwesomeSymbol{f27e}]
- \definesymbol [blind] [\FontAwesomeSymbol{f29d}]
- \definesymbol [bluetooth] [\FontAwesomeSymbol{f293}]
- \definesymbol [bluetooth-b] [\FontAwesomeSymbol{f294}]
- \definesymbol [bold] [\FontAwesomeSymbol{f032}]
- \definesymbol [bolt] [\FontAwesomeSymbol{f0e7}]
- \definesymbol [bomb] [\FontAwesomeSymbol{f1e2}]
- \definesymbol [book] [\FontAwesomeSymbol{f02d}]
- \definesymbol [bookmark] [\FontAwesomeSymbol{f02e}]
- \definesymbol [bookmark-o] [\FontAwesomeSymbol{f097}]
- \definesymbol [braille] [\FontAwesomeSymbol{f2a1}]
- \definesymbol [briefcase] [\FontAwesomeSymbol{f0b1}]
- \definesymbol [btc] [\FontAwesomeSymbol{f15a}]
- \definesymbol [bug] [\FontAwesomeSymbol{f188}]
- \definesymbol [building] [\FontAwesomeSymbol{f1ad}]
- \definesymbol [building-o] [\FontAwesomeSymbol{f0f7}]
- \definesymbol [bullhorn] [\FontAwesomeSymbol{f0a1}]
- \definesymbol [bullseye] [\FontAwesomeSymbol{f140}]
- \definesymbol [bus] [\FontAwesomeSymbol{f207}]
- \definesymbol [buysellads] [\FontAwesomeSymbol{f20d}]
- \definesymbol [cab] [\FontAwesomeSymbol{f1ba}]
- \definesymbol [calculator] [\FontAwesomeSymbol{f1ec}]
- \definesymbol [calendar] [\FontAwesomeSymbol{f073}]
- \definesymbol [calendar-check-o] [\FontAwesomeSymbol{f274}]
- \definesymbol [calendar-minus-o] [\FontAwesomeSymbol{f272}]
- \definesymbol [calendar-o] [\FontAwesomeSymbol{f133}]
- \definesymbol [calendar-plus-o] [\FontAwesomeSymbol{f271}]
- \definesymbol [calendar-times-o] [\FontAwesomeSymbol{f273}]
- \definesymbol [camera] [\FontAwesomeSymbol{f030}]
- \definesymbol [camera-retro] [\FontAwesomeSymbol{f083}]
- \definesymbol [car] [\FontAwesomeSymbol{f1b9}]
- \definesymbol [caret-down] [\FontAwesomeSymbol{f0d7}]
- \definesymbol [caret-left] [\FontAwesomeSymbol{f0d9}]
- \definesymbol [caret-right] [\FontAwesomeSymbol{f0da}]
- \definesymbol [caret-square-o-down] [\FontAwesomeSymbol{f150}]
- \definesymbol [caret-square-o-left] [\FontAwesomeSymbol{f191}]
- \definesymbol [caret-square-o-right] [\FontAwesomeSymbol{f152}]
- \definesymbol [caret-square-o-up] [\FontAwesomeSymbol{f151}]
- \definesymbol [caret-up] [\FontAwesomeSymbol{f0d8}]
- \definesymbol [cart-arrow-down] [\FontAwesomeSymbol{f218}]
- \definesymbol [cart-plus] [\FontAwesomeSymbol{f217}]
- \definesymbol [cc] [\FontAwesomeSymbol{f20a}]
- \definesymbol [cc-amex] [\FontAwesomeSymbol{f1f3}]
- \definesymbol [cc-diners-club] [\FontAwesomeSymbol{f24c}]
- \definesymbol [cc-discover] [\FontAwesomeSymbol{f1f2}]
- \definesymbol [cc-jcb] [\FontAwesomeSymbol{f24b}]
- \definesymbol [cc-mastercard] [\FontAwesomeSymbol{f1f1}]
- \definesymbol [cc-paypal] [\FontAwesomeSymbol{f1f4}]
- \definesymbol [cc-stripe] [\FontAwesomeSymbol{f1f5}]
- \definesymbol [cc-visa] [\FontAwesomeSymbol{f1f0}]
- \definesymbol [certificate] [\FontAwesomeSymbol{f0a3}]
- \definesymbol [chain] [\FontAwesomeSymbol{f0c1}]
- \definesymbol [chain-broken] [\FontAwesomeSymbol{f127}]
- \definesymbol [check] [\FontAwesomeSymbol{f00c}]
- \definesymbol [check-circle] [\FontAwesomeSymbol{f058}]
- \definesymbol [check-circle-o] [\FontAwesomeSymbol{f05d}]
- \definesymbol [check-square] [\FontAwesomeSymbol{f14a}]
- \definesymbol [check-square-o] [\FontAwesomeSymbol{f046}]
- \definesymbol [chevron-circle-down] [\FontAwesomeSymbol{f13a}]
- \definesymbol [chevron-circle-left] [\FontAwesomeSymbol{f137}]
- \definesymbol [chevron-circle-right] [\FontAwesomeSymbol{f138}]
- \definesymbol [chevron-circle-up] [\FontAwesomeSymbol{f139}]
- \definesymbol [chevron-down] [\FontAwesomeSymbol{f078}]
- \definesymbol [chevron-left] [\FontAwesomeSymbol{f053}]
- \definesymbol [chevron-right] [\FontAwesomeSymbol{f054}]
- \definesymbol [chevron-up] [\FontAwesomeSymbol{f077}]
- \definesymbol [child] [\FontAwesomeSymbol{f1ae}]
- \definesymbol [chrome] [\FontAwesomeSymbol{f268}]
- \definesymbol [circle] [\FontAwesomeSymbol{f111}]
- \definesymbol [circle-o] [\FontAwesomeSymbol{f10c}]
- \definesymbol [circle-o-notch] [\FontAwesomeSymbol{f1ce}]
- \definesymbol [circle-thin] [\FontAwesomeSymbol{f1db}]
- \definesymbol [clipboard] [\FontAwesomeSymbol{f0ea}]
- \definesymbol [clock-o] [\FontAwesomeSymbol{f017}]
- \definesymbol [clone] [\FontAwesomeSymbol{f24d}]
- \definesymbol [close] [\FontAwesomeSymbol{f00d}]
- \definesymbol [cloud] [\FontAwesomeSymbol{f0c2}]
- \definesymbol [cloud-download] [\FontAwesomeSymbol{f0ed}]
- \definesymbol [cloud-upload] [\FontAwesomeSymbol{f0ee}]
- \definesymbol [cny] [\FontAwesomeSymbol{f157}]
- \definesymbol [code] [\FontAwesomeSymbol{f121}]
- \definesymbol [code-fork] [\FontAwesomeSymbol{f126}]
- \definesymbol [codepen] [\FontAwesomeSymbol{f1cb}]
- \definesymbol [codiepie] [\FontAwesomeSymbol{f284}]
- \definesymbol [coffee] [\FontAwesomeSymbol{f0f4}]
- \definesymbol [cog] [\FontAwesomeSymbol{f013}]
- \definesymbol [cogs] [\FontAwesomeSymbol{f085}]
- \definesymbol [columns] [\FontAwesomeSymbol{f0db}]
- \definesymbol [comment] [\FontAwesomeSymbol{f075}]
- \definesymbol [comment-o] [\FontAwesomeSymbol{f0e5}]
- \definesymbol [commenting] [\FontAwesomeSymbol{f27a}]
- \definesymbol [commenting-o] [\FontAwesomeSymbol{f27b}]
- \definesymbol [comments] [\FontAwesomeSymbol{f086}]
- \definesymbol [comments-o] [\FontAwesomeSymbol{f0e6}]
- \definesymbol [compass] [\FontAwesomeSymbol{f14e}]
- \definesymbol [compress] [\FontAwesomeSymbol{f066}]
- \definesymbol [connectdevelop] [\FontAwesomeSymbol{f20e}]
- \definesymbol [contao] [\FontAwesomeSymbol{f26d}]
- \definesymbol [copy] [\FontAwesomeSymbol{f0c5}]
- \definesymbol [copyright] [\FontAwesomeSymbol{f1f9}]
- \definesymbol [creative-commons] [\FontAwesomeSymbol{f25e}]
- \definesymbol [credit-card] [\FontAwesomeSymbol{f09d}]
- \definesymbol [credit-card-alt] [\FontAwesomeSymbol{f283}]
- \definesymbol [crop] [\FontAwesomeSymbol{f125}]
- \definesymbol [crosshairs] [\FontAwesomeSymbol{f05b}]
- \definesymbol [css3] [\FontAwesomeSymbol{f13c}]
- \definesymbol [cube] [\FontAwesomeSymbol{f1b2}]
- \definesymbol [cubes] [\FontAwesomeSymbol{f1b3}]
- \definesymbol [cut] [\FontAwesomeSymbol{f0c4}]
- \definesymbol [cutlery] [\FontAwesomeSymbol{f0f5}]
- \definesymbol [dashboard] [\FontAwesomeSymbol{f0e4}]
- \definesymbol [dashcube] [\FontAwesomeSymbol{f210}]
- \definesymbol [database] [\FontAwesomeSymbol{f1c0}]
- \definesymbol [deaf] [\FontAwesomeSymbol{f2a4}]
- \definesymbol [deafness] [\FontAwesomeSymbol{f2a4}]
- \definesymbol [dedent] [\FontAwesomeSymbol{f03b}]
- \definesymbol [delicious] [\FontAwesomeSymbol{f1a5}]
- \definesymbol [desktop] [\FontAwesomeSymbol{f108}]
- \definesymbol [deviantart] [\FontAwesomeSymbol{f1bd}]
- \definesymbol [diamond] [\FontAwesomeSymbol{f219}]
- \definesymbol [digg] [\FontAwesomeSymbol{f1a6}]
- \definesymbol [dollar] [\FontAwesomeSymbol{f155}]
- \definesymbol [dot-circle-o] [\FontAwesomeSymbol{f192}]
- \definesymbol [download] [\FontAwesomeSymbol{f019}]
- \definesymbol [dribbble] [\FontAwesomeSymbol{f17d}]
- \definesymbol [dropbox] [\FontAwesomeSymbol{f16b}]
- \definesymbol [drupal] [\FontAwesomeSymbol{f1a9}]
- \definesymbol [edge] [\FontAwesomeSymbol{f282}]
- \definesymbol [edit] [\FontAwesomeSymbol{f044}]
- \definesymbol [eject] [\FontAwesomeSymbol{f052}]
- \definesymbol [ellipsis-h] [\FontAwesomeSymbol{f141}]
- \definesymbol [ellipsis-v] [\FontAwesomeSymbol{f142}]
- \definesymbol [empire] [\FontAwesomeSymbol{f1d1}]
- \definesymbol [envelope] [\FontAwesomeSymbol{f0e0}]
- \definesymbol [envelope-o] [\FontAwesomeSymbol{f003}]
- \definesymbol [envelope-square] [\FontAwesomeSymbol{f199}]
- \definesymbol [envira] [\FontAwesomeSymbol{f299}]
- \definesymbol [eraser] [\FontAwesomeSymbol{f12d}]
- \definesymbol [eur] [\FontAwesomeSymbol{f153}]
- \definesymbol [euro] [\FontAwesomeSymbol{f153}]
- \definesymbol [exchange] [\FontAwesomeSymbol{f0ec}]
- \definesymbol [exclamation] [\FontAwesomeSymbol{f12a}]
- \definesymbol [exclamation-circle] [\FontAwesomeSymbol{f06a}]
- \definesymbol [exclamation-triangle] [\FontAwesomeSymbol{f071}]
- \definesymbol [expand] [\FontAwesomeSymbol{f065}]
- \definesymbol [expeditedssl] [\FontAwesomeSymbol{f23e}]
- \definesymbol [external-link] [\FontAwesomeSymbol{f08e}]
- \definesymbol [external-link-square] [\FontAwesomeSymbol{f14c}]
- \definesymbol [eye] [\FontAwesomeSymbol{f06e}]
- \definesymbol [eye-slash] [\FontAwesomeSymbol{f070}]
- \definesymbol [eyedropper] [\FontAwesomeSymbol{f1fb}]
- \definesymbol [fa] [\FontAwesomeSymbol{f2b4}]
- \definesymbol [facebook] [\FontAwesomeSymbol{f09a}]
- \definesymbol [facebook-f] [\FontAwesomeSymbol{f09a}]
- \definesymbol [facebook-official] [\FontAwesomeSymbol{f230}]
- \definesymbol [facebook-square] [\FontAwesomeSymbol{f082}]
- \definesymbol [fast-backward] [\FontAwesomeSymbol{f049}]
- \definesymbol [fast-forward] [\FontAwesomeSymbol{f050}]
- \definesymbol [fax] [\FontAwesomeSymbol{f1ac}]
- \definesymbol [feed] [\FontAwesomeSymbol{f09e}]
- \definesymbol [female] [\FontAwesomeSymbol{f182}]
- \definesymbol [fighter-jet] [\FontAwesomeSymbol{f0fb}]
- \definesymbol [file] [\FontAwesomeSymbol{f15b}]
- \definesymbol [file-archive-o] [\FontAwesomeSymbol{f1c6}]
- \definesymbol [file-audio-o] [\FontAwesomeSymbol{f1c7}]
- \definesymbol [file-code-o] [\FontAwesomeSymbol{f1c9}]
- \definesymbol [file-excel-o] [\FontAwesomeSymbol{f1c3}]
- \definesymbol [file-image-o] [\FontAwesomeSymbol{f1c5}]
- \definesymbol [file-movie-o] [\FontAwesomeSymbol{f1c8}]
- \definesymbol [file-o] [\FontAwesomeSymbol{f016}]
- \definesymbol [file-pdf-o] [\FontAwesomeSymbol{f1c1}]
- \definesymbol [file-photo-o] [\FontAwesomeSymbol{f1c5}]
- \definesymbol [file-picture-o] [\FontAwesomeSymbol{f1c5}]
- \definesymbol [file-powerpoint-o] [\FontAwesomeSymbol{f1c4}]
- \definesymbol [file-sound-o] [\FontAwesomeSymbol{f1c7}]
- \definesymbol [file-text] [\FontAwesomeSymbol{f15c}]
- \definesymbol [file-text-o] [\FontAwesomeSymbol{f0f6}]
- \definesymbol [file-video-o] [\FontAwesomeSymbol{f1c8}]
- \definesymbol [file-word-o] [\FontAwesomeSymbol{f1c2}]
- \definesymbol [file-zip-o] [\FontAwesomeSymbol{f1c6}]
- \definesymbol [files-o] [\FontAwesomeSymbol{f0c5}]
- \definesymbol [film] [\FontAwesomeSymbol{f008}]
- \definesymbol [filter] [\FontAwesomeSymbol{f0b0}]
- \definesymbol [fire] [\FontAwesomeSymbol{f06d}]
- \definesymbol [fire-extinguisher] [\FontAwesomeSymbol{f134}]
- \definesymbol [firefox] [\FontAwesomeSymbol{f269}]
- \definesymbol [first-order] [\FontAwesomeSymbol{f2b0}]
- \definesymbol [flag] [\FontAwesomeSymbol{f024}]
- \definesymbol [flag-checkered] [\FontAwesomeSymbol{f11e}]
- \definesymbol [flag-o] [\FontAwesomeSymbol{f11d}]
- \definesymbol [flash] [\FontAwesomeSymbol{f0e7}]
- \definesymbol [flask] [\FontAwesomeSymbol{f0c3}]
- \definesymbol [flickr] [\FontAwesomeSymbol{f16e}]
- \definesymbol [floppy-o] [\FontAwesomeSymbol{f0c7}]
- \definesymbol [folder] [\FontAwesomeSymbol{f07b}]
- \definesymbol [folder-o] [\FontAwesomeSymbol{f114}]
- \definesymbol [folder-open] [\FontAwesomeSymbol{f07c}]
- \definesymbol [folder-open-o] [\FontAwesomeSymbol{f115}]
- \definesymbol [font] [\FontAwesomeSymbol{f031}]
- \definesymbol [font-awesome] [\FontAwesomeSymbol{f2b4}]
- \definesymbol [fonticons] [\FontAwesomeSymbol{f280}]
- \definesymbol [fort-awesome] [\FontAwesomeSymbol{f286}]
- \definesymbol [forumbee] [\FontAwesomeSymbol{f211}]
- \definesymbol [forward] [\FontAwesomeSymbol{f04e}]
- \definesymbol [foursquare] [\FontAwesomeSymbol{f180}]
- \definesymbol [frown-o] [\FontAwesomeSymbol{f119}]
- \definesymbol [futbol-o] [\FontAwesomeSymbol{f1e3}]
- \definesymbol [gamepad] [\FontAwesomeSymbol{f11b}]
- \definesymbol [gavel] [\FontAwesomeSymbol{f0e3}]
- \definesymbol [gbp] [\FontAwesomeSymbol{f154}]
- \definesymbol [ge] [\FontAwesomeSymbol{f1d1}]
- \definesymbol [gear] [\FontAwesomeSymbol{f013}]
- \definesymbol [gears] [\FontAwesomeSymbol{f085}]
- \definesymbol [genderless] [\FontAwesomeSymbol{f22d}]
- \definesymbol [get-pocket] [\FontAwesomeSymbol{f265}]
- \definesymbol [gg] [\FontAwesomeSymbol{f260}]
- \definesymbol [gg-circle] [\FontAwesomeSymbol{f261}]
- \definesymbol [gift] [\FontAwesomeSymbol{f06b}]
- \definesymbol [git] [\FontAwesomeSymbol{f1d3}]
- \definesymbol [git-square] [\FontAwesomeSymbol{f1d2}]
- \definesymbol [github] [\FontAwesomeSymbol{f09b}]
- \definesymbol [github-alt] [\FontAwesomeSymbol{f113}]
- \definesymbol [github-square] [\FontAwesomeSymbol{f092}]
- \definesymbol [gitlab] [\FontAwesomeSymbol{f296}]
- \definesymbol [gittip] [\FontAwesomeSymbol{f184}]
- \definesymbol [glass] [\FontAwesomeSymbol{f000}]
- \definesymbol [glide] [\FontAwesomeSymbol{f2a5}]
- \definesymbol [glide-g] [\FontAwesomeSymbol{f2a6}]
- \definesymbol [globe] [\FontAwesomeSymbol{f0ac}]
- \definesymbol [google] [\FontAwesomeSymbol{f1a0}]
- \definesymbol [google-plus] [\FontAwesomeSymbol{f0d5}]
- \definesymbol [google-plus-circle] [\FontAwesomeSymbol{f2b3}]
- \definesymbol [google-plus-official] [\FontAwesomeSymbol{f2b3}]
- \definesymbol [google-plus-square] [\FontAwesomeSymbol{f0d4}]
- \definesymbol [google-wallet] [\FontAwesomeSymbol{f1ee}]
- \definesymbol [graduation-cap] [\FontAwesomeSymbol{f19d}]
- \definesymbol [gratipay] [\FontAwesomeSymbol{f184}]
- \definesymbol [group] [\FontAwesomeSymbol{f0c0}]
- \definesymbol [h-square] [\FontAwesomeSymbol{f0fd}]
- \definesymbol [hacker-news] [\FontAwesomeSymbol{f1d4}]
- \definesymbol [hand-grab-o] [\FontAwesomeSymbol{f255}]
- \definesymbol [hand-lizard-o] [\FontAwesomeSymbol{f258}]
- \definesymbol [hand-o-down] [\FontAwesomeSymbol{f0a7}]
- \definesymbol [hand-o-left] [\FontAwesomeSymbol{f0a5}]
- \definesymbol [hand-o-right] [\FontAwesomeSymbol{f0a4}]
- \definesymbol [hand-o-up] [\FontAwesomeSymbol{f0a6}]
- \definesymbol [hand-paper-o] [\FontAwesomeSymbol{f256}]
- \definesymbol [hand-peace-o] [\FontAwesomeSymbol{f25b}]
- \definesymbol [hand-pointer-o] [\FontAwesomeSymbol{f25a}]
- \definesymbol [hand-rock-o] [\FontAwesomeSymbol{f255}]
- \definesymbol [hand-scissors-o] [\FontAwesomeSymbol{f257}]
- \definesymbol [hand-spock-o] [\FontAwesomeSymbol{f259}]
- \definesymbol [hand-stop-o] [\FontAwesomeSymbol{f256}]
- \definesymbol [hard-of-hearing] [\FontAwesomeSymbol{f2a4}]
- \definesymbol [hashtag] [\FontAwesomeSymbol{f292}]
- \definesymbol [hdd-o] [\FontAwesomeSymbol{f0a0}]
- \definesymbol [header] [\FontAwesomeSymbol{f1dc}]
- \definesymbol [headphones] [\FontAwesomeSymbol{f025}]
- \definesymbol [heart] [\FontAwesomeSymbol{f004}]
- \definesymbol [heart-o] [\FontAwesomeSymbol{f08a}]
- \definesymbol [heartbeat] [\FontAwesomeSymbol{f21e}]
- \definesymbol [history] [\FontAwesomeSymbol{f1da}]
- \definesymbol [home] [\FontAwesomeSymbol{f015}]
- \definesymbol [hospital-o] [\FontAwesomeSymbol{f0f8}]
- \definesymbol [hotel] [\FontAwesomeSymbol{f236}]
- \definesymbol [hourglass] [\FontAwesomeSymbol{f254}]
- \definesymbol [hourglass-1] [\FontAwesomeSymbol{f251}]
- \definesymbol [hourglass-2] [\FontAwesomeSymbol{f252}]
- \definesymbol [hourglass-3] [\FontAwesomeSymbol{f253}]
- \definesymbol [hourglass-end] [\FontAwesomeSymbol{f253}]
- \definesymbol [hourglass-half] [\FontAwesomeSymbol{f252}]
- \definesymbol [hourglass-o] [\FontAwesomeSymbol{f250}]
- \definesymbol [hourglass-start] [\FontAwesomeSymbol{f251}]
- \definesymbol [houzz] [\FontAwesomeSymbol{f27c}]
- \definesymbol [html5] [\FontAwesomeSymbol{f13b}]
- \definesymbol [i-cursor] [\FontAwesomeSymbol{f246}]
- \definesymbol [ils] [\FontAwesomeSymbol{f20b}]
- \definesymbol [image] [\FontAwesomeSymbol{f03e}]
- \definesymbol [inbox] [\FontAwesomeSymbol{f01c}]
- \definesymbol [indent] [\FontAwesomeSymbol{f03c}]
- \definesymbol [industry] [\FontAwesomeSymbol{f275}]
- \definesymbol [info] [\FontAwesomeSymbol{f129}]
- \definesymbol [info-circle] [\FontAwesomeSymbol{f05a}]
- \definesymbol [inr] [\FontAwesomeSymbol{f156}]
- \definesymbol [instagram] [\FontAwesomeSymbol{f16d}]
- \definesymbol [institution] [\FontAwesomeSymbol{f19c}]
- \definesymbol [internet-explorer] [\FontAwesomeSymbol{f26b}]
- \definesymbol [intersex] [\FontAwesomeSymbol{f224}]
- \definesymbol [ioxhost] [\FontAwesomeSymbol{f208}]
- \definesymbol [italic] [\FontAwesomeSymbol{f033}]
- \definesymbol [joomla] [\FontAwesomeSymbol{f1aa}]
- \definesymbol [jpy] [\FontAwesomeSymbol{f157}]
- \definesymbol [jsfiddle] [\FontAwesomeSymbol{f1cc}]
- \definesymbol [key] [\FontAwesomeSymbol{f084}]
- \definesymbol [keyboard-o] [\FontAwesomeSymbol{f11c}]
- \definesymbol [krw] [\FontAwesomeSymbol{f159}]
- \definesymbol [language] [\FontAwesomeSymbol{f1ab}]
- \definesymbol [laptop] [\FontAwesomeSymbol{f109}]
- \definesymbol [lastfm] [\FontAwesomeSymbol{f202}]
- \definesymbol [lastfm-square] [\FontAwesomeSymbol{f203}]
- \definesymbol [leaf] [\FontAwesomeSymbol{f06c}]
- \definesymbol [leanpub] [\FontAwesomeSymbol{f212}]
- \definesymbol [legal] [\FontAwesomeSymbol{f0e3}]
- \definesymbol [lemon-o] [\FontAwesomeSymbol{f094}]
- \definesymbol [level-down] [\FontAwesomeSymbol{f149}]
- \definesymbol [level-up] [\FontAwesomeSymbol{f148}]
- \definesymbol [life-bouy] [\FontAwesomeSymbol{f1cd}]
- \definesymbol [life-buoy] [\FontAwesomeSymbol{f1cd}]
- \definesymbol [life-ring] [\FontAwesomeSymbol{f1cd}]
- \definesymbol [life-saver] [\FontAwesomeSymbol{f1cd}]
- \definesymbol [lightbulb-o] [\FontAwesomeSymbol{f0eb}]
- \definesymbol [line-chart] [\FontAwesomeSymbol{f201}]
- \definesymbol [link] [\FontAwesomeSymbol{f0c1}]
- \definesymbol [linkedin] [\FontAwesomeSymbol{f0e1}]
- \definesymbol [linkedin-square] [\FontAwesomeSymbol{f08c}]
- \definesymbol [linux] [\FontAwesomeSymbol{f17c}]
- \definesymbol [list] [\FontAwesomeSymbol{f03a}]
- \definesymbol [list-alt] [\FontAwesomeSymbol{f022}]
- \definesymbol [list-ol] [\FontAwesomeSymbol{f0cb}]
- \definesymbol [list-ul] [\FontAwesomeSymbol{f0ca}]
- \definesymbol [location-arrow] [\FontAwesomeSymbol{f124}]
- \definesymbol [lock] [\FontAwesomeSymbol{f023}]
- \definesymbol [long-arrow-down] [\FontAwesomeSymbol{f175}]
- \definesymbol [long-arrow-left] [\FontAwesomeSymbol{f177}]
- \definesymbol [long-arrow-right] [\FontAwesomeSymbol{f178}]
- \definesymbol [long-arrow-up] [\FontAwesomeSymbol{f176}]
- \definesymbol [low-vision] [\FontAwesomeSymbol{f2a8}]
- \definesymbol [magic] [\FontAwesomeSymbol{f0d0}]
- \definesymbol [magnet] [\FontAwesomeSymbol{f076}]
- \definesymbol [mail-forward] [\FontAwesomeSymbol{f064}]
- \definesymbol [mail-reply] [\FontAwesomeSymbol{f112}]
- \definesymbol [mail-reply-all] [\FontAwesomeSymbol{f122}]
- \definesymbol [male] [\FontAwesomeSymbol{f183}]
- \definesymbol [map] [\FontAwesomeSymbol{f279}]
- \definesymbol [map-marker] [\FontAwesomeSymbol{f041}]
- \definesymbol [map-o] [\FontAwesomeSymbol{f278}]
- \definesymbol [map-pin] [\FontAwesomeSymbol{f276}]
- \definesymbol [map-signs] [\FontAwesomeSymbol{f277}]
- \definesymbol [mars] [\FontAwesomeSymbol{f222}]
- \definesymbol [mars-double] [\FontAwesomeSymbol{f227}]
- \definesymbol [mars-stroke] [\FontAwesomeSymbol{f229}]
- \definesymbol [mars-stroke-h] [\FontAwesomeSymbol{f22b}]
- \definesymbol [mars-stroke-v] [\FontAwesomeSymbol{f22a}]
- \definesymbol [maxcdn] [\FontAwesomeSymbol{f136}]
- \definesymbol [meanpath] [\FontAwesomeSymbol{f20c}]
- \definesymbol [medium] [\FontAwesomeSymbol{f23a}]
- \definesymbol [medkit] [\FontAwesomeSymbol{f0fa}]
- \definesymbol [meh-o] [\FontAwesomeSymbol{f11a}]
- \definesymbol [mercury] [\FontAwesomeSymbol{f223}]
- \definesymbol [microphone] [\FontAwesomeSymbol{f130}]
- \definesymbol [microphone-slash] [\FontAwesomeSymbol{f131}]
- \definesymbol [minus] [\FontAwesomeSymbol{f068}]
- \definesymbol [minus-circle] [\FontAwesomeSymbol{f056}]
- \definesymbol [minus-square] [\FontAwesomeSymbol{f146}]
- \definesymbol [minus-square-o] [\FontAwesomeSymbol{f147}]
- \definesymbol [mixcloud] [\FontAwesomeSymbol{f289}]
- \definesymbol [mobile] [\FontAwesomeSymbol{f10b}]
- \definesymbol [mobile-phone] [\FontAwesomeSymbol{f10b}]
- \definesymbol [modx] [\FontAwesomeSymbol{f285}]
- \definesymbol [money] [\FontAwesomeSymbol{f0d6}]
- \definesymbol [moon-o] [\FontAwesomeSymbol{f186}]
- \definesymbol [mortar-board] [\FontAwesomeSymbol{f19d}]
- \definesymbol [motorcycle] [\FontAwesomeSymbol{f21c}]
- \definesymbol [mouse-pointer] [\FontAwesomeSymbol{f245}]
- \definesymbol [music] [\FontAwesomeSymbol{f001}]
- \definesymbol [navicon] [\FontAwesomeSymbol{f0c9}]
- \definesymbol [neuter] [\FontAwesomeSymbol{f22c}]
- \definesymbol [newspaper-o] [\FontAwesomeSymbol{f1ea}]
- \definesymbol [object-group] [\FontAwesomeSymbol{f247}]
- \definesymbol [object-ungroup] [\FontAwesomeSymbol{f248}]
- \definesymbol [odnoklassniki] [\FontAwesomeSymbol{f263}]
- \definesymbol [odnoklassniki-square] [\FontAwesomeSymbol{f264}]
- \definesymbol [opencart] [\FontAwesomeSymbol{f23d}]
- \definesymbol [openid] [\FontAwesomeSymbol{f19b}]
- \definesymbol [opera] [\FontAwesomeSymbol{f26a}]
- \definesymbol [optin-monster] [\FontAwesomeSymbol{f23c}]
- \definesymbol [outdent] [\FontAwesomeSymbol{f03b}]
- \definesymbol [pagelines] [\FontAwesomeSymbol{f18c}]
- \definesymbol [paint-brush] [\FontAwesomeSymbol{f1fc}]
- \definesymbol [paper-plane] [\FontAwesomeSymbol{f1d8}]
- \definesymbol [paper-plane-o] [\FontAwesomeSymbol{f1d9}]
- \definesymbol [paperclip] [\FontAwesomeSymbol{f0c6}]
- \definesymbol [paragraph] [\FontAwesomeSymbol{f1dd}]
- \definesymbol [paste] [\FontAwesomeSymbol{f0ea}]
- \definesymbol [pause] [\FontAwesomeSymbol{f04c}]
- \definesymbol [pause-circle] [\FontAwesomeSymbol{f28b}]
- \definesymbol [pause-circle-o] [\FontAwesomeSymbol{f28c}]
- \definesymbol [paw] [\FontAwesomeSymbol{f1b0}]
- \definesymbol [paypal] [\FontAwesomeSymbol{f1ed}]
- \definesymbol [pencil] [\FontAwesomeSymbol{f040}]
- \definesymbol [pencil-square] [\FontAwesomeSymbol{f14b}]
- \definesymbol [pencil-square-o] [\FontAwesomeSymbol{f044}]
- \definesymbol [percent] [\FontAwesomeSymbol{f295}]
- \definesymbol [phone] [\FontAwesomeSymbol{f095}]
- \definesymbol [phone-square] [\FontAwesomeSymbol{f098}]
- \definesymbol [photo] [\FontAwesomeSymbol{f03e}]
- \definesymbol [picture-o] [\FontAwesomeSymbol{f03e}]
- \definesymbol [pie-chart] [\FontAwesomeSymbol{f200}]
- \definesymbol [pied-piper] [\FontAwesomeSymbol{f2ae}]
- \definesymbol [pied-piper-alt] [\FontAwesomeSymbol{f1a8}]
- \definesymbol [pied-piper-pp] [\FontAwesomeSymbol{f1a7}]
- \definesymbol [pinterest] [\FontAwesomeSymbol{f0d2}]
- \definesymbol [pinterest-p] [\FontAwesomeSymbol{f231}]
- \definesymbol [pinterest-square] [\FontAwesomeSymbol{f0d3}]
- \definesymbol [plane] [\FontAwesomeSymbol{f072}]
- \definesymbol [play] [\FontAwesomeSymbol{f04b}]
- \definesymbol [play-circle] [\FontAwesomeSymbol{f144}]
- \definesymbol [play-circle-o] [\FontAwesomeSymbol{f01d}]
- \definesymbol [plug] [\FontAwesomeSymbol{f1e6}]
- \definesymbol [plus] [\FontAwesomeSymbol{f067}]
- \definesymbol [plus-circle] [\FontAwesomeSymbol{f055}]
- \definesymbol [plus-square] [\FontAwesomeSymbol{f0fe}]
- \definesymbol [plus-square-o] [\FontAwesomeSymbol{f196}]
- \definesymbol [power-off] [\FontAwesomeSymbol{f011}]
- \definesymbol [print] [\FontAwesomeSymbol{f02f}]
- \definesymbol [product-hunt] [\FontAwesomeSymbol{f288}]
- \definesymbol [puzzle-piece] [\FontAwesomeSymbol{f12e}]
- \definesymbol [qq] [\FontAwesomeSymbol{f1d6}]
- \definesymbol [qrcode] [\FontAwesomeSymbol{f029}]
- \definesymbol [question] [\FontAwesomeSymbol{f128}]
- \definesymbol [question-circle] [\FontAwesomeSymbol{f059}]
- \definesymbol [question-circle-o] [\FontAwesomeSymbol{f29c}]
- \definesymbol [quote-left] [\FontAwesomeSymbol{f10d}]
- \definesymbol [quote-right] [\FontAwesomeSymbol{f10e}]
- \definesymbol [ra] [\FontAwesomeSymbol{f1d0}]
- \definesymbol [random] [\FontAwesomeSymbol{f074}]
- \definesymbol [rebel] [\FontAwesomeSymbol{f1d0}]
- \definesymbol [recycle] [\FontAwesomeSymbol{f1b8}]
- \definesymbol [reddit] [\FontAwesomeSymbol{f1a1}]
- \definesymbol [reddit-alien] [\FontAwesomeSymbol{f281}]
- \definesymbol [reddit-square] [\FontAwesomeSymbol{f1a2}]
- \definesymbol [refresh] [\FontAwesomeSymbol{f021}]
- \definesymbol [registered] [\FontAwesomeSymbol{f25d}]
- \definesymbol [remove] [\FontAwesomeSymbol{f00d}]
- \definesymbol [renren] [\FontAwesomeSymbol{f18b}]
- \definesymbol [reorder] [\FontAwesomeSymbol{f0c9}]
- \definesymbol [repeat] [\FontAwesomeSymbol{f01e}]
- \definesymbol [reply] [\FontAwesomeSymbol{f112}]
- \definesymbol [reply-all] [\FontAwesomeSymbol{f122}]
- \definesymbol [resistance] [\FontAwesomeSymbol{f1d0}]
- \definesymbol [retweet] [\FontAwesomeSymbol{f079}]
- \definesymbol [rmb] [\FontAwesomeSymbol{f157}]
- \definesymbol [road] [\FontAwesomeSymbol{f018}]
- \definesymbol [rocket] [\FontAwesomeSymbol{f135}]
- \definesymbol [rotate-left] [\FontAwesomeSymbol{f0e2}]
- \definesymbol [rotate-right] [\FontAwesomeSymbol{f01e}]
- \definesymbol [rouble] [\FontAwesomeSymbol{f158}]
- \definesymbol [rss] [\FontAwesomeSymbol{f09e}]
- \definesymbol [rss-square] [\FontAwesomeSymbol{f143}]
- \definesymbol [rub] [\FontAwesomeSymbol{f158}]
- \definesymbol [ruble] [\FontAwesomeSymbol{f158}]
- \definesymbol [rupee] [\FontAwesomeSymbol{f156}]
- \definesymbol [safari] [\FontAwesomeSymbol{f267}]
- \definesymbol [save] [\FontAwesomeSymbol{f0c7}]
- \definesymbol [scissors] [\FontAwesomeSymbol{f0c4}]
- \definesymbol [scribd] [\FontAwesomeSymbol{f28a}]
- \definesymbol [search] [\FontAwesomeSymbol{f002}]
- \definesymbol [search-minus] [\FontAwesomeSymbol{f010}]
- \definesymbol [search-plus] [\FontAwesomeSymbol{f00e}]
- \definesymbol [sellsy] [\FontAwesomeSymbol{f213}]
- \definesymbol [send] [\FontAwesomeSymbol{f1d8}]
- \definesymbol [send-o] [\FontAwesomeSymbol{f1d9}]
- \definesymbol [server] [\FontAwesomeSymbol{f233}]
- \definesymbol [share] [\FontAwesomeSymbol{f064}]
- \definesymbol [share-alt] [\FontAwesomeSymbol{f1e0}]
- \definesymbol [share-alt-square] [\FontAwesomeSymbol{f1e1}]
- \definesymbol [share-square] [\FontAwesomeSymbol{f14d}]
- \definesymbol [share-square-o] [\FontAwesomeSymbol{f045}]
- \definesymbol [shekel] [\FontAwesomeSymbol{f20b}]
- \definesymbol [sheqel] [\FontAwesomeSymbol{f20b}]
- \definesymbol [shield] [\FontAwesomeSymbol{f132}]
- \definesymbol [ship] [\FontAwesomeSymbol{f21a}]
- \definesymbol [shirtsinbulk] [\FontAwesomeSymbol{f214}]
- \definesymbol [shopping-bag] [\FontAwesomeSymbol{f290}]
- \definesymbol [shopping-basket] [\FontAwesomeSymbol{f291}]
- \definesymbol [shopping-cart] [\FontAwesomeSymbol{f07a}]
- \definesymbol [sign-in] [\FontAwesomeSymbol{f090}]
- \definesymbol [sign-language] [\FontAwesomeSymbol{f2a7}]
- \definesymbol [sign-out] [\FontAwesomeSymbol{f08b}]
- \definesymbol [signal] [\FontAwesomeSymbol{f012}]
- \definesymbol [signing] [\FontAwesomeSymbol{f2a7}]
- \definesymbol [simplybuilt] [\FontAwesomeSymbol{f215}]
- \definesymbol [sitemap] [\FontAwesomeSymbol{f0e8}]
- \definesymbol [skyatlas] [\FontAwesomeSymbol{f216}]
- \definesymbol [skype] [\FontAwesomeSymbol{f17e}]
- \definesymbol [slack] [\FontAwesomeSymbol{f198}]
- \definesymbol [sliders] [\FontAwesomeSymbol{f1de}]
- \definesymbol [slideshare] [\FontAwesomeSymbol{f1e7}]
- \definesymbol [smile-o] [\FontAwesomeSymbol{f118}]
- \definesymbol [snapchat] [\FontAwesomeSymbol{f2ab}]
- \definesymbol [snapchat-ghost] [\FontAwesomeSymbol{f2ac}]
- \definesymbol [snapchat-square] [\FontAwesomeSymbol{f2ad}]
- \definesymbol [soccer-ball-o] [\FontAwesomeSymbol{f1e3}]
- \definesymbol [sort] [\FontAwesomeSymbol{f0dc}]
- \definesymbol [sort-alpha-asc] [\FontAwesomeSymbol{f15d}]
- \definesymbol [sort-alpha-desc] [\FontAwesomeSymbol{f15e}]
- \definesymbol [sort-amount-asc] [\FontAwesomeSymbol{f160}]
- \definesymbol [sort-amount-desc] [\FontAwesomeSymbol{f161}]
- \definesymbol [sort-asc] [\FontAwesomeSymbol{f0de}]
- \definesymbol [sort-desc] [\FontAwesomeSymbol{f0dd}]
- \definesymbol [sort-down] [\FontAwesomeSymbol{f0dd}]
- \definesymbol [sort-numeric-asc] [\FontAwesomeSymbol{f162}]
- \definesymbol [sort-numeric-desc] [\FontAwesomeSymbol{f163}]
- \definesymbol [sort-up] [\FontAwesomeSymbol{f0de}]
- \definesymbol [soundcloud] [\FontAwesomeSymbol{f1be}]
- \definesymbol [space-shuttle] [\FontAwesomeSymbol{f197}]
- \definesymbol [spinner] [\FontAwesomeSymbol{f110}]
- \definesymbol [spoon] [\FontAwesomeSymbol{f1b1}]
- \definesymbol [spotify] [\FontAwesomeSymbol{f1bc}]
- \definesymbol [square] [\FontAwesomeSymbol{f0c8}]
- \definesymbol [square-o] [\FontAwesomeSymbol{f096}]
- \definesymbol [stack-exchange] [\FontAwesomeSymbol{f18d}]
- \definesymbol [stack-overflow] [\FontAwesomeSymbol{f16c}]
- \definesymbol [star] [\FontAwesomeSymbol{f005}]
- \definesymbol [star-half] [\FontAwesomeSymbol{f089}]
- \definesymbol [star-half-empty] [\FontAwesomeSymbol{f123}]
- \definesymbol [star-half-full] [\FontAwesomeSymbol{f123}]
- \definesymbol [star-half-o] [\FontAwesomeSymbol{f123}]
- \definesymbol [star-o] [\FontAwesomeSymbol{f006}]
- \definesymbol [steam] [\FontAwesomeSymbol{f1b6}]
- \definesymbol [steam-square] [\FontAwesomeSymbol{f1b7}]
- \definesymbol [step-backward] [\FontAwesomeSymbol{f048}]
- \definesymbol [step-forward] [\FontAwesomeSymbol{f051}]
- \definesymbol [stethoscope] [\FontAwesomeSymbol{f0f1}]
- \definesymbol [sticky-note] [\FontAwesomeSymbol{f249}]
- \definesymbol [sticky-note-o] [\FontAwesomeSymbol{f24a}]
- \definesymbol [stop] [\FontAwesomeSymbol{f04d}]
- \definesymbol [stop-circle] [\FontAwesomeSymbol{f28d}]
- \definesymbol [stop-circle-o] [\FontAwesomeSymbol{f28e}]
- \definesymbol [street-view] [\FontAwesomeSymbol{f21d}]
- \definesymbol [strikethrough] [\FontAwesomeSymbol{f0cc}]
- \definesymbol [stumbleupon] [\FontAwesomeSymbol{f1a4}]
- \definesymbol [stumbleupon-circle] [\FontAwesomeSymbol{f1a3}]
- \definesymbol [subscript] [\FontAwesomeSymbol{f12c}]
- \definesymbol [subway] [\FontAwesomeSymbol{f239}]
- \definesymbol [suitcase] [\FontAwesomeSymbol{f0f2}]
- \definesymbol [sun-o] [\FontAwesomeSymbol{f185}]
- \definesymbol [superscript] [\FontAwesomeSymbol{f12b}]
- \definesymbol [support] [\FontAwesomeSymbol{f1cd}]
- \definesymbol [table] [\FontAwesomeSymbol{f0ce}]
- \definesymbol [tablet] [\FontAwesomeSymbol{f10a}]
- \definesymbol [tachometer] [\FontAwesomeSymbol{f0e4}]
- \definesymbol [tag] [\FontAwesomeSymbol{f02b}]
- \definesymbol [tags] [\FontAwesomeSymbol{f02c}]
- \definesymbol [tasks] [\FontAwesomeSymbol{f0ae}]
- \definesymbol [taxi] [\FontAwesomeSymbol{f1ba}]
- \definesymbol [television] [\FontAwesomeSymbol{f26c}]
- \definesymbol [tencent-weibo] [\FontAwesomeSymbol{f1d5}]
- \definesymbol [terminal] [\FontAwesomeSymbol{f120}]
- \definesymbol [text-height] [\FontAwesomeSymbol{f034}]
- \definesymbol [text-width] [\FontAwesomeSymbol{f035}]
- \definesymbol [th] [\FontAwesomeSymbol{f00a}]
- \definesymbol [th-large] [\FontAwesomeSymbol{f009}]
- \definesymbol [th-list] [\FontAwesomeSymbol{f00b}]
- \definesymbol [themeisle] [\FontAwesomeSymbol{f2b2}]
- \definesymbol [thumb-tack] [\FontAwesomeSymbol{f08d}]
- \definesymbol [thumbs-down] [\FontAwesomeSymbol{f165}]
- \definesymbol [thumbs-o-down] [\FontAwesomeSymbol{f088}]
- \definesymbol [thumbs-o-up] [\FontAwesomeSymbol{f087}]
- \definesymbol [thumbs-up] [\FontAwesomeSymbol{f164}]
- \definesymbol [ticket] [\FontAwesomeSymbol{f145}]
- \definesymbol [times] [\FontAwesomeSymbol{f00d}]
- \definesymbol [times-circle] [\FontAwesomeSymbol{f057}]
- \definesymbol [times-circle-o] [\FontAwesomeSymbol{f05c}]
- \definesymbol [tint] [\FontAwesomeSymbol{f043}]
- \definesymbol [toggle-down] [\FontAwesomeSymbol{f150}]
- \definesymbol [toggle-left] [\FontAwesomeSymbol{f191}]
- \definesymbol [toggle-off] [\FontAwesomeSymbol{f204}]
- \definesymbol [toggle-on] [\FontAwesomeSymbol{f205}]
- \definesymbol [toggle-right] [\FontAwesomeSymbol{f152}]
- \definesymbol [toggle-up] [\FontAwesomeSymbol{f151}]
- \definesymbol [trademark] [\FontAwesomeSymbol{f25c}]
- \definesymbol [train] [\FontAwesomeSymbol{f238}]
- \definesymbol [transgender] [\FontAwesomeSymbol{f224}]
- \definesymbol [transgender-alt] [\FontAwesomeSymbol{f225}]
- \definesymbol [trash] [\FontAwesomeSymbol{f1f8}]
- \definesymbol [trash-o] [\FontAwesomeSymbol{f014}]
- \definesymbol [tree] [\FontAwesomeSymbol{f1bb}]
- \definesymbol [trello] [\FontAwesomeSymbol{f181}]
- \definesymbol [tripadvisor] [\FontAwesomeSymbol{f262}]
- \definesymbol [trophy] [\FontAwesomeSymbol{f091}]
- \definesymbol [truck] [\FontAwesomeSymbol{f0d1}]
- \definesymbol [try] [\FontAwesomeSymbol{f195}]
- \definesymbol [tty] [\FontAwesomeSymbol{f1e4}]
- \definesymbol [tumblr] [\FontAwesomeSymbol{f173}]
- \definesymbol [tumblr-square] [\FontAwesomeSymbol{f174}]
- \definesymbol [turkish-lira] [\FontAwesomeSymbol{f195}]
- \definesymbol [tv] [\FontAwesomeSymbol{f26c}]
- \definesymbol [twitch] [\FontAwesomeSymbol{f1e8}]
- \definesymbol [twitter] [\FontAwesomeSymbol{f099}]
- \definesymbol [twitter-square] [\FontAwesomeSymbol{f081}]
- \definesymbol [umbrella] [\FontAwesomeSymbol{f0e9}]
- \definesymbol [underline] [\FontAwesomeSymbol{f0cd}]
- \definesymbol [undo] [\FontAwesomeSymbol{f0e2}]
- \definesymbol [universal-access] [\FontAwesomeSymbol{f29a}]
- \definesymbol [university] [\FontAwesomeSymbol{f19c}]
- \definesymbol [unlink] [\FontAwesomeSymbol{f127}]
- \definesymbol [unlock] [\FontAwesomeSymbol{f09c}]
- \definesymbol [unlock-alt] [\FontAwesomeSymbol{f13e}]
- \definesymbol [unsorted] [\FontAwesomeSymbol{f0dc}]
- \definesymbol [upload] [\FontAwesomeSymbol{f093}]
- \definesymbol [usb] [\FontAwesomeSymbol{f287}]
- \definesymbol [usd] [\FontAwesomeSymbol{f155}]
- \definesymbol [user] [\FontAwesomeSymbol{f007}]
- \definesymbol [user-md] [\FontAwesomeSymbol{f0f0}]
- \definesymbol [user-plus] [\FontAwesomeSymbol{f234}]
- \definesymbol [user-secret] [\FontAwesomeSymbol{f21b}]
- \definesymbol [user-times] [\FontAwesomeSymbol{f235}]
- \definesymbol [users] [\FontAwesomeSymbol{f0c0}]
- \definesymbol [venus] [\FontAwesomeSymbol{f221}]
- \definesymbol [venus-double] [\FontAwesomeSymbol{f226}]
- \definesymbol [venus-mars] [\FontAwesomeSymbol{f228}]
- \definesymbol [viacoin] [\FontAwesomeSymbol{f237}]
- \definesymbol [viadeo] [\FontAwesomeSymbol{f2a9}]
- \definesymbol [viadeo-square] [\FontAwesomeSymbol{f2aa}]
- \definesymbol [video-camera] [\FontAwesomeSymbol{f03d}]
- \definesymbol [vimeo] [\FontAwesomeSymbol{f27d}]
- \definesymbol [vimeo-square] [\FontAwesomeSymbol{f194}]
- \definesymbol [vine] [\FontAwesomeSymbol{f1ca}]
- \definesymbol [vk] [\FontAwesomeSymbol{f189}]
- \definesymbol [volume-control-phone] [\FontAwesomeSymbol{f2a0}]
- \definesymbol [volume-down] [\FontAwesomeSymbol{f027}]
- \definesymbol [volume-off] [\FontAwesomeSymbol{f026}]
- \definesymbol [volume-up] [\FontAwesomeSymbol{f028}]
- \definesymbol [warning] [\FontAwesomeSymbol{f071}]
- \definesymbol [wechat] [\FontAwesomeSymbol{f1d7}]
- \definesymbol [weibo] [\FontAwesomeSymbol{f18a}]
- \definesymbol [weixin] [\FontAwesomeSymbol{f1d7}]
- \definesymbol [whatsapp] [\FontAwesomeSymbol{f232}]
- \definesymbol [wheelchair] [\FontAwesomeSymbol{f193}]
- \definesymbol [wheelchair-alt] [\FontAwesomeSymbol{f29b}]
- \definesymbol [wifi] [\FontAwesomeSymbol{f1eb}]
- \definesymbol [wikipedia-w] [\FontAwesomeSymbol{f266}]
- \definesymbol [windows] [\FontAwesomeSymbol{f17a}]
- \definesymbol [won] [\FontAwesomeSymbol{f159}]
- \definesymbol [wordpress] [\FontAwesomeSymbol{f19a}]
- \definesymbol [wpbeginner] [\FontAwesomeSymbol{f297}]
- \definesymbol [wpforms] [\FontAwesomeSymbol{f298}]
- \definesymbol [wrench] [\FontAwesomeSymbol{f0ad}]
- \definesymbol [xing] [\FontAwesomeSymbol{f168}]
- \definesymbol [xing-square] [\FontAwesomeSymbol{f169}]
- \definesymbol [y-combinator] [\FontAwesomeSymbol{f23b}]
- \definesymbol [y-combinator-square] [\FontAwesomeSymbol{f1d4}]
- \definesymbol [yahoo] [\FontAwesomeSymbol{f19e}]
- \definesymbol [yc] [\FontAwesomeSymbol{f23b}]
- \definesymbol [yc-square] [\FontAwesomeSymbol{f1d4}]
- \definesymbol [yelp] [\FontAwesomeSymbol{f1e9}]
- \definesymbol [yen] [\FontAwesomeSymbol{f157}]
- \definesymbol [yoast] [\FontAwesomeSymbol{f2b1}]
- \definesymbol [youtube] [\FontAwesomeSymbol{f167}]
- \definesymbol [youtube-play] [\FontAwesomeSymbol{f16a}]
- \definesymbol [youtube-square] [\FontAwesomeSymbol{f166}]
+ \definesymbol [wheelchair] [\FontAwesomeSymbol{_378}]
+% \definesymbol [500px] [\FontAwesomeSymbol{f26e}]
+% \definesymbol [adjust] [\FontAwesomeSymbol{f042}]
+% \definesymbol [adn] [\FontAwesomeSymbol{f170}]
+% \definesymbol [align-center] [\FontAwesomeSymbol{f037}]
+% \definesymbol [align-justify] [\FontAwesomeSymbol{f039}]
+% \definesymbol [align-left] [\FontAwesomeSymbol{f036}]
+% \definesymbol [align-right] [\FontAwesomeSymbol{f038}]
+% \definesymbol [amazon] [\FontAwesomeSymbol{f270}]
+% \definesymbol [ambulance] [\FontAwesomeSymbol{f0f9}]
+% \definesymbol [american-sign-language-interpreting] [\FontAwesomeSymbol{f2a3}]
+% \definesymbol [anchor] [\FontAwesomeSymbol{f13d}]
+% \definesymbol [android] [\FontAwesomeSymbol{f17b}]
+% \definesymbol [angellist] [\FontAwesomeSymbol{f209}]
+% \definesymbol [angle-double-down] [\FontAwesomeSymbol{f103}]
+% \definesymbol [angle-double-left] [\FontAwesomeSymbol{f100}]
+% \definesymbol [angle-double-right] [\FontAwesomeSymbol{f101}]
+% \definesymbol [angle-double-up] [\FontAwesomeSymbol{f102}]
+% \definesymbol [angle-down] [\FontAwesomeSymbol{f107}]
+% \definesymbol [angle-left] [\FontAwesomeSymbol{f104}]
+% \definesymbol [angle-right] [\FontAwesomeSymbol{f105}]
+% \definesymbol [angle-up] [\FontAwesomeSymbol{f106}]
+% \definesymbol [apple] [\FontAwesomeSymbol{f179}]
+% \definesymbol [archive] [\FontAwesomeSymbol{f187}]
+% \definesymbol [area-chart] [\FontAwesomeSymbol{f1fe}]
+% \definesymbol [arrow-circle-down] [\FontAwesomeSymbol{f0ab}]
+% \definesymbol [arrow-circle-left] [\FontAwesomeSymbol{f0a8}]
+% \definesymbol [arrow-circle-o-down] [\FontAwesomeSymbol{f01a}]
+% \definesymbol [arrow-circle-o-left] [\FontAwesomeSymbol{f190}]
+% \definesymbol [arrow-circle-o-right] [\FontAwesomeSymbol{f18e}]
+% \definesymbol [arrow-circle-o-up] [\FontAwesomeSymbol{f01b}]
+% \definesymbol [arrow-circle-right] [\FontAwesomeSymbol{f0a9}]
+% \definesymbol [arrow-circle-up] [\FontAwesomeSymbol{f0aa}]
+% \definesymbol [arrow-down] [\FontAwesomeSymbol{f063}]
+% \definesymbol [arrow-left] [\FontAwesomeSymbol{f060}]
+% \definesymbol [arrow-right] [\FontAwesomeSymbol{f061}]
+% \definesymbol [arrow-up] [\FontAwesomeSymbol{f062}]
+% \definesymbol [arrows] [\FontAwesomeSymbol{f047}]
+% \definesymbol [arrows-alt] [\FontAwesomeSymbol{f0b2}]
+% \definesymbol [arrows-h] [\FontAwesomeSymbol{f07e}]
+% \definesymbol [arrows-v] [\FontAwesomeSymbol{f07d}]
+% \definesymbol [asl-interpreting] [\FontAwesomeSymbol{f2a3}]
+% \definesymbol [assistive-listening-systems] [\FontAwesomeSymbol{f2a2}]
+% \definesymbol [asterisk] [\FontAwesomeSymbol{f069}]
+% \definesymbol [at] [\FontAwesomeSymbol{f1fa}]
+% \definesymbol [audio-description] [\FontAwesomeSymbol{f29e}]
+% \definesymbol [automobile] [\FontAwesomeSymbol{f1b9}]
+% \definesymbol [backward] [\FontAwesomeSymbol{f04a}]
+% \definesymbol [balance-scale] [\FontAwesomeSymbol{f24e}]
+% \definesymbol [ban] [\FontAwesomeSymbol{f05e}]
+% \definesymbol [bank] [\FontAwesomeSymbol{f19c}]
+% \definesymbol [bar-chart] [\FontAwesomeSymbol{f080}]
+% \definesymbol [bar-chart-o] [\FontAwesomeSymbol{f080}]
+% \definesymbol [barcode] [\FontAwesomeSymbol{f02a}]
+% \definesymbol [bars] [\FontAwesomeSymbol{f0c9}]
+% \definesymbol [battery-0] [\FontAwesomeSymbol{f244}]
+% \definesymbol [battery-1] [\FontAwesomeSymbol{f243}]
+% \definesymbol [battery-2] [\FontAwesomeSymbol{f242}]
+% \definesymbol [battery-3] [\FontAwesomeSymbol{f241}]
+% \definesymbol [battery-4] [\FontAwesomeSymbol{f240}]
+% \definesymbol [battery-empty] [\FontAwesomeSymbol{f244}]
+% \definesymbol [battery-full] [\FontAwesomeSymbol{f240}]
+% \definesymbol [battery-half] [\FontAwesomeSymbol{f242}]
+% \definesymbol [battery-quarter] [\FontAwesomeSymbol{f243}]
+% \definesymbol [battery-three-quarters] [\FontAwesomeSymbol{f241}]
+% \definesymbol [bed] [\FontAwesomeSymbol{f236}]
+% \definesymbol [beer] [\FontAwesomeSymbol{f0fc}]
+% \definesymbol [behance] [\FontAwesomeSymbol{f1b4}]
+% \definesymbol [behance-square] [\FontAwesomeSymbol{f1b5}]
+% \definesymbol [bell] [\FontAwesomeSymbol{f0f3}]
+% \definesymbol [bell-o] [\FontAwesomeSymbol{f0a2}]
+% \definesymbol [bell-slash] [\FontAwesomeSymbol{f1f6}]
+% \definesymbol [bell-slash-o] [\FontAwesomeSymbol{f1f7}]
+% \definesymbol [bicycle] [\FontAwesomeSymbol{f206}]
+% \definesymbol [binoculars] [\FontAwesomeSymbol{f1e5}]
+% \definesymbol [birthday-cake] [\FontAwesomeSymbol{f1fd}]
+% \definesymbol [bitbucket] [\FontAwesomeSymbol{f171}]
+% \definesymbol [bitbucket-square] [\FontAwesomeSymbol{f172}]
+% \definesymbol [bitcoin] [\FontAwesomeSymbol{f15a}]
+% \definesymbol [black-tie] [\FontAwesomeSymbol{f27e}]
+% \definesymbol [blind] [\FontAwesomeSymbol{f29d}]
+% \definesymbol [bluetooth] [\FontAwesomeSymbol{f293}]
+% \definesymbol [bluetooth-b] [\FontAwesomeSymbol{f294}]
+% \definesymbol [bold] [\FontAwesomeSymbol{f032}]
+% \definesymbol [bolt] [\FontAwesomeSymbol{f0e7}]
+% \definesymbol [bomb] [\FontAwesomeSymbol{f1e2}]
+% \definesymbol [book] [\FontAwesomeSymbol{f02d}]
+% \definesymbol [bookmark] [\FontAwesomeSymbol{f02e}]
+% \definesymbol [bookmark-o] [\FontAwesomeSymbol{f097}]
+% \definesymbol [braille] [\FontAwesomeSymbol{f2a1}]
+% \definesymbol [briefcase] [\FontAwesomeSymbol{f0b1}]
+% \definesymbol [btc] [\FontAwesomeSymbol{f15a}]
+% \definesymbol [bug] [\FontAwesomeSymbol{f188}]
+% \definesymbol [building] [\FontAwesomeSymbol{f1ad}]
+% \definesymbol [building-o] [\FontAwesomeSymbol{f0f7}]
+% \definesymbol [bullhorn] [\FontAwesomeSymbol{f0a1}]
+% \definesymbol [bullseye] [\FontAwesomeSymbol{f140}]
+% \definesymbol [bus] [\FontAwesomeSymbol{f207}]
+% \definesymbol [buysellads] [\FontAwesomeSymbol{f20d}]
+% \definesymbol [cab] [\FontAwesomeSymbol{f1ba}]
+% \definesymbol [calculator] [\FontAwesomeSymbol{f1ec}]
+% \definesymbol [calendar] [\FontAwesomeSymbol{f073}]
+% \definesymbol [calendar-check-o] [\FontAwesomeSymbol{f274}]
+% \definesymbol [calendar-minus-o] [\FontAwesomeSymbol{f272}]
+% \definesymbol [calendar-o] [\FontAwesomeSymbol{f133}]
+% \definesymbol [calendar-plus-o] [\FontAwesomeSymbol{f271}]
+% \definesymbol [calendar-times-o] [\FontAwesomeSymbol{f273}]
+% \definesymbol [camera] [\FontAwesomeSymbol{f030}]
+% \definesymbol [camera-retro] [\FontAwesomeSymbol{f083}]
+% \definesymbol [car] [\FontAwesomeSymbol{f1b9}]
+% \definesymbol [caret-down] [\FontAwesomeSymbol{f0d7}]
+% \definesymbol [caret-left] [\FontAwesomeSymbol{f0d9}]
+% \definesymbol [caret-right] [\FontAwesomeSymbol{f0da}]
+% \definesymbol [caret-square-o-down] [\FontAwesomeSymbol{f150}]
+% \definesymbol [caret-square-o-left] [\FontAwesomeSymbol{f191}]
+% \definesymbol [caret-square-o-right] [\FontAwesomeSymbol{f152}]
+% \definesymbol [caret-square-o-up] [\FontAwesomeSymbol{f151}]
+% \definesymbol [caret-up] [\FontAwesomeSymbol{f0d8}]
+% \definesymbol [cart-arrow-down] [\FontAwesomeSymbol{f218}]
+% \definesymbol [cart-plus] [\FontAwesomeSymbol{f217}]
+% \definesymbol [cc] [\FontAwesomeSymbol{f20a}]
+% \definesymbol [cc-amex] [\FontAwesomeSymbol{f1f3}]
+% \definesymbol [cc-diners-club] [\FontAwesomeSymbol{f24c}]
+% \definesymbol [cc-discover] [\FontAwesomeSymbol{f1f2}]
+% \definesymbol [cc-jcb] [\FontAwesomeSymbol{f24b}]
+% \definesymbol [cc-mastercard] [\FontAwesomeSymbol{f1f1}]
+% \definesymbol [cc-paypal] [\FontAwesomeSymbol{f1f4}]
+% \definesymbol [cc-stripe] [\FontAwesomeSymbol{f1f5}]
+% \definesymbol [cc-visa] [\FontAwesomeSymbol{f1f0}]
+% \definesymbol [certificate] [\FontAwesomeSymbol{f0a3}]
+% \definesymbol [chain] [\FontAwesomeSymbol{f0c1}]
+% \definesymbol [chain-broken] [\FontAwesomeSymbol{f127}]
+% \definesymbol [check] [\FontAwesomeSymbol{f00c}]
+% \definesymbol [check-circle] [\FontAwesomeSymbol{f058}]
+% \definesymbol [check-circle-o] [\FontAwesomeSymbol{f05d}]
+% \definesymbol [check-square] [\FontAwesomeSymbol{f14a}]
+% \definesymbol [check-square-o] [\FontAwesomeSymbol{f046}]
+% \definesymbol [chevron-circle-down] [\FontAwesomeSymbol{f13a}]
+% \definesymbol [chevron-circle-left] [\FontAwesomeSymbol{f137}]
+% \definesymbol [chevron-circle-right] [\FontAwesomeSymbol{f138}]
+% \definesymbol [chevron-circle-up] [\FontAwesomeSymbol{f139}]
+% \definesymbol [chevron-down] [\FontAwesomeSymbol{f078}]
+% \definesymbol [chevron-left] [\FontAwesomeSymbol{f053}]
+% \definesymbol [chevron-right] [\FontAwesomeSymbol{f054}]
+% \definesymbol [chevron-up] [\FontAwesomeSymbol{f077}]
+% \definesymbol [child] [\FontAwesomeSymbol{f1ae}]
+% \definesymbol [chrome] [\FontAwesomeSymbol{f268}]
+% \definesymbol [circle] [\FontAwesomeSymbol{f111}]
+% \definesymbol [circle-o] [\FontAwesomeSymbol{f10c}]
+% \definesymbol [circle-o-notch] [\FontAwesomeSymbol{f1ce}]
+% \definesymbol [circle-thin] [\FontAwesomeSymbol{f1db}]
+% \definesymbol [clipboard] [\FontAwesomeSymbol{f0ea}]
+% \definesymbol [clock-o] [\FontAwesomeSymbol{f017}]
+% \definesymbol [clone] [\FontAwesomeSymbol{f24d}]
+% \definesymbol [close] [\FontAwesomeSymbol{f00d}]
+% \definesymbol [cloud] [\FontAwesomeSymbol{f0c2}]
+% \definesymbol [cloud-download] [\FontAwesomeSymbol{f0ed}]
+% \definesymbol [cloud-upload] [\FontAwesomeSymbol{f0ee}]
+% \definesymbol [cny] [\FontAwesomeSymbol{f157}]
+% \definesymbol [code] [\FontAwesomeSymbol{f121}]
+% \definesymbol [code-fork] [\FontAwesomeSymbol{f126}]
+% \definesymbol [codepen] [\FontAwesomeSymbol{f1cb}]
+% \definesymbol [codiepie] [\FontAwesomeSymbol{f284}]
+% \definesymbol [coffee] [\FontAwesomeSymbol{f0f4}]
+% \definesymbol [cog] [\FontAwesomeSymbol{f013}]
+% \definesymbol [cogs] [\FontAwesomeSymbol{f085}]
+% \definesymbol [columns] [\FontAwesomeSymbol{f0db}]
+% \definesymbol [comment] [\FontAwesomeSymbol{f075}]
+% \definesymbol [comment-o] [\FontAwesomeSymbol{f0e5}]
+% \definesymbol [commenting] [\FontAwesomeSymbol{f27a}]
+% \definesymbol [commenting-o] [\FontAwesomeSymbol{f27b}]
+% \definesymbol [comments] [\FontAwesomeSymbol{f086}]
+% \definesymbol [comments-o] [\FontAwesomeSymbol{f0e6}]
+% \definesymbol [compass] [\FontAwesomeSymbol{f14e}]
+% \definesymbol [compress] [\FontAwesomeSymbol{f066}]
+% \definesymbol [connectdevelop] [\FontAwesomeSymbol{f20e}]
+% \definesymbol [contao] [\FontAwesomeSymbol{f26d}]
+% \definesymbol [copy] [\FontAwesomeSymbol{f0c5}]
+% \definesymbol [copyright] [\FontAwesomeSymbol{f1f9}]
+% \definesymbol [creative-commons] [\FontAwesomeSymbol{f25e}]
+% \definesymbol [credit-card] [\FontAwesomeSymbol{f09d}]
+% \definesymbol [credit-card-alt] [\FontAwesomeSymbol{f283}]
+% \definesymbol [crop] [\FontAwesomeSymbol{f125}]
+% \definesymbol [crosshairs] [\FontAwesomeSymbol{f05b}]
+% \definesymbol [css3] [\FontAwesomeSymbol{f13c}]
+% \definesymbol [cube] [\FontAwesomeSymbol{f1b2}]
+% \definesymbol [cubes] [\FontAwesomeSymbol{f1b3}]
+% \definesymbol [cut] [\FontAwesomeSymbol{f0c4}]
+% \definesymbol [cutlery] [\FontAwesomeSymbol{f0f5}]
+% \definesymbol [dashboard] [\FontAwesomeSymbol{f0e4}]
+% \definesymbol [dashcube] [\FontAwesomeSymbol{f210}]
+% \definesymbol [database] [\FontAwesomeSymbol{f1c0}]
+% \definesymbol [deaf] [\FontAwesomeSymbol{f2a4}]
+% \definesymbol [deafness] [\FontAwesomeSymbol{f2a4}]
+% \definesymbol [dedent] [\FontAwesomeSymbol{f03b}]
+% \definesymbol [delicious] [\FontAwesomeSymbol{f1a5}]
+% \definesymbol [desktop] [\FontAwesomeSymbol{f108}]
+% \definesymbol [deviantart] [\FontAwesomeSymbol{f1bd}]
+% \definesymbol [diamond] [\FontAwesomeSymbol{f219}]
+% \definesymbol [digg] [\FontAwesomeSymbol{f1a6}]
+% \definesymbol [dollar] [\FontAwesomeSymbol{f155}]
+% \definesymbol [dot-circle-o] [\FontAwesomeSymbol{f192}]
+% \definesymbol [download] [\FontAwesomeSymbol{f019}]
+% \definesymbol [dribbble] [\FontAwesomeSymbol{f17d}]
+% \definesymbol [dropbox] [\FontAwesomeSymbol{f16b}]
+% \definesymbol [drupal] [\FontAwesomeSymbol{f1a9}]
+% \definesymbol [edge] [\FontAwesomeSymbol{f282}]
+% \definesymbol [edit] [\FontAwesomeSymbol{f044}]
+% \definesymbol [eject] [\FontAwesomeSymbol{f052}]
+% \definesymbol [ellipsis-h] [\FontAwesomeSymbol{f141}]
+% \definesymbol [ellipsis-v] [\FontAwesomeSymbol{f142}]
+% \definesymbol [empire] [\FontAwesomeSymbol{f1d1}]
+% \definesymbol [envelope] [\FontAwesomeSymbol{f0e0}]
+% \definesymbol [envelope-o] [\FontAwesomeSymbol{f003}]
+% \definesymbol [envelope-square] [\FontAwesomeSymbol{f199}]
+% \definesymbol [envira] [\FontAwesomeSymbol{f299}]
+% \definesymbol [eraser] [\FontAwesomeSymbol{f12d}]
+% \definesymbol [eur] [\FontAwesomeSymbol{f153}]
+% \definesymbol [euro] [\FontAwesomeSymbol{f153}]
+% \definesymbol [exchange] [\FontAwesomeSymbol{f0ec}]
+% \definesymbol [exclamation] [\FontAwesomeSymbol{f12a}]
+% \definesymbol [exclamation-circle] [\FontAwesomeSymbol{f06a}]
+% \definesymbol [exclamation-triangle] [\FontAwesomeSymbol{f071}]
+% \definesymbol [expand] [\FontAwesomeSymbol{f065}]
+% \definesymbol [expeditedssl] [\FontAwesomeSymbol{f23e}]
+% \definesymbol [external-link] [\FontAwesomeSymbol{f08e}]
+% \definesymbol [external-link-square] [\FontAwesomeSymbol{f14c}]
+% \definesymbol [eye] [\FontAwesomeSymbol{f06e}]
+% \definesymbol [eye-slash] [\FontAwesomeSymbol{f070}]
+% \definesymbol [eyedropper] [\FontAwesomeSymbol{f1fb}]
+% \definesymbol [fa] [\FontAwesomeSymbol{f2b4}]
+% \definesymbol [facebook] [\FontAwesomeSymbol{f09a}]
+% \definesymbol [facebook-f] [\FontAwesomeSymbol{f09a}]
+% \definesymbol [facebook-official] [\FontAwesomeSymbol{f230}]
+% \definesymbol [facebook-square] [\FontAwesomeSymbol{f082}]
+% \definesymbol [fast-backward] [\FontAwesomeSymbol{f049}]
+% \definesymbol [fast-forward] [\FontAwesomeSymbol{f050}]
+% \definesymbol [fax] [\FontAwesomeSymbol{f1ac}]
+% \definesymbol [feed] [\FontAwesomeSymbol{f09e}]
+% \definesymbol [female] [\FontAwesomeSymbol{f182}]
+% \definesymbol [fighter-jet] [\FontAwesomeSymbol{f0fb}]
+% \definesymbol [file] [\FontAwesomeSymbol{f15b}]
+% \definesymbol [file-archive-o] [\FontAwesomeSymbol{f1c6}]
+% \definesymbol [file-audio-o] [\FontAwesomeSymbol{f1c7}]
+% \definesymbol [file-code-o] [\FontAwesomeSymbol{f1c9}]
+% \definesymbol [file-excel-o] [\FontAwesomeSymbol{f1c3}]
+% \definesymbol [file-image-o] [\FontAwesomeSymbol{f1c5}]
+% \definesymbol [file-movie-o] [\FontAwesomeSymbol{f1c8}]
+% \definesymbol [file-o] [\FontAwesomeSymbol{f016}]
+% \definesymbol [file-pdf-o] [\FontAwesomeSymbol{f1c1}]
+% \definesymbol [file-photo-o] [\FontAwesomeSymbol{f1c5}]
+% \definesymbol [file-picture-o] [\FontAwesomeSymbol{f1c5}]
+% \definesymbol [file-powerpoint-o] [\FontAwesomeSymbol{f1c4}]
+% \definesymbol [file-sound-o] [\FontAwesomeSymbol{f1c7}]
+% \definesymbol [file-text] [\FontAwesomeSymbol{f15c}]
+% \definesymbol [file-text-o] [\FontAwesomeSymbol{f0f6}]
+% \definesymbol [file-video-o] [\FontAwesomeSymbol{f1c8}]
+% \definesymbol [file-word-o] [\FontAwesomeSymbol{f1c2}]
+% \definesymbol [file-zip-o] [\FontAwesomeSymbol{f1c6}]
+% \definesymbol [files-o] [\FontAwesomeSymbol{f0c5}]
+% \definesymbol [film] [\FontAwesomeSymbol{f008}]
+% \definesymbol [filter] [\FontAwesomeSymbol{f0b0}]
+% \definesymbol [fire] [\FontAwesomeSymbol{f06d}]
+% \definesymbol [fire-extinguisher] [\FontAwesomeSymbol{f134}]
+% \definesymbol [firefox] [\FontAwesomeSymbol{f269}]
+% \definesymbol [first-order] [\FontAwesomeSymbol{f2b0}]
+% \definesymbol [flag] [\FontAwesomeSymbol{f024}]
+% \definesymbol [flag-checkered] [\FontAwesomeSymbol{f11e}]
+% \definesymbol [flag-o] [\FontAwesomeSymbol{f11d}]
+% \definesymbol [flash] [\FontAwesomeSymbol{f0e7}]
+% \definesymbol [flask] [\FontAwesomeSymbol{f0c3}]
+% \definesymbol [flickr] [\FontAwesomeSymbol{f16e}]
+% \definesymbol [floppy-o] [\FontAwesomeSymbol{f0c7}]
+% \definesymbol [folder] [\FontAwesomeSymbol{f07b}]
+% \definesymbol [folder-o] [\FontAwesomeSymbol{f114}]
+% \definesymbol [folder-open] [\FontAwesomeSymbol{f07c}]
+% \definesymbol [folder-open-o] [\FontAwesomeSymbol{f115}]
+% \definesymbol [font] [\FontAwesomeSymbol{f031}]
+% \definesymbol [font-awesome] [\FontAwesomeSymbol{f2b4}]
+% \definesymbol [fonticons] [\FontAwesomeSymbol{f280}]
+% \definesymbol [fort-awesome] [\FontAwesomeSymbol{f286}]
+% \definesymbol [forumbee] [\FontAwesomeSymbol{f211}]
+% \definesymbol [forward] [\FontAwesomeSymbol{f04e}]
+% \definesymbol [foursquare] [\FontAwesomeSymbol{f180}]
+% \definesymbol [frown-o] [\FontAwesomeSymbol{f119}]
+% \definesymbol [futbol-o] [\FontAwesomeSymbol{f1e3}]
+% \definesymbol [gamepad] [\FontAwesomeSymbol{f11b}]
+% \definesymbol [gavel] [\FontAwesomeSymbol{f0e3}]
+% \definesymbol [gbp] [\FontAwesomeSymbol{f154}]
+% \definesymbol [ge] [\FontAwesomeSymbol{f1d1}]
+% \definesymbol [gear] [\FontAwesomeSymbol{f013}]
+% \definesymbol [gears] [\FontAwesomeSymbol{f085}]
+% \definesymbol [genderless] [\FontAwesomeSymbol{f22d}]
+% \definesymbol [get-pocket] [\FontAwesomeSymbol{f265}]
+% \definesymbol [gg] [\FontAwesomeSymbol{f260}]
+% \definesymbol [gg-circle] [\FontAwesomeSymbol{f261}]
+% \definesymbol [gift] [\FontAwesomeSymbol{f06b}]
+% \definesymbol [git] [\FontAwesomeSymbol{f1d3}]
+% \definesymbol [git-square] [\FontAwesomeSymbol{f1d2}]
+% \definesymbol [github] [\FontAwesomeSymbol{f09b}]
+% \definesymbol [github-alt] [\FontAwesomeSymbol{f113}]
+% \definesymbol [github-square] [\FontAwesomeSymbol{f092}]
+% \definesymbol [gitlab] [\FontAwesomeSymbol{f296}]
+% \definesymbol [gittip] [\FontAwesomeSymbol{f184}]
+% \definesymbol [glass] [\FontAwesomeSymbol{f000}]
+% \definesymbol [glide] [\FontAwesomeSymbol{f2a5}]
+% \definesymbol [glide-g] [\FontAwesomeSymbol{f2a6}]
+% \definesymbol [globe] [\FontAwesomeSymbol{f0ac}]
+% \definesymbol [google] [\FontAwesomeSymbol{f1a0}]
+% \definesymbol [google-plus] [\FontAwesomeSymbol{f0d5}]
+% \definesymbol [google-plus-circle] [\FontAwesomeSymbol{f2b3}]
+% \definesymbol [google-plus-official] [\FontAwesomeSymbol{f2b3}]
+% \definesymbol [google-plus-square] [\FontAwesomeSymbol{f0d4}]
+% \definesymbol [google-wallet] [\FontAwesomeSymbol{f1ee}]
+% \definesymbol [graduation-cap] [\FontAwesomeSymbol{f19d}]
+% \definesymbol [gratipay] [\FontAwesomeSymbol{f184}]
+% \definesymbol [group] [\FontAwesomeSymbol{f0c0}]
+% \definesymbol [h-square] [\FontAwesomeSymbol{f0fd}]
+% \definesymbol [hacker-news] [\FontAwesomeSymbol{f1d4}]
+% \definesymbol [hand-grab-o] [\FontAwesomeSymbol{f255}]
+% \definesymbol [hand-lizard-o] [\FontAwesomeSymbol{f258}]
+% \definesymbol [hand-o-down] [\FontAwesomeSymbol{f0a7}]
+% \definesymbol [hand-o-left] [\FontAwesomeSymbol{f0a5}]
+% \definesymbol [hand-o-right] [\FontAwesomeSymbol{f0a4}]
+% \definesymbol [hand-o-up] [\FontAwesomeSymbol{f0a6}]
+% \definesymbol [hand-paper-o] [\FontAwesomeSymbol{f256}]
+% \definesymbol [hand-peace-o] [\FontAwesomeSymbol{f25b}]
+% \definesymbol [hand-pointer-o] [\FontAwesomeSymbol{f25a}]
+% \definesymbol [hand-rock-o] [\FontAwesomeSymbol{f255}]
+% \definesymbol [hand-scissors-o] [\FontAwesomeSymbol{f257}]
+% \definesymbol [hand-spock-o] [\FontAwesomeSymbol{f259}]
+% \definesymbol [hand-stop-o] [\FontAwesomeSymbol{f256}]
+% \definesymbol [hard-of-hearing] [\FontAwesomeSymbol{f2a4}]
+% \definesymbol [hashtag] [\FontAwesomeSymbol{f292}]
+% \definesymbol [hdd-o] [\FontAwesomeSymbol{f0a0}]
+% \definesymbol [header] [\FontAwesomeSymbol{f1dc}]
+% \definesymbol [headphones] [\FontAwesomeSymbol{f025}]
+% \definesymbol [heart] [\FontAwesomeSymbol{f004}]
+% \definesymbol [heart-o] [\FontAwesomeSymbol{f08a}]
+% \definesymbol [heartbeat] [\FontAwesomeSymbol{f21e}]
+% \definesymbol [history] [\FontAwesomeSymbol{f1da}]
+% \definesymbol [home] [\FontAwesomeSymbol{f015}]
+% \definesymbol [hospital-o] [\FontAwesomeSymbol{f0f8}]
+% \definesymbol [hotel] [\FontAwesomeSymbol{f236}]
+% \definesymbol [hourglass] [\FontAwesomeSymbol{f254}]
+% \definesymbol [hourglass-1] [\FontAwesomeSymbol{f251}]
+% \definesymbol [hourglass-2] [\FontAwesomeSymbol{f252}]
+% \definesymbol [hourglass-3] [\FontAwesomeSymbol{f253}]
+% \definesymbol [hourglass-end] [\FontAwesomeSymbol{f253}]
+% \definesymbol [hourglass-half] [\FontAwesomeSymbol{f252}]
+% \definesymbol [hourglass-o] [\FontAwesomeSymbol{f250}]
+% \definesymbol [hourglass-start] [\FontAwesomeSymbol{f251}]
+% \definesymbol [houzz] [\FontAwesomeSymbol{f27c}]
+% \definesymbol [html5] [\FontAwesomeSymbol{f13b}]
+% \definesymbol [i-cursor] [\FontAwesomeSymbol{f246}]
+% \definesymbol [ils] [\FontAwesomeSymbol{f20b}]
+% \definesymbol [image] [\FontAwesomeSymbol{f03e}]
+% \definesymbol [inbox] [\FontAwesomeSymbol{f01c}]
+% \definesymbol [indent] [\FontAwesomeSymbol{f03c}]
+% \definesymbol [industry] [\FontAwesomeSymbol{f275}]
+% \definesymbol [info] [\FontAwesomeSymbol{f129}]
+% \definesymbol [info-circle] [\FontAwesomeSymbol{f05a}]
+% \definesymbol [inr] [\FontAwesomeSymbol{f156}]
+% \definesymbol [instagram] [\FontAwesomeSymbol{f16d}]
+% \definesymbol [institution] [\FontAwesomeSymbol{f19c}]
+% \definesymbol [internet-explorer] [\FontAwesomeSymbol{f26b}]
+% \definesymbol [intersex] [\FontAwesomeSymbol{f224}]
+% \definesymbol [ioxhost] [\FontAwesomeSymbol{f208}]
+% \definesymbol [italic] [\FontAwesomeSymbol{f033}]
+% \definesymbol [joomla] [\FontAwesomeSymbol{f1aa}]
+% \definesymbol [jpy] [\FontAwesomeSymbol{f157}]
+% \definesymbol [jsfiddle] [\FontAwesomeSymbol{f1cc}]
+% \definesymbol [key] [\FontAwesomeSymbol{f084}]
+% \definesymbol [keyboard-o] [\FontAwesomeSymbol{f11c}]
+% \definesymbol [krw] [\FontAwesomeSymbol{f159}]
+% \definesymbol [language] [\FontAwesomeSymbol{f1ab}]
+% \definesymbol [laptop] [\FontAwesomeSymbol{f109}]
+% \definesymbol [lastfm] [\FontAwesomeSymbol{f202}]
+% \definesymbol [lastfm-square] [\FontAwesomeSymbol{f203}]
+% \definesymbol [leaf] [\FontAwesomeSymbol{f06c}]
+% \definesymbol [leanpub] [\FontAwesomeSymbol{f212}]
+% \definesymbol [legal] [\FontAwesomeSymbol{f0e3}]
+% \definesymbol [lemon-o] [\FontAwesomeSymbol{f094}]
+% \definesymbol [level-down] [\FontAwesomeSymbol{f149}]
+% \definesymbol [level-up] [\FontAwesomeSymbol{f148}]
+% \definesymbol [life-bouy] [\FontAwesomeSymbol{f1cd}]
+% \definesymbol [life-buoy] [\FontAwesomeSymbol{f1cd}]
+% \definesymbol [life-ring] [\FontAwesomeSymbol{f1cd}]
+% \definesymbol [life-saver] [\FontAwesomeSymbol{f1cd}]
+% \definesymbol [lightbulb-o] [\FontAwesomeSymbol{f0eb}]
+% \definesymbol [line-chart] [\FontAwesomeSymbol{f201}]
+% \definesymbol [link] [\FontAwesomeSymbol{f0c1}]
+% \definesymbol [linkedin] [\FontAwesomeSymbol{f0e1}]
+% \definesymbol [linkedin-square] [\FontAwesomeSymbol{f08c}]
+% \definesymbol [linux] [\FontAwesomeSymbol{f17c}]
+% \definesymbol [list] [\FontAwesomeSymbol{f03a}]
+% \definesymbol [list-alt] [\FontAwesomeSymbol{f022}]
+% \definesymbol [list-ol] [\FontAwesomeSymbol{f0cb}]
+% \definesymbol [list-ul] [\FontAwesomeSymbol{f0ca}]
+% \definesymbol [location-arrow] [\FontAwesomeSymbol{f124}]
+% \definesymbol [lock] [\FontAwesomeSymbol{f023}]
+% \definesymbol [long-arrow-down] [\FontAwesomeSymbol{f175}]
+% \definesymbol [long-arrow-left] [\FontAwesomeSymbol{f177}]
+% \definesymbol [long-arrow-right] [\FontAwesomeSymbol{f178}]
+% \definesymbol [long-arrow-up] [\FontAwesomeSymbol{f176}]
+% \definesymbol [low-vision] [\FontAwesomeSymbol{f2a8}]
+% \definesymbol [magic] [\FontAwesomeSymbol{f0d0}]
+% \definesymbol [magnet] [\FontAwesomeSymbol{f076}]
+% \definesymbol [mail-forward] [\FontAwesomeSymbol{f064}]
+% \definesymbol [mail-reply] [\FontAwesomeSymbol{f112}]
+% \definesymbol [mail-reply-all] [\FontAwesomeSymbol{f122}]
+% \definesymbol [male] [\FontAwesomeSymbol{f183}]
+% \definesymbol [map] [\FontAwesomeSymbol{f279}]
+% \definesymbol [map-marker] [\FontAwesomeSymbol{f041}]
+% \definesymbol [map-o] [\FontAwesomeSymbol{f278}]
+% \definesymbol [map-pin] [\FontAwesomeSymbol{f276}]
+% \definesymbol [map-signs] [\FontAwesomeSymbol{f277}]
+% \definesymbol [mars] [\FontAwesomeSymbol{f222}]
+% \definesymbol [mars-double] [\FontAwesomeSymbol{f227}]
+% \definesymbol [mars-stroke] [\FontAwesomeSymbol{f229}]
+% \definesymbol [mars-stroke-h] [\FontAwesomeSymbol{f22b}]
+% \definesymbol [mars-stroke-v] [\FontAwesomeSymbol{f22a}]
+% \definesymbol [maxcdn] [\FontAwesomeSymbol{f136}]
+% \definesymbol [meanpath] [\FontAwesomeSymbol{f20c}]
+% \definesymbol [medium] [\FontAwesomeSymbol{f23a}]
+% \definesymbol [medkit] [\FontAwesomeSymbol{f0fa}]
+% \definesymbol [meh-o] [\FontAwesomeSymbol{f11a}]
+% \definesymbol [mercury] [\FontAwesomeSymbol{f223}]
+% \definesymbol [microphone] [\FontAwesomeSymbol{f130}]
+% \definesymbol [microphone-slash] [\FontAwesomeSymbol{f131}]
+% \definesymbol [minus] [\FontAwesomeSymbol{f068}]
+% \definesymbol [minus-circle] [\FontAwesomeSymbol{f056}]
+% \definesymbol [minus-square] [\FontAwesomeSymbol{f146}]
+% \definesymbol [minus-square-o] [\FontAwesomeSymbol{f147}]
+% \definesymbol [mixcloud] [\FontAwesomeSymbol{f289}]
+% \definesymbol [mobile] [\FontAwesomeSymbol{f10b}]
+% \definesymbol [mobile-phone] [\FontAwesomeSymbol{f10b}]
+% \definesymbol [modx] [\FontAwesomeSymbol{f285}]
+% \definesymbol [money] [\FontAwesomeSymbol{f0d6}]
+% \definesymbol [moon-o] [\FontAwesomeSymbol{f186}]
+% \definesymbol [mortar-board] [\FontAwesomeSymbol{f19d}]
+% \definesymbol [motorcycle] [\FontAwesomeSymbol{f21c}]
+% \definesymbol [mouse-pointer] [\FontAwesomeSymbol{f245}]
+% \definesymbol [music] [\FontAwesomeSymbol{f001}]
+% \definesymbol [navicon] [\FontAwesomeSymbol{f0c9}]
+% \definesymbol [neuter] [\FontAwesomeSymbol{f22c}]
+% \definesymbol [newspaper-o] [\FontAwesomeSymbol{f1ea}]
+% \definesymbol [object-group] [\FontAwesomeSymbol{f247}]
+% \definesymbol [object-ungroup] [\FontAwesomeSymbol{f248}]
+% \definesymbol [odnoklassniki] [\FontAwesomeSymbol{f263}]
+% \definesymbol [odnoklassniki-square] [\FontAwesomeSymbol{f264}]
+% \definesymbol [opencart] [\FontAwesomeSymbol{f23d}]
+% \definesymbol [openid] [\FontAwesomeSymbol{f19b}]
+% \definesymbol [opera] [\FontAwesomeSymbol{f26a}]
+% \definesymbol [optin-monster] [\FontAwesomeSymbol{f23c}]
+% \definesymbol [outdent] [\FontAwesomeSymbol{f03b}]
+% \definesymbol [pagelines] [\FontAwesomeSymbol{f18c}]
+% \definesymbol [paint-brush] [\FontAwesomeSymbol{f1fc}]
+% \definesymbol [paper-plane] [\FontAwesomeSymbol{f1d8}]
+% \definesymbol [paper-plane-o] [\FontAwesomeSymbol{f1d9}]
+% \definesymbol [paperclip] [\FontAwesomeSymbol{f0c6}]
+% \definesymbol [paragraph] [\FontAwesomeSymbol{f1dd}]
+% \definesymbol [paste] [\FontAwesomeSymbol{f0ea}]
+% \definesymbol [pause] [\FontAwesomeSymbol{f04c}]
+% \definesymbol [pause-circle] [\FontAwesomeSymbol{f28b}]
+% \definesymbol [pause-circle-o] [\FontAwesomeSymbol{f28c}]
+% \definesymbol [paw] [\FontAwesomeSymbol{f1b0}]
+% \definesymbol [paypal] [\FontAwesomeSymbol{f1ed}]
+% \definesymbol [pencil] [\FontAwesomeSymbol{f040}]
+% \definesymbol [pencil-square] [\FontAwesomeSymbol{f14b}]
+% \definesymbol [pencil-square-o] [\FontAwesomeSymbol{f044}]
+% \definesymbol [percent] [\FontAwesomeSymbol{f295}]
+% \definesymbol [phone] [\FontAwesomeSymbol{f095}]
+% \definesymbol [phone-square] [\FontAwesomeSymbol{f098}]
+% \definesymbol [photo] [\FontAwesomeSymbol{f03e}]
+% \definesymbol [picture-o] [\FontAwesomeSymbol{f03e}]
+% \definesymbol [pie-chart] [\FontAwesomeSymbol{f200}]
+% \definesymbol [pied-piper] [\FontAwesomeSymbol{f2ae}]
+% \definesymbol [pied-piper-alt] [\FontAwesomeSymbol{f1a8}]
+% \definesymbol [pied-piper-pp] [\FontAwesomeSymbol{f1a7}]
+% \definesymbol [pinterest] [\FontAwesomeSymbol{f0d2}]
+% \definesymbol [pinterest-p] [\FontAwesomeSymbol{f231}]
+% \definesymbol [pinterest-square] [\FontAwesomeSymbol{f0d3}]
+% \definesymbol [plane] [\FontAwesomeSymbol{f072}]
+% \definesymbol [play] [\FontAwesomeSymbol{f04b}]
+% \definesymbol [play-circle] [\FontAwesomeSymbol{f144}]
+% \definesymbol [play-circle-o] [\FontAwesomeSymbol{f01d}]
+% \definesymbol [plug] [\FontAwesomeSymbol{f1e6}]
+% \definesymbol [plus] [\FontAwesomeSymbol{f067}]
+% \definesymbol [plus-circle] [\FontAwesomeSymbol{f055}]
+% \definesymbol [plus-square] [\FontAwesomeSymbol{f0fe}]
+% \definesymbol [plus-square-o] [\FontAwesomeSymbol{f196}]
+% \definesymbol [power-off] [\FontAwesomeSymbol{f011}]
+% \definesymbol [print] [\FontAwesomeSymbol{f02f}]
+% \definesymbol [product-hunt] [\FontAwesomeSymbol{f288}]
+% \definesymbol [puzzle-piece] [\FontAwesomeSymbol{f12e}]
+% \definesymbol [qq] [\FontAwesomeSymbol{f1d6}]
+% \definesymbol [qrcode] [\FontAwesomeSymbol{f029}]
+% \definesymbol [question] [\FontAwesomeSymbol{f128}]
+% \definesymbol [question-circle] [\FontAwesomeSymbol{f059}]
+% \definesymbol [question-circle-o] [\FontAwesomeSymbol{f29c}]
+% \definesymbol [quote-left] [\FontAwesomeSymbol{f10d}]
+% \definesymbol [quote-right] [\FontAwesomeSymbol{f10e}]
+% \definesymbol [ra] [\FontAwesomeSymbol{f1d0}]
+% \definesymbol [random] [\FontAwesomeSymbol{f074}]
+% \definesymbol [rebel] [\FontAwesomeSymbol{f1d0}]
+% \definesymbol [recycle] [\FontAwesomeSymbol{f1b8}]
+% \definesymbol [reddit] [\FontAwesomeSymbol{f1a1}]
+% \definesymbol [reddit-alien] [\FontAwesomeSymbol{f281}]
+% \definesymbol [reddit-square] [\FontAwesomeSymbol{f1a2}]
+% \definesymbol [refresh] [\FontAwesomeSymbol{f021}]
+% \definesymbol [registered] [\FontAwesomeSymbol{f25d}]
+% \definesymbol [remove] [\FontAwesomeSymbol{f00d}]
+% \definesymbol [renren] [\FontAwesomeSymbol{f18b}]
+% \definesymbol [reorder] [\FontAwesomeSymbol{f0c9}]
+% \definesymbol [repeat] [\FontAwesomeSymbol{f01e}]
+% \definesymbol [reply] [\FontAwesomeSymbol{f112}]
+% \definesymbol [reply-all] [\FontAwesomeSymbol{f122}]
+% \definesymbol [resistance] [\FontAwesomeSymbol{f1d0}]
+% \definesymbol [retweet] [\FontAwesomeSymbol{f079}]
+% \definesymbol [rmb] [\FontAwesomeSymbol{f157}]
+% \definesymbol [road] [\FontAwesomeSymbol{f018}]
+% \definesymbol [rocket] [\FontAwesomeSymbol{f135}]
+% \definesymbol [rotate-left] [\FontAwesomeSymbol{f0e2}]
+% \definesymbol [rotate-right] [\FontAwesomeSymbol{f01e}]
+% \definesymbol [rouble] [\FontAwesomeSymbol{f158}]
+% \definesymbol [rss] [\FontAwesomeSymbol{f09e}]
+% \definesymbol [rss-square] [\FontAwesomeSymbol{f143}]
+% \definesymbol [rub] [\FontAwesomeSymbol{f158}]
+% \definesymbol [ruble] [\FontAwesomeSymbol{f158}]
+% \definesymbol [rupee] [\FontAwesomeSymbol{f156}]
+% \definesymbol [safari] [\FontAwesomeSymbol{f267}]
+% \definesymbol [save] [\FontAwesomeSymbol{f0c7}]
+% \definesymbol [scissors] [\FontAwesomeSymbol{f0c4}]
+% \definesymbol [scribd] [\FontAwesomeSymbol{f28a}]
+% \definesymbol [search] [\FontAwesomeSymbol{f002}]
+% \definesymbol [search-minus] [\FontAwesomeSymbol{f010}]
+% \definesymbol [search-plus] [\FontAwesomeSymbol{f00e}]
+% \definesymbol [sellsy] [\FontAwesomeSymbol{f213}]
+% \definesymbol [send] [\FontAwesomeSymbol{f1d8}]
+% \definesymbol [send-o] [\FontAwesomeSymbol{f1d9}]
+% \definesymbol [server] [\FontAwesomeSymbol{f233}]
+% \definesymbol [share] [\FontAwesomeSymbol{f064}]
+% \definesymbol [share-alt] [\FontAwesomeSymbol{f1e0}]
+% \definesymbol [share-alt-square] [\FontAwesomeSymbol{f1e1}]
+% \definesymbol [share-square] [\FontAwesomeSymbol{f14d}]
+% \definesymbol [share-square-o] [\FontAwesomeSymbol{f045}]
+% \definesymbol [shekel] [\FontAwesomeSymbol{f20b}]
+% \definesymbol [sheqel] [\FontAwesomeSymbol{f20b}]
+% \definesymbol [shield] [\FontAwesomeSymbol{f132}]
+% \definesymbol [ship] [\FontAwesomeSymbol{f21a}]
+% \definesymbol [shirtsinbulk] [\FontAwesomeSymbol{f214}]
+% \definesymbol [shopping-bag] [\FontAwesomeSymbol{f290}]
+% \definesymbol [shopping-basket] [\FontAwesomeSymbol{f291}]
+% \definesymbol [shopping-cart] [\FontAwesomeSymbol{f07a}]
+% \definesymbol [sign-in] [\FontAwesomeSymbol{f090}]
+% \definesymbol [sign-language] [\FontAwesomeSymbol{f2a7}]
+% \definesymbol [sign-out] [\FontAwesomeSymbol{f08b}]
+% \definesymbol [signal] [\FontAwesomeSymbol{f012}]
+% \definesymbol [signing] [\FontAwesomeSymbol{f2a7}]
+% \definesymbol [simplybuilt] [\FontAwesomeSymbol{f215}]
+% \definesymbol [sitemap] [\FontAwesomeSymbol{f0e8}]
+% \definesymbol [skyatlas] [\FontAwesomeSymbol{f216}]
+% \definesymbol [skype] [\FontAwesomeSymbol{f17e}]
+% \definesymbol [slack] [\FontAwesomeSymbol{f198}]
+% \definesymbol [sliders] [\FontAwesomeSymbol{f1de}]
+% \definesymbol [slideshare] [\FontAwesomeSymbol{f1e7}]
+% \definesymbol [smile-o] [\FontAwesomeSymbol{f118}]
+% \definesymbol [snapchat] [\FontAwesomeSymbol{f2ab}]
+% \definesymbol [snapchat-ghost] [\FontAwesomeSymbol{f2ac}]
+% \definesymbol [snapchat-square] [\FontAwesomeSymbol{f2ad}]
+% \definesymbol [soccer-ball-o] [\FontAwesomeSymbol{f1e3}]
+% \definesymbol [sort] [\FontAwesomeSymbol{f0dc}]
+% \definesymbol [sort-alpha-asc] [\FontAwesomeSymbol{f15d}]
+% \definesymbol [sort-alpha-desc] [\FontAwesomeSymbol{f15e}]
+% \definesymbol [sort-amount-asc] [\FontAwesomeSymbol{f160}]
+% \definesymbol [sort-amount-desc] [\FontAwesomeSymbol{f161}]
+% \definesymbol [sort-asc] [\FontAwesomeSymbol{f0de}]
+% \definesymbol [sort-desc] [\FontAwesomeSymbol{f0dd}]
+% \definesymbol [sort-down] [\FontAwesomeSymbol{f0dd}]
+% \definesymbol [sort-numeric-asc] [\FontAwesomeSymbol{f162}]
+% \definesymbol [sort-numeric-desc] [\FontAwesomeSymbol{f163}]
+% \definesymbol [sort-up] [\FontAwesomeSymbol{f0de}]
+% \definesymbol [soundcloud] [\FontAwesomeSymbol{f1be}]
+% \definesymbol [space-shuttle] [\FontAwesomeSymbol{f197}]
+% \definesymbol [spinner] [\FontAwesomeSymbol{f110}]
+% \definesymbol [spoon] [\FontAwesomeSymbol{f1b1}]
+% \definesymbol [spotify] [\FontAwesomeSymbol{f1bc}]
+% \definesymbol [square] [\FontAwesomeSymbol{f0c8}]
+% \definesymbol [square-o] [\FontAwesomeSymbol{f096}]
+% \definesymbol [stack-exchange] [\FontAwesomeSymbol{f18d}]
+% \definesymbol [stack-overflow] [\FontAwesomeSymbol{f16c}]
+% \definesymbol [star] [\FontAwesomeSymbol{f005}]
+% \definesymbol [star-half] [\FontAwesomeSymbol{f089}]
+% \definesymbol [star-half-empty] [\FontAwesomeSymbol{f123}]
+% \definesymbol [star-half-full] [\FontAwesomeSymbol{f123}]
+% \definesymbol [star-half-o] [\FontAwesomeSymbol{f123}]
+% \definesymbol [star-o] [\FontAwesomeSymbol{f006}]
+% \definesymbol [steam] [\FontAwesomeSymbol{f1b6}]
+% \definesymbol [steam-square] [\FontAwesomeSymbol{f1b7}]
+% \definesymbol [step-backward] [\FontAwesomeSymbol{f048}]
+% \definesymbol [step-forward] [\FontAwesomeSymbol{f051}]
+% \definesymbol [stethoscope] [\FontAwesomeSymbol{f0f1}]
+% \definesymbol [sticky-note] [\FontAwesomeSymbol{f249}]
+% \definesymbol [sticky-note-o] [\FontAwesomeSymbol{f24a}]
+% \definesymbol [stop] [\FontAwesomeSymbol{f04d}]
+% \definesymbol [stop-circle] [\FontAwesomeSymbol{f28d}]
+% \definesymbol [stop-circle-o] [\FontAwesomeSymbol{f28e}]
+% \definesymbol [street-view] [\FontAwesomeSymbol{f21d}]
+% \definesymbol [strikethrough] [\FontAwesomeSymbol{f0cc}]
+% \definesymbol [stumbleupon] [\FontAwesomeSymbol{f1a4}]
+% \definesymbol [stumbleupon-circle] [\FontAwesomeSymbol{f1a3}]
+% \definesymbol [subscript] [\FontAwesomeSymbol{f12c}]
+% \definesymbol [subway] [\FontAwesomeSymbol{f239}]
+% \definesymbol [suitcase] [\FontAwesomeSymbol{f0f2}]
+% \definesymbol [sun-o] [\FontAwesomeSymbol{f185}]
+% \definesymbol [superscript] [\FontAwesomeSymbol{f12b}]
+% \definesymbol [support] [\FontAwesomeSymbol{f1cd}]
+% \definesymbol [table] [\FontAwesomeSymbol{f0ce}]
+% \definesymbol [tablet] [\FontAwesomeSymbol{f10a}]
+% \definesymbol [tachometer] [\FontAwesomeSymbol{f0e4}]
+% \definesymbol [tag] [\FontAwesomeSymbol{f02b}]
+% \definesymbol [tags] [\FontAwesomeSymbol{f02c}]
+% \definesymbol [tasks] [\FontAwesomeSymbol{f0ae}]
+% \definesymbol [taxi] [\FontAwesomeSymbol{f1ba}]
+% \definesymbol [television] [\FontAwesomeSymbol{f26c}]
+% \definesymbol [tencent-weibo] [\FontAwesomeSymbol{f1d5}]
+% \definesymbol [terminal] [\FontAwesomeSymbol{f120}]
+% \definesymbol [text-height] [\FontAwesomeSymbol{f034}]
+% \definesymbol [text-width] [\FontAwesomeSymbol{f035}]
+% \definesymbol [th] [\FontAwesomeSymbol{f00a}]
+% \definesymbol [th-large] [\FontAwesomeSymbol{f009}]
+% \definesymbol [th-list] [\FontAwesomeSymbol{f00b}]
+% \definesymbol [themeisle] [\FontAwesomeSymbol{f2b2}]
+% \definesymbol [thumb-tack] [\FontAwesomeSymbol{f08d}]
+% \definesymbol [thumbs-down] [\FontAwesomeSymbol{f165}]
+% \definesymbol [thumbs-o-down] [\FontAwesomeSymbol{f088}]
+% \definesymbol [thumbs-o-up] [\FontAwesomeSymbol{f087}]
+% \definesymbol [thumbs-up] [\FontAwesomeSymbol{f164}]
+% \definesymbol [ticket] [\FontAwesomeSymbol{f145}]
+% \definesymbol [times] [\FontAwesomeSymbol{f00d}]
+% \definesymbol [times-circle] [\FontAwesomeSymbol{f057}]
+% \definesymbol [times-circle-o] [\FontAwesomeSymbol{f05c}]
+% \definesymbol [tint] [\FontAwesomeSymbol{f043}]
+% \definesymbol [toggle-down] [\FontAwesomeSymbol{f150}]
+% \definesymbol [toggle-left] [\FontAwesomeSymbol{f191}]
+% \definesymbol [toggle-off] [\FontAwesomeSymbol{f204}]
+% \definesymbol [toggle-on] [\FontAwesomeSymbol{f205}]
+% \definesymbol [toggle-right] [\FontAwesomeSymbol{f152}]
+% \definesymbol [toggle-up] [\FontAwesomeSymbol{f151}]
+% \definesymbol [trademark] [\FontAwesomeSymbol{f25c}]
+% \definesymbol [train] [\FontAwesomeSymbol{f238}]
+% \definesymbol [transgender] [\FontAwesomeSymbol{f224}]
+% \definesymbol [transgender-alt] [\FontAwesomeSymbol{f225}]
+% \definesymbol [trash] [\FontAwesomeSymbol{f1f8}]
+% \definesymbol [trash-o] [\FontAwesomeSymbol{f014}]
+% \definesymbol [tree] [\FontAwesomeSymbol{f1bb}]
+% \definesymbol [trello] [\FontAwesomeSymbol{f181}]
+% \definesymbol [tripadvisor] [\FontAwesomeSymbol{f262}]
+% \definesymbol [trophy] [\FontAwesomeSymbol{f091}]
+% \definesymbol [truck] [\FontAwesomeSymbol{f0d1}]
+% \definesymbol [try] [\FontAwesomeSymbol{f195}]
+% \definesymbol [tty] [\FontAwesomeSymbol{f1e4}]
+% \definesymbol [tumblr] [\FontAwesomeSymbol{f173}]
+% \definesymbol [tumblr-square] [\FontAwesomeSymbol{f174}]
+% \definesymbol [turkish-lira] [\FontAwesomeSymbol{f195}]
+% \definesymbol [tv] [\FontAwesomeSymbol{f26c}]
+% \definesymbol [twitch] [\FontAwesomeSymbol{f1e8}]
+% \definesymbol [twitter] [\FontAwesomeSymbol{f099}]
+% \definesymbol [twitter-square] [\FontAwesomeSymbol{f081}]
+% \definesymbol [umbrella] [\FontAwesomeSymbol{f0e9}]
+% \definesymbol [underline] [\FontAwesomeSymbol{f0cd}]
+% \definesymbol [undo] [\FontAwesomeSymbol{f0e2}]
+% \definesymbol [universal-access] [\FontAwesomeSymbol{f29a}]
+% \definesymbol [university] [\FontAwesomeSymbol{f19c}]
+% \definesymbol [unlink] [\FontAwesomeSymbol{f127}]
+% \definesymbol [unlock] [\FontAwesomeSymbol{f09c}]
+% \definesymbol [unlock-alt] [\FontAwesomeSymbol{f13e}]
+% \definesymbol [unsorted] [\FontAwesomeSymbol{f0dc}]
+% \definesymbol [upload] [\FontAwesomeSymbol{f093}]
+% \definesymbol [usb] [\FontAwesomeSymbol{f287}]
+% \definesymbol [usd] [\FontAwesomeSymbol{f155}]
+% \definesymbol [user] [\FontAwesomeSymbol{f007}]
+% \definesymbol [user-md] [\FontAwesomeSymbol{f0f0}]
+% \definesymbol [user-plus] [\FontAwesomeSymbol{f234}]
+% \definesymbol [user-secret] [\FontAwesomeSymbol{f21b}]
+% \definesymbol [user-times] [\FontAwesomeSymbol{f235}]
+% \definesymbol [users] [\FontAwesomeSymbol{f0c0}]
+% \definesymbol [venus] [\FontAwesomeSymbol{f221}]
+% \definesymbol [venus-double] [\FontAwesomeSymbol{f226}]
+% \definesymbol [venus-mars] [\FontAwesomeSymbol{f228}]
+% \definesymbol [viacoin] [\FontAwesomeSymbol{f237}]
+% \definesymbol [viadeo] [\FontAwesomeSymbol{f2a9}]
+% \definesymbol [viadeo-square] [\FontAwesomeSymbol{f2aa}]
+% \definesymbol [video-camera] [\FontAwesomeSymbol{f03d}]
+% \definesymbol [vimeo] [\FontAwesomeSymbol{f27d}]
+% \definesymbol [vimeo-square] [\FontAwesomeSymbol{f194}]
+% \definesymbol [vine] [\FontAwesomeSymbol{f1ca}]
+% \definesymbol [vk] [\FontAwesomeSymbol{f189}]
+% \definesymbol [volume-control-phone] [\FontAwesomeSymbol{f2a0}]
+% \definesymbol [volume-down] [\FontAwesomeSymbol{f027}]
+% \definesymbol [volume-off] [\FontAwesomeSymbol{f026}]
+% \definesymbol [volume-up] [\FontAwesomeSymbol{f028}]
+% \definesymbol [warning] [\FontAwesomeSymbol{f071}]
+% \definesymbol [wechat] [\FontAwesomeSymbol{f1d7}]
+% \definesymbol [weibo] [\FontAwesomeSymbol{f18a}]
+% \definesymbol [weixin] [\FontAwesomeSymbol{f1d7}]
+% \definesymbol [whatsapp] [\FontAwesomeSymbol{f232}]
+% \definesymbol [wheelchair] [\FontAwesomeSymbol{f193}]
+% \definesymbol [wheelchair-alt] [\FontAwesomeSymbol{f29b}]
+% \definesymbol [wifi] [\FontAwesomeSymbol{f1eb}]
+% \definesymbol [wikipedia-w] [\FontAwesomeSymbol{f266}]
+% \definesymbol [windows] [\FontAwesomeSymbol{f17a}]
+% \definesymbol [won] [\FontAwesomeSymbol{f159}]
+% \definesymbol [wordpress] [\FontAwesomeSymbol{f19a}]
+% \definesymbol [wpbeginner] [\FontAwesomeSymbol{f297}]
+% \definesymbol [wpforms] [\FontAwesomeSymbol{f298}]
+% \definesymbol [wrench] [\FontAwesomeSymbol{f0ad}]
+% \definesymbol [xing] [\FontAwesomeSymbol{f168}]
+% \definesymbol [xing-square] [\FontAwesomeSymbol{f169}]
+% \definesymbol [y-combinator] [\FontAwesomeSymbol{f23b}]
+% \definesymbol [y-combinator-square] [\FontAwesomeSymbol{f1d4}]
+% \definesymbol [yahoo] [\FontAwesomeSymbol{f19e}]
+% \definesymbol [yc] [\FontAwesomeSymbol{f23b}]
+% \definesymbol [yc-square] [\FontAwesomeSymbol{f1d4}]
+% \definesymbol [yelp] [\FontAwesomeSymbol{f1e9}]
+% \definesymbol [yen] [\FontAwesomeSymbol{f157}]
+% \definesymbol [yoast] [\FontAwesomeSymbol{f2b1}]
+% \definesymbol [youtube] [\FontAwesomeSymbol{f167}]
+% \definesymbol [youtube-play] [\FontAwesomeSymbol{f16a}]
+% \definesymbol [youtube-square] [\FontAwesomeSymbol{f166}]
+
+\stopsymbolset
+
+\definefontsynonym [FontAwesomeBrands] [file:fontawesome5brandsregular400.otf]
+\definefontsynonym [FontAwesomeRegular] [file:fontawesome5freeregular400.otf]
+\definefontsynonym [FontAwesomeSolid] [file:fontawesome5freesolid900.otf]
+
+\startsymbolset [fontawesome-brands] [font=FontAwesomeBrands]
+ % Font Awesome Brands
+\stopsymbolset
+
+\startsymbolset [fontawesome-regular] [font=FontAwesomeRegular]
+ % Font Awesome Regular
+\stopsymbolset
+
+\startsymbolset [fontawesome-solid] [font=FontAwesomeSolid]
+ % Font Awesome Solid
\stopsymbolset
\continueifinputfile{symb-imp-fontawesome.mkiv}
-% \usesymbols[fontawesome]
+\usemodule[article-basic]
\starttext
- \showsymbolset[fontawesome]
+ % \usesymbols[fontawesome]
+ %
+ % \symbol[fontawesome][wheelchair]
+ % \symbol[fontawesome][angle-right]
+ % \symbol[fontawesome][angle right]
+ % \symbol[fontawesome][angle_right]
+
+ % \showsymbolset[fontawesome]
+
+ \startnamedsection [title] [title={Font Awesome Brands}]
+ \showsymbolset [fontawesome-brands]
+ \stopnamedsection
+
+ \startnamedsection [title] [title={Font Awesome Regular}]
+ \showsymbolset [fontawesome-regular]
+ \stopnamedsection
+
+ \startnamedsection [title] [title={Font Awesome Solid}]
+ \showsymbolset [fontawesome-solid]
+ \stopnamedsection
\stoptext
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mis.mkiv b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mis.mkiv
index d2657512f3f..2320ea59ae0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mis.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mis.mkiv
@@ -21,34 +21,36 @@
\definesymbol [\v!none] []
-\definesymbol [bullet] [\textmath\bullet]
-\definesymbol [dash] [\textmath-]
-\definesymbol [star] [\textmath\star]
-\definesymbol [triangle] [\textmath\triangleright]
-\definesymbol [circle] [\textmath\circ]
-\definesymbol [square] [\textmath\square]
-\definesymbol [diamond] [\textmath\diamond]
+% \definesymbol [bullet] [\textmath\bullet]
+% \definesymbol [dash] [\textmath-]
+% \definesymbol [star] [\textmath\star]
+% \definesymbol [triangle] [\textmath\triangleright]
+% \definesymbol [circle] [\textmath\circ]
+% \definesymbol [square] [\textmath\square]
+% \definesymbol [diamond] [\textmath\diamond]
+% \definesymbol [asterisk] [\textmath\ast]
% I'm not sure about this ... I dislike the small bullet. So we provide
% it as variant: \type {\setupsymbolset[text]}. Also, we want to be
% backward compatible.
-\startsymbolset[text]
+% \startsymbolset[text]
\definesymbol [bullet] [\textormathchar{"2022}] % • \bullet
\definesymbol [dash] [\textormathchar{"2013}] % –
- \definesymbol [star] [\textormathchar{"22C6}] % ✴ \star
+ \definesymbol [star] [\textormathchar{"22C6}] % ⋆ \star
\definesymbol [triangle] [\textormathchar{"22B3}] % ⊳ \triangleright
\definesymbol [circle] [\textormathchar{"2218}] % ∘ \circ
\definesymbol [square] [\textormathchar{"25A1}] % □ \square
\definesymbol [diamond] [\textormathchar{"22C4}] % ⋄ \diamond
\definesymbol [checkmark] [\textormathchar{"2713}] % ✓ \checkmark
+ \definesymbol [asterisk] [\textormathchar{"2217}] % ∗ \asterisk
\definesymbol [blacktriangle] [\textormathchar{"25B6}] % ▶
\definesymbol [blacksquare] [\textormathchar{"25A0}] % ■
\definesymbol [blackdiamond] [\textormathchar{"25C6}] % ◆
-\stopsymbolset
+% \stopsymbolset
\definesymbol [smallcircle] [\hbox{\raise.1ex\hbox{\textmath{\scriptscriptstyle\bigcirc}}}]
\definesymbol [medcircle] [\hbox{\raise.1ex\hbox{\textmath{\scriptstyle \bigcirc}}}]
@@ -62,6 +64,7 @@
\definesymbol [6] [\symbol{medcircle}]
\definesymbol [7] [\symbol{bigcircle}]
\definesymbol [8] [\symbol{square}]
+\definesymbol [9] [\symbol{checkmark}]
\definesymbol [S] [\sectionmark]
\definesymbol [P] [\paragraphmark]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mvs.mkiv b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mvs.mkiv
index 9902fc9e8a3..f6a38214f62 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mvs.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-imp-mvs.mkiv
@@ -254,10 +254,16 @@
\stopsymbolset
-%D \showsymbolset[astronomic]
-%D \showsymbolset[zodiac]
-%D \showsymbolset[europe]
-%D \showsymbolset[martinvogel 1]
-%D \showsymbolset[martinvogel 2]
+\continueifinputfile{symb-imp-mvs.mkiv}
-\endinput
+\usemodule[article-basic]
+
+\starttext
+
+\startsubject[title={Astronomic}] \showsymbolset[astronomic] \stopsubject
+\startsubject[title={Zodiac}] \showsymbolset[zodiac] \stopsubject
+\startsubject[title={Europe}] \showsymbolset[europe] \stopsubject
+\startsubject[title={Martinvogel 1}] \showsymbolset[martinvogel 1] \stopsubject
+\startsubject[title={Martinvogel 2}] \showsymbolset[martinvogel 2] \stopsubject
+
+\stoptext
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv
index e4950e09d73..abf85767576 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv
@@ -45,6 +45,7 @@
\installcorenamespace{symbol}
\installcorenamespace{symbolset}
+\installcorenamespace{symboldefault}
\let\currentsymbol \empty
\let\currentsymbolset\empty
@@ -95,8 +96,9 @@
% Test test \symbol[whatever]\ test \symbol[whatever].
% Test test \symbol{whatever} test \symbol{whatever}.
-\unexpanded\def\symbol % This one always gobbles spaces,
- {\dodoubleempty\symb_place} % so never change it again!
+\unexpanded\def\symbol
+ {\dontleavehmode % so we can start a paragraph with it
+ \dodoubleempty\symb_place}
\def\symb_place % so we also handle \symbol{name}
{\iffirstargument % which is nicer with following spaces
@@ -112,13 +114,23 @@
\expandafter\symb_place_normal_b
\fi}
+% \def\symb_place_normal_a[#1][#2]%
+% {\edef\currentsymbol{#2}%
+% \ifcsname\??symbol#1:#2\endcsname
+% \symb_place_indeed{#1:#2}%
+% \else
+% \symb_place_normal_c
+% \fi}
+
\def\symb_place_normal_a[#1][#2]%
{\edef\currentsymbol{#2}%
\ifcsname\??symbol#1:#2\endcsname
- \symb_place_indeed{#1:#2}%
+ \symb_place_indeed{#1:#2}% maybe use \lastnamescs
+ \else\ifcsname\??symboldefault#1\endcsname
+ \symb_place_named{#1}% maybe use \lastnamescs
\else
\symb_place_normal_c
- \fi}
+ \fi\fi}
\def\symb_place_normal_b[#1][#2]%
{\edef\currentsymbol{#1}%
@@ -160,11 +172,47 @@
\expandafter\symb_fetch_indeed
\fi}
+% \def\symb_fetch_indeed#1%
+% {\ifcsname\??symbol#1:\currentsymbol\endcsname
+% \symb_place_indeed{#1:\currentsymbol}%
+% \fi}
+
\def\symb_fetch_indeed#1%
{\ifcsname\??symbol#1:\currentsymbol\endcsname
\symb_place_indeed{#1:\currentsymbol}%
+ \else\ifcsname\??symboldefault#1\endcsname
+ \symb_place_named{#1}%
+ \fi\fi}
+
+\def\symb_place_named#1% \relax's prevent lookahead problems
+ {\begingroup
+ \setbox\scratchbox\hbox\bgroup
+ \the\everysymbol
+ \getglyphstyled
+ {\csname\??symboldefault#1\endcsname}%
+ {\tochar{n:\currentsymbol}}%
+ \relax
+ \egroup
+ \ifdim\wd\scratchbox>\zeropoint
+ \unhbox\scratchbox
+ \endgroup
+ \setxvalue{\??symbol#1:\currentsymbol}%
+ {\symb_place_named_indeed{#1}{\currentsymbol}}%
+ \settrue\c_symb_found
+ \else
+ \endgroup
\fi}
+\unexpanded\def\symb_place_named_indeed#1#2% \relax's prevent lookahead problems
+ {\settrue\c_symb_found
+ \begingroup
+ \the\everysymbol
+ \getglyphstyled
+ {\csname\??symboldefault#1\endcsname}%
+ {\tochar{n:#2}}%
+ \relax
+ \endgroup}
+
\def\symb_place_retry#1%
{\ifcsname\??symbol:#1\endcsname
\symb_place_indeed{:#1}%
@@ -273,9 +321,25 @@
\installcorenamespace{symbolsets}
-\unexpanded\def\startsymbolset[#1]%
+% \unexpanded\def\startsymbolset[#1]%
+% {\pushmacro\m_symb_current_set
+% \def\m_symb_current_set{#1}}
+
+% maybe a parameterhandler:
+
+\unexpanded\def\startsymbolset
+ {\dodoubleargument\symb_start_set}
+
+\def\symb_start_set[#1][#2]%
{\pushmacro\m_symb_current_set
- \def\m_symb_current_set{#1}}
+ \def\m_symb_current_set{#1}%
+ \ifsecondargument
+ \getdummyparameters[\s!font=,#2]%
+ \edef\p_font{\dummyparameter\s!font}%
+ \ifx\p_font\empty\else
+ \letvalue{\??symboldefault#1}\p_font
+ \fi
+ \fi}
\unexpanded\def\stopsymbolset
{\popmacro\m_symb_current_set}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/symb-run.mkiv b/Master/texmf-dist/tex/context/base/mkiv/symb-run.mkiv
index ed4d90861ec..c25d13d48bf 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/symb-run.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/symb-run.mkiv
@@ -12,23 +12,55 @@
%C details.
\startluacode
- function commands.showsymbolset(collection,symbols)
+ function commands.showsymbolset(collection,symbols,fontid)
if type(symbols) == "string" then
symbols = utilities.parsers.settings_to_array(symbols)
end
+ local options = { framecolor = "orange", rulethickness = ".8pt", offset = interfaces.variables.overlay }
+ local list = table.tohash(symbols)
+ local alsofont = fontid > 0
+ local defined = #symbols > 0
+ local byname = false
+ if alsofont then
+ local is_symbol = characters.is_symbol
+ local chardata = characters.data
+ local resources = fonts.hashes.resources [fontid]
+ local characters = fonts.hashes.characters[fontid]
+ if resources and characters then
+ local unicodes = resources.unicodes
+ if unicodes then
+ for name, unicode in next, unicodes do
+ if not list[name] and name ~= ".notdef" then
+ local c = rawget(chardata,unicode)
+ if not c or is_symbol[c.category] then
+ list[name] = false
+ byname = true
+ end
+ end
+ end
+ end
+ end
+ end
+ local detail = defined and byname
context.start()
context.forcesymbolset { collection }
- context.starttabulate { "|lT|l|l|" }
- local options = { framecolor = "orange", rulethickness = ".8pt", offset = interfaces.variables.overlay }
- for i=1,#symbols do
- local symbol = symbols[i]
+ context.starttabulate { detail and "|lT|l|l|lT|" or "|lT|l|l|"}
+ for symbol, how in table.sortedhash(list) do
context.NC()
- context(symbol)
+ if detail and how then
+ context.bold(symbol)
+ else
+ context(symbol)
+ end
context.NC()
context.symbol(symbol)
context.NC()
context.framed(options,context.nested.symbol(symbol))
context.NC()
+ if detail and how then
+ context.bold("defined")
+ context.NC()
+ end
context.NR()
end
context.stoptabulate()
@@ -42,7 +74,23 @@
{\dosingleargument\symb_show_set}
\gdef\symb_show_set[#1]%
- {\ctxcommand{showsymbolset("#1","\symbolset{#1}")}}
+ {\begingroup
+ \edef\p_font{\begincsname\??symboldefault#1\endcsname}%
+ \begingroup
+ \ifx\p_font\empty
+ \global\globalscratchcounter\zerocount
+ \else
+ \definedfont[\p_font]%
+ \global\globalscratchcounter\fontid\font\relax
+ \fi
+ \endgroup
+ \ctxcommand {
+ showsymbolset (
+ "#1",
+ "\symbolset{#1}",
+ \the\globalscratchcounter
+ ) }%
+ \endgroup}
\protect
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-aux.lua b/Master/texmf-dist/tex/context/base/mkiv/syst-aux.lua
index f9d8505f1d4..9b0ca82c430 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/syst-aux.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-aux.lua
@@ -323,9 +323,47 @@ end
implement { name = "texdefinition_one", actions = texdefinition_one, scope = "private", arguments = "string" }
implement { name = "texdefinition_two", actions = texdefinition_two, scope = "private" }
-implement { name = "upper", arguments = "string", actions = { utf.upper, context } }
-implement { name = "lower", arguments = "string", actions = { utf.lower, context } }
-implement { name = "strip", arguments = "string", actions = { string.strip, context } } -- or utf.strip
+do
+
+ -- Quite probably we don't yet have characters loaded so we delay some
+ -- aliases.
+
+ local _lower_, _upper_, _strip_
+
+ _lower_ = function(s)
+ if characters and characters.lower then
+ _lower_ = characters.lower
+ return _lower_(s)
+ end
+ return string.lower(s)
+ end
+
+ _upper_ = function(s)
+ if characters and characters.upper then
+ _upper_ = characters.upper
+ return _upper_(s)
+ end
+ return string.upper(s)
+ end
+
+ _strip_ = function(s)
+ -- or utf.strip
+ if string.strip then
+ _strip_ = string.strip
+ return _strip_(s)
+ end
+ return s
+ end
+
+ local function lower(s) context(_lower_(s)) end
+ local function upper(s) context(_upper_(s)) end
+ local function strip(s) context(_strip_(s)) end
+
+ implement { name = "upper", arguments = "string", actions = upper }
+ implement { name = "lower", arguments = "string", actions = lower }
+ implement { name = "strip", arguments = "string", actions = strip }
+
+end
implement {
name = "converteddimen",
@@ -373,10 +411,17 @@ implement {
-- not faster but just less tracing:
-local firstoftwoarguments = context.firstoftwoarguments
-local secondoftwoarguments = context.secondoftwoarguments
-local firstofoneargument = context.firstofoneargument
-local gobbleoneargument = context.gobbleoneargument
+local ctx_protected_cs = context.protected.cs -- more efficient
+
+local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments
+local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments
+local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument
+local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument
+
+context.firstoftwoarguments = ctx_firstoftwoarguments
+context.secondoftwoarguments = ctx_secondoftwoarguments
+context.firstofoneargument = ctx_firstofoneargument
+context.gobbleoneargument = ctx_gobbleoneargument
local hash = utilities.parsers.hashes.settings_to_set
@@ -384,9 +429,9 @@ local function doifelsecommon(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
else
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
end
return
end
@@ -400,7 +445,7 @@ local function doifelsecommon(a,b)
for k in next, ha do
if hb[k] then
setmacro("commalistelement",k)
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
end
@@ -408,28 +453,28 @@ local function doifelsecommon(a,b)
if hash[a][b] then
-- if settings_to_set(a)[b] then
setmacro("commalistelement",b)
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
elseif bb then
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
end
setmacro("commalistelement","")
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
local function doifcommon(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- gobbleoneargument()
+ ctx_gobbleoneargument()
else
- firstofoneargument()
+ ctx_firstofoneargument()
end
return
end
@@ -443,7 +488,7 @@ local function doifcommon(a,b)
for k in next, ha do
if hb[k] then
setmacro("commalistelement",k)
- firstofoneargument()
+ ctx_firstofoneargument()
return
end
end
@@ -451,28 +496,28 @@ local function doifcommon(a,b)
if hash[a][b] then
-- if settings_to_set(a)[b] then
setmacro("commalistelement",b)
- firstofoneargument()
+ ctx_firstofoneargument()
return
end
elseif bb then
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- firstofoneargument()
+ ctx_firstofoneargument()
return
end
end
setmacro("commalistelement","")
- gobbleoneargument()
+ ctx_gobbleoneargument()
end
local function doifnotcommon(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- firstofoneargument()
+ ctx_firstofoneargument()
else
- gobbleoneargument()
+ ctx_gobbleoneargument()
end
return
end
@@ -486,7 +531,7 @@ local function doifnotcommon(a,b)
for k in next, ha do
if hb[k] then
setmacro("commalistelement",k)
- gobbleoneargument()
+ ctx_gobbleoneargument()
return
end
end
@@ -494,28 +539,28 @@ local function doifnotcommon(a,b)
if hash[a][b] then
-- if settings_to_set(a)[b] then
setmacro("commalistelement",b)
- gobbleoneargument()
+ ctx_gobbleoneargument()
return
end
elseif bb then
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- gobbleoneargument()
+ ctx_gobbleoneargument()
return
end
end
setmacro("commalistelement","")
- firstofoneargument()
+ ctx_firstofoneargument()
end
local function doifelseinset(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
else
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
end
return
end
@@ -524,21 +569,21 @@ local function doifelseinset(a,b)
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
end
setmacro("commalistelement","")
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
local function doifinset(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- gobbleoneargument()
+ ctx_gobbleoneargument()
else
- firstofoneargument()
+ ctx_firstofoneargument()
end
return
end
@@ -547,21 +592,21 @@ local function doifinset(a,b)
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- firstofoneargument()
+ ctx_firstofoneargument()
return
end
end
setmacro("commalistelement","")
- gobbleoneargument()
+ ctx_gobbleoneargument()
end
local function doifnotinset(a,b)
if a == b then
setmacro("commalistelement",a)
if a == "" then
- firstofoneargument()
+ ctx_firstofoneargument()
else
- gobbleoneargument()
+ ctx_gobbleoneargument()
end
return
end
@@ -570,12 +615,12 @@ local function doifnotinset(a,b)
if hash[b][a] then
-- if settings_to_set(b)[a] then
setmacro("commalistelement",a)
- gobbleoneargument()
+ ctx_gobbleoneargument()
return
end
end
setmacro("commalistelement","")
- firstofoneargument()
+ ctx_firstofoneargument()
end
implement {
@@ -614,6 +659,20 @@ implement {
arguments = "2 strings",
}
+-- done elsewhere:
+--
+-- local function firstinset(a)
+-- local aa = hash[a]
+-- context(aa and aa[1] or a)
+-- end
+--
+-- implement {
+-- name = "firstinset",
+-- actions = firstinset,
+-- arguments = "string",
+-- private = false,
+-- }
+
-- implement {
-- name = "stringcompare",
-- arguments = "2 strings",
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-aux.mkiv b/Master/texmf-dist/tex/context/base/mkiv/syst-aux.mkiv
index 77f947753ec..3004c08b805 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/syst-aux.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-aux.mkiv
@@ -181,12 +181,9 @@
%D These are not needed any more now that we have wide screens (and bytes come
%D cheap).
-\let\@EA \singleexpandafter
-\let\@EAEAEA \doubleexpandafter
-\let\@EAEAEAEAEAEA\tripleexpandafter
-
-\let\@NX \noexpand
-\def\@EAEA {\expandafter\expandafter} % can often be avoided
+\let\@EA \singleexpandafter % obsolete
+\let\@EAEAEA \doubleexpandafter % obsolete
+\let\@EAEAEAEAEAEA\tripleexpandafter % obsolete
%D Sometimes we pass macros as arguments to commands that don't expand them
%D before interpretation. Such commands can be enclosed with \type {\expanded},
@@ -345,6 +342,18 @@
\let\doifnextoptionalelse \doifelsenextoptional
\let\doifnextoptionalcselse\doifelsenextoptionalcs
+% fails on assignments
+%
+% \unexpanded\def\doifelsenextoptional {\afterassignment\doifelsenextoptional_n \def\m_syst_action_yes}
+% \def\doifelsenextoptional_n {\afterassignment\doifelsenextoptional_n_n\def\m_syst_action_nop}
+% \def\doifelsenextoptional_n_n {\let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+%
+% \unexpanded\def\doifelsenextoptionalcs {\afterassignment\doifelsenextoptionalcs_n \let\m_syst_action_yes}
+% \def\doifelsenextoptionalcs_n {\afterassignment\doifelsenextoptionalcs_n_n\let\m_syst_action_nop}
+% \def\doifelsenextoptionalcs_n_n{\let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+
\def\syst_helpers_inspect_next_optional_character
{\ifx\nexttoken\blankspace
\expandafter\syst_helpers_reinspect_next_optional_character
@@ -491,8 +500,6 @@
%D \type {\def} comes into action. This way the space after \type {\:} becomes a
%D delimiter of the longer named \type {\reinspectnextcharacter}.
-% try: \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_character} {...}
-
\let\next\:
\def\:{\let\blankspace= } \:
@@ -514,6 +521,31 @@
\let\:\next
+%D This is much nicer and works too:
+
+% \def\firstofoneargument#1{#1}
+%
+% \expandafter\let\firstofoneargument{\blankspace= }
+%
+% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_character
+% } {\let\if_next_blank_space_token\iftrue
+% \futurelet\nexttoken\syst_helpers_inspect_next_character}
+%
+% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_optional_character
+% } {\let\if_next_blank_space_token\iftrue
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+%
+% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_bgroup_character
+% } {\let\if_next_blank_space_token\iftrue
+% \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character}
+%
+% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_parenthesis_character
+% } {\let\if_next_blank_space_token\iftrue
+% \futurelet\nexttoken\syst_helpers_inspect_next_parenthesis_character}
+%
+% \expandafter\def\firstofoneargument{\syst_helpers_ignore_spacing_blankspace
+% } {\futurelet\nexttoken\syst_helpers_ignore_spacing}
+
%D \macros
%D {setvalue,setgvalue,setevalue,setxvalue,
%D letvalue,letgvalue,getvalue,resetvalue,
@@ -529,7 +561,7 @@
%D \setevalue {name}{...} = \edef\name{...}
%D \setxvalue {name}{...} = \xdef\name{...}
%D \letvalue {name}=\... = \let\name=\...
-%D \letgvalue {name}=\... = \global\let\name=\...
+%D \letgvalue {name}=\... = \glet\name=\...
%D \getvalue {name} = \name
%D \resetvalue {name} = \def\name{}
%D \stoptyping
@@ -537,16 +569,16 @@
%D As we will see, \CONTEXT\ uses these commands many times, which is mainly due to
%D its object oriented and parameter driven character.
-\def\setvalue #1{\expandafter \def\csname#1\endcsname}
+\def\setvalue #1{\expandafter\def \csname#1\endcsname}
\def\setgvalue #1{\expandafter\gdef\csname#1\endcsname}
\def\setevalue #1{\expandafter\edef\csname#1\endcsname}
\def\setxvalue #1{\expandafter\xdef\csname#1\endcsname}
-\def\getvalue #1{\csname#1\endcsname}
-\def\letvalue #1{\expandafter\let\csname#1\endcsname}
-\def\letgvalue #1{\global\expandafter\let\csname#1\endcsname}
-\def\resetvalue #1{\expandafter\let\csname#1\endcsname\empty}
-\def\undefinevalue#1{\expandafter\let\csname#1\endcsname\undefined}
-\def\ignorevalue#1#2{\expandafter\let\csname#1\endcsname\empty}
+\def\getvalue #1{\csname#1\endcsname} % maybe: \begincsname#1\endcsname
+\def\letvalue #1{\expandafter\let \csname#1\endcsname}
+\def\letgvalue #1{\expandafter\glet\csname#1\endcsname}
+\def\resetvalue #1{\expandafter\let \csname#1\endcsname\empty}
+\def\undefinevalue#1{\expandafter\let \csname#1\endcsname\undefined}
+\def\ignorevalue#1#2{\expandafter\let \csname#1\endcsname\empty}
\def\setuvalue #1{\normalprotected\expandafter \def\csname#1\endcsname}
\def\setuevalue #1{\normalprotected\expandafter\edef\csname#1\endcsname}
@@ -562,7 +594,7 @@
%D tokens will save us some $300\times4=1200$ bytes of format file on a 32~bit
%D system. Not that it matters much today. This shortcut is already defined:
-\unexpanded\def\glet{\global\let} \let\globallet\glet
+\let\globallet\glet
%D \macros
%D {doifundefined,doifdefined,
@@ -635,7 +667,7 @@
{\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi}
\def\globalundefine#1% conditional
- {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi}
+ {\ifcsname#1\endcsname\expandafter\glet\csname#1\endcsname\undefined\fi}
%D Beware, being \type {\undefined} in \ETEX\ means that the macro {\em is} defined!
%D
@@ -705,6 +737,23 @@
\expandafter\secondoftwoarguments
\fi}
+%D Slightly faster on longer arguments (0.179 downto 0.141):
+%D
+%D \testfeatureonce{100000}{\doifelse{aaaaaaaaaaaaaaa}{bbbbbbbbbbbbbbb}\relax\relax}
+
+% \unexpanded\def\doifelse
+% {\afterassignment\doifelse_n\edef\m_syst_string_one}
+%
+% \unexpanded\def\doifelse_n
+% {\afterassignment\doifelse_n_n\edef\m_syst_string_two}
+%
+% \unexpanded\def\doifelse_n_n
+% {\ifx\m_syst_string_one\m_syst_string_two
+% \expandafter\firstoftwoarguments
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
%D \macros
%D {doifempty,doifemptyelse,doifnotempty}
%D
@@ -912,6 +961,7 @@
\unexpanded\def\doifelseinset#1#2{\clf_doifelseinset{#1}{#2}}
\unexpanded\def\doifinset #1#2{\clf_doifinset {#1}{#2}}
\unexpanded\def\doifnotinset #1#2{\clf_doifnotinset {#1}{#2}}
+ % \let\firstinset \clf_firstinset
\let\doifinsetelse\doifelseinset
@@ -1348,7 +1398,7 @@
%D
%D Sometimes the action to be undertaken depends on the
%D next character. This macro get this character and puts it in
-%D \type{\firstcharacter}.
+%D \type {\firstcharacter}.
%D
%D \starttyping
%D \getfirstcharacter {string}
@@ -2243,202 +2293,517 @@
% \dotripleempty\test[] xxx\par
% \dotripleempty\test xxx\par
+%D Common:
+
+\newtoks\t_syst_aux
+
+% \def\syst_helpers_empty_spaced_six {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][][] }
+% \def\syst_helpers_empty_normal_six {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][][]}
+% \def\syst_helpers_empty_spaced_five {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][] }
+% \def\syst_helpers_empty_normal_five {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][]}
+% \def\syst_helpers_empty_spaced_four {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][] }
+% \def\syst_helpers_empty_normal_four {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][]}
+% \def\syst_helpers_empty_spaced_three{\expandafter\m_syst_aux_do\the\t_syst_aux[][][] }
+% \def\syst_helpers_empty_normal_three{\expandafter\m_syst_aux_do\the\t_syst_aux[][][]}
+% \def\syst_helpers_empty_spaced_two {\expandafter\m_syst_aux_do\the\t_syst_aux[][] }
+% \def\syst_helpers_empty_normal_two {\expandafter\m_syst_aux_do\the\t_syst_aux[][]}
+% \def\syst_helpers_empty_spaced_one {\expandafter\m_syst_aux_do\the\t_syst_aux[] }
+% \def\syst_helpers_empty_normal_one {\expandafter\m_syst_aux_do\the\t_syst_aux[]}
+%
+% \def\syst_helpers_single_empty_one_yes {\firstargumenttrue \m_syst_aux_do}
+% \def\syst_helpers_double_empty_two_yes {\secondargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux}
+% \def\syst_helpers_triple_empty_three_yes {\thirdargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux}
+% \def\syst_helpers_quadruple_empty_four_yes {\fourthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux}
+% \def\syst_helpers_quintuple_empty_five_yes {\fifthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux}
+% \def\syst_helpers_sixtuple_empty_six_yes {\sixthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux}
+% \def\syst_helpers_seventuple_empty_seven_yes{\seventhargumenttrue\expandafter\m_syst_aux_do\the\t_syst_aux}
+%
+% with
+%
+% \unexpanded\def\dodoubleempty#1%
+% {\syst_helpers_argument_reset
+% \let\m_syst_aux_do#1% alias
+% \let\m_syst_action_yes\syst_helpers_double_empty_one_yes
+% \let\m_syst_action_nop\syst_helpers_double_empty_one_nop
+% \let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+%
+% \def\syst_helpers_double_empty_one_yes[#1]%
+% {\firstargumenttrue
+% \t_syst_aux{[{#1}]}% assignment
+% \let\m_syst_action_yes\syst_helpers_double_empty_two_yes
+% \let\m_syst_action_nop\syst_helpers_double_empty_two_nop
+% \let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+%
+% But we use this as it keeps the original name visible:
+
+\def\syst_helpers_empty_spaced_six {\the\t_syst_aux[][][][][][] }
+\def\syst_helpers_empty_normal_six {\the\t_syst_aux[][][][][][]}
+\def\syst_helpers_empty_spaced_five {\the\t_syst_aux[][][][][] }
+\def\syst_helpers_empty_normal_five {\the\t_syst_aux[][][][][]}
+\def\syst_helpers_empty_spaced_four {\the\t_syst_aux[][][][] }
+\def\syst_helpers_empty_normal_four {\the\t_syst_aux[][][][]}
+\def\syst_helpers_empty_spaced_three{\the\t_syst_aux[][][] }
+\def\syst_helpers_empty_normal_three{\the\t_syst_aux[][][]}
+\def\syst_helpers_empty_spaced_two {\the\t_syst_aux[][] }
+\def\syst_helpers_empty_normal_two {\the\t_syst_aux[][]}
+\def\syst_helpers_empty_spaced_one {\the\t_syst_aux[] }
+\def\syst_helpers_empty_normal_one {\the\t_syst_aux[]}
+
+\def\syst_helpers_single_empty_one_yes {\firstargumenttrue \the\t_syst_aux}
+\def\syst_helpers_double_empty_two_yes {\secondargumenttrue \the\t_syst_aux}
+\def\syst_helpers_triple_empty_three_yes {\thirdargumenttrue \the\t_syst_aux}
+\def\syst_helpers_quadruple_empty_four_yes {\fourthargumenttrue \the\t_syst_aux}
+\def\syst_helpers_quintuple_empty_five_yes {\fifthargumenttrue \the\t_syst_aux}
+\def\syst_helpers_sixtuple_empty_six_yes {\sixthargumenttrue \the\t_syst_aux}
+\def\syst_helpers_seventuple_empty_seven_yes{\seventhargumenttrue\the\t_syst_aux}
+
%D Single:
+% \unexpanded\def\dosingleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\firstargumenttrue#1}%
+% {\syst_helpers_single_empty_one_nop#1}}
+%
+% \def\syst_helpers_single_empty_one_nop#1%
+% {\firstargumentfalse
+% #1[]}
+
\unexpanded\def\dosingleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\firstargumenttrue#1}%
- {\syst_helpers_single_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_single_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_single_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_single_empty_one_nop#1%
+\def\syst_helpers_single_empty_one_nop
{\firstargumentfalse
- #1[]}
+ \the\t_syst_aux[]}
%D Double
+% \unexpanded\def\dodoubleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_double_empty_one_yes#1}%
+% {\syst_helpers_double_empty_one_nop#1}}
+%
+% \def\syst_helpers_double_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\secondargumenttrue#1[{#2}]}%
+% {\syst_helpers_double_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_double_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% #1[][]}
+%
+% \def\syst_helpers_double_empty_two_nop
+% {\secondargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_double_empty_one_spaced
+% \else
+% \expandafter\syst_helpers_double_empty_one_normal
+% \fi}
+%
+% \def\syst_helpers_double_empty_one_spaced#1#2{#1[{#2}][] }
+% \def\syst_helpers_double_empty_one_normal#1#2{#1[{#2}][]}
+
\unexpanded\def\dodoubleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_double_empty_one_yes#1}%
- {\syst_helpers_double_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_double_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_double_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_double_empty_one_yes#1[#2]%
+\def\syst_helpers_double_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\secondargumenttrue#1[{#2}]}%
- {\syst_helpers_double_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_double_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_double_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_double_empty_one_nop#1%
+\def\syst_helpers_double_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
- #1[][]}
+ \the\t_syst_aux[][]}
\def\syst_helpers_double_empty_two_nop
{\secondargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_double_empty_one_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_double_empty_one_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_double_empty_one_spaced#1#2{#1[{#2}][] }
-\def\syst_helpers_double_empty_one_normal#1#2{#1[{#2}][]}
+% Triple
-% Three
+% \unexpanded\def\dotripleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_triple_empty_one_yes#1}%
+% {\syst_helpers_triple_empty_one_nop#1}}
+%
+% \def\syst_helpers_triple_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_triple_empty_two_yes#1{#2}}%
+% {\syst_helpers_triple_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_triple_empty_two_yes#1#2[#3]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\thirdargumenttrue#1[{#2}][{#3}]}%
+% {\syst_helpers_triple_empty_three_nop#1{#2}{#3}}}
+%
+% \def\syst_helpers_triple_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% #1[][][]}
+%
+% \def\syst_helpers_triple_empty_two_nop
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_triple_empty_two_spaced
+% \else
+% \expandafter\syst_helpers_triple_empty_two_normal
+% \fi}
+%
+% \def\syst_helpers_triple_empty_three_nop
+% {\thirdargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_triple_empty_three_spaced
+% \else
+% \expandafter\syst_helpers_triple_empty_three_normal
+% \fi}
+%
+% \def\syst_helpers_triple_empty_two_spaced #1#2{#1[{#2}][][] }
+% \def\syst_helpers_triple_empty_two_normal #1#2{#1[{#2}][][]}
+% \def\syst_helpers_triple_empty_three_spaced#1#2#3{#1[{#2}][{#3}][] }
+% \def\syst_helpers_triple_empty_three_normal#1#2#3{#1[{#2}][{#3}][]}
\unexpanded\def\dotripleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_triple_empty_one_yes#1}%
- {\syst_helpers_triple_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_triple_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_triple_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_triple_empty_one_yes#1[#2]%
+\def\syst_helpers_triple_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_triple_empty_two_yes#1{#2}}%
- {\syst_helpers_triple_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_triple_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_triple_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_triple_empty_two_yes#1#2[#3]%
+\def\syst_helpers_triple_empty_two_yes[#1]%
{\secondargumenttrue
- \doifelsenextoptional
- {\thirdargumenttrue#1[{#2}][{#3}]}%
- {\syst_helpers_triple_empty_three_nop#1{#2}{#3}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_triple_empty_three_yes
+ \let\m_syst_action_nop\syst_helpers_triple_empty_three_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_triple_empty_one_nop#1%
+\def\syst_helpers_triple_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
\thirdargumentfalse
- #1[][][]}
+ \the\t_syst_aux[][][]}
\def\syst_helpers_triple_empty_two_nop
{\secondargumentfalse
\thirdargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_triple_empty_two_spaced
+ \expandafter\syst_helpers_empty_spaced_two
\else
- \expandafter\syst_helpers_triple_empty_two_normal
+ \expandafter\syst_helpers_empty_normal_two
\fi}
\def\syst_helpers_triple_empty_three_nop
{\thirdargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_triple_empty_three_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_triple_empty_three_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_triple_empty_two_spaced #1#2{#1[{#2}][][] }
-\def\syst_helpers_triple_empty_two_normal #1#2{#1[{#2}][][]}
-\def\syst_helpers_triple_empty_three_spaced#1#2#3{#1[{#2}][{#3}][] }
-\def\syst_helpers_triple_empty_three_normal#1#2#3{#1[{#2}][{#3}][]}
+%D Quadruple:
-%D Four:
+% \unexpanded\def\doquadrupleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_quadruple_empty_one_yes#1}%
+% {\syst_helpers_quadruple_empty_one_nop#1}}
+%
+% \def\syst_helpers_quadruple_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_quadruple_empty_two_yes#1{#2}}%
+% {\syst_helpers_quadruple_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_quadruple_empty_two_yes#1#2[#3]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_quadruple_empty_three_yes#1{#2}{#3}}%
+% {\syst_helpers_quadruple_empty_three_nop#1{#2}{#3}}}
+%
+% \def\syst_helpers_quadruple_empty_three_yes#1#2#3[#4]%
+% {\thirdargumenttrue
+% \doifelsenextoptional
+% {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}%
+% {\syst_helpers_quadruple_empty_four_nop#1{#2}{#3}{#4}}}
+%
+% \def\syst_helpers_quadruple_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% #1[][][][]}
+%
+% \def\syst_helpers_quadruple_empty_two_nop
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quadruple_empty_two_spaced
+% \else
+% \expandafter\syst_helpers_quadruple_empty_two_normal
+% \fi}
+%
+% \def\syst_helpers_quadruple_empty_three_nop
+% {\thirdargumentfalse
+% \fourthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quadruple_empty_three_spaced
+% \else
+% \expandafter\syst_helpers_quadruple_empty_three_normal
+% \fi}
+%
+% \def\syst_helpers_quadruple_empty_four_nop
+% {\fourthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quadruple_empty_four_spaced
+% \else
+% \expandafter\syst_helpers_quadruple_empty_four_normal
+% \fi}
+%
+% \def\syst_helpers_quadruple_empty_two_spaced #1#2{#1[{#2}][][][] }
+% \def\syst_helpers_quadruple_empty_two_normal #1#2{#1[{#2}][][][]}
+% \def\syst_helpers_quadruple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][] }
+% \def\syst_helpers_quadruple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][]}
+% \def\syst_helpers_quadruple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][] }
+% \def\syst_helpers_quadruple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][]}
\unexpanded\def\doquadrupleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_quadruple_empty_one_yes#1}%
- {\syst_helpers_quadruple_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_quadruple_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_quadruple_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quadruple_empty_one_yes#1[#2]%
+\def\syst_helpers_quadruple_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_quadruple_empty_two_yes#1{#2}}%
- {\syst_helpers_quadruple_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quadruple_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_quadruple_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quadruple_empty_two_yes#1#2[#3]%
+\def\syst_helpers_quadruple_empty_two_yes[#1]%
{\secondargumenttrue
- \doifelsenextoptional
- {\syst_helpers_quadruple_empty_three_yes#1{#2}{#3}}%
- {\syst_helpers_quadruple_empty_three_nop#1{#2}{#3}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quadruple_empty_three_yes
+ \let\m_syst_action_nop\syst_helpers_quadruple_empty_three_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quadruple_empty_three_yes#1#2#3[#4]%
+\def\syst_helpers_quadruple_empty_three_yes[#1]%
{\thirdargumenttrue
- \doifelsenextoptional
- {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}%
- {\syst_helpers_quadruple_empty_four_nop#1{#2}{#3}{#4}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quadruple_empty_four_yes
+ \let\m_syst_action_nop\syst_helpers_quadruple_empty_four_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quadruple_empty_one_nop#1%
+\def\syst_helpers_quadruple_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
\thirdargumentfalse
\fourthargumentfalse
- #1[][][][]}
+ \the\t_syst_aux[][][][]}
\def\syst_helpers_quadruple_empty_two_nop
{\secondargumentfalse
\thirdargumentfalse
\fourthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quadruple_empty_two_spaced
+ \expandafter\syst_helpers_empty_spaced_three
\else
- \expandafter\syst_helpers_quadruple_empty_two_normal
+ \expandafter\syst_helpers_empty_normal_three
\fi}
\def\syst_helpers_quadruple_empty_three_nop
{\thirdargumentfalse
\fourthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quadruple_empty_three_spaced
+ \expandafter\syst_helpers_empty_spaced_two
\else
- \expandafter\syst_helpers_quadruple_empty_three_normal
+ \expandafter\syst_helpers_empty_normal_two
\fi}
\def\syst_helpers_quadruple_empty_four_nop
{\fourthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quadruple_empty_four_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_quadruple_empty_four_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_quadruple_empty_two_spaced #1#2{#1[{#2}][][][] }
-\def\syst_helpers_quadruple_empty_two_normal #1#2{#1[{#2}][][][]}
-\def\syst_helpers_quadruple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][] }
-\def\syst_helpers_quadruple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][]}
-\def\syst_helpers_quadruple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][] }
-\def\syst_helpers_quadruple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][]}
+%D Quintuple:
-%D Five:
+% \unexpanded\def\doquintupleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_quintuple_empty_one_yes#1}%
+% {\syst_helpers_quintuple_empty_one_nop#1}}
+%
+% \def\syst_helpers_quintuple_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_quintuple_empty_two_yes#1{#2}}%
+% {\syst_helpers_quintuple_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_quintuple_empty_two_yes#1#2[#3]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_quintuple_empty_three_yes#1{#2}{#3}}%
+% {\syst_helpers_quintuple_empty_three_nop#1{#2}{#3}}}
+%
+% \def\syst_helpers_quintuple_empty_three_yes#1#2#3[#4]%
+% {\thirdargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_quintuple_empty_four_yes#1{#2}{#3}{#4}}%
+% {\syst_helpers_quintuple_empty_four_nop#1{#2}{#3}{#4}}}
+%
+% \def\syst_helpers_quintuple_empty_four_yes#1#2#3#4[#5]%
+% {\fourthargumenttrue
+% \doifelsenextoptional
+% {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}%
+% {\syst_helpers_quintuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+%
+% \def\syst_helpers_quintuple_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% #1[][][][][]}
+%
+% \def\syst_helpers_quintuple_empty_two_nop
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quintuple_empty_two_spaced
+% \else
+% \expandafter\syst_helpers_quintuple_empty_two_normal
+% \fi}
+%
+% \def\syst_helpers_quintuple_empty_three_nop
+% {\thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quintuple_empty_three_spaced
+% \else
+% \expandafter\syst_helpers_quintuple_empty_three_normal
+% \fi}
+%
+% \def\syst_helpers_quintuple_empty_four_nop
+% {\fourthargumentfalse
+% \fifthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quintuple_empty_four_spaced
+% \else
+% \expandafter\syst_helpers_quintuple_empty_four_normal
+% \fi}
+%
+% \def\syst_helpers_quintuple_empty_five_nop
+% {\fifthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_quintuple_empty_five_spaced
+% \else
+% \expandafter\syst_helpers_quintuple_empty_five_normal
+% \fi}
+%
+% \def\syst_helpers_quintuple_empty_two_spaced #1#2{#1[{#2}][][][][] }
+% \def\syst_helpers_quintuple_empty_two_normal #1#2{#1[{#2}][][][][]}
+% \def\syst_helpers_quintuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][] }
+% \def\syst_helpers_quintuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][]}
+% \def\syst_helpers_quintuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][] }
+% \def\syst_helpers_quintuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][]}
+% \def\syst_helpers_quintuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][] }
+% \def\syst_helpers_quintuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][]}
\unexpanded\def\doquintupleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_quintuple_empty_one_yes#1}%
- {\syst_helpers_quintuple_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_quintuple_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_quintuple_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quintuple_empty_one_yes#1[#2]%
+\def\syst_helpers_quintuple_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_quintuple_empty_two_yes#1{#2}}%
- {\syst_helpers_quintuple_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quintuple_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_quintuple_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quintuple_empty_two_yes#1#2[#3]%
+\def\syst_helpers_quintuple_empty_two_yes[#1]%
{\secondargumenttrue
- \doifelsenextoptional
- {\syst_helpers_quintuple_empty_three_yes#1{#2}{#3}}%
- {\syst_helpers_quintuple_empty_three_nop#1{#2}{#3}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quintuple_empty_three_yes
+ \let\m_syst_action_nop\syst_helpers_quintuple_empty_three_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quintuple_empty_three_yes#1#2#3[#4]%
+\def\syst_helpers_quintuple_empty_three_yes[#1]%
{\thirdargumenttrue
- \doifelsenextoptional
- {\syst_helpers_quintuple_empty_four_yes#1{#2}{#3}{#4}}%
- {\syst_helpers_quintuple_empty_four_nop#1{#2}{#3}{#4}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quintuple_empty_four_yes
+ \let\m_syst_action_nop\syst_helpers_quintuple_empty_four_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quintuple_empty_four_yes#1#2#3#4[#5]%
+\def\syst_helpers_quintuple_empty_four_yes[#1]%
{\fourthargumenttrue
- \doifelsenextoptional
- {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}%
- {\syst_helpers_quintuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_quintuple_empty_five_yes
+ \let\m_syst_action_nop\syst_helpers_quintuple_empty_five_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_quintuple_empty_one_nop#1%
+\def\syst_helpers_quintuple_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
\thirdargumentfalse
\fourthargumentfalse
\fifthargumentfalse
- #1[][][][][]}
+ \the\t_syst_aux[][][][][]}
\def\syst_helpers_quintuple_empty_two_nop
{\secondargumentfalse
@@ -2446,9 +2811,9 @@
\fourthargumentfalse
\fifthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quintuple_empty_two_spaced
+ \expandafter\syst_helpers_empty_spaced_four
\else
- \expandafter\syst_helpers_quintuple_empty_two_normal
+ \expandafter\syst_helpers_empty_normal_four
\fi}
\def\syst_helpers_quintuple_empty_three_nop
@@ -2456,83 +2821,192 @@
\fourthargumentfalse
\fifthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quintuple_empty_three_spaced
+ \expandafter\syst_helpers_empty_spaced_three
\else
- \expandafter\syst_helpers_quintuple_empty_three_normal
+ \expandafter\syst_helpers_empty_normal_three
\fi}
\def\syst_helpers_quintuple_empty_four_nop
{\fourthargumentfalse
\fifthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quintuple_empty_four_spaced
+ \expandafter\syst_helpers_empty_spaced_two
\else
- \expandafter\syst_helpers_quintuple_empty_four_normal
+ \expandafter\syst_helpers_empty_normal_two
\fi}
\def\syst_helpers_quintuple_empty_five_nop
{\fifthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_quintuple_empty_five_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_quintuple_empty_five_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_quintuple_empty_two_spaced #1#2{#1[{#2}][][][][] }
-\def\syst_helpers_quintuple_empty_two_normal #1#2{#1[{#2}][][][][]}
-\def\syst_helpers_quintuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][] }
-\def\syst_helpers_quintuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][]}
-\def\syst_helpers_quintuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][] }
-\def\syst_helpers_quintuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][]}
-\def\syst_helpers_quintuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][] }
-\def\syst_helpers_quintuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][]}
+%D Sixtuple:
-%D Six
+% \unexpanded\def\dosixtupleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_sixtuple_empty_one_yes#1}
+% {\syst_helpers_sixtuple_empty_one_nop#1}}
+%
+% \def\syst_helpers_sixtuple_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_sixtuple_empty_two_yes#1{#2}}%
+% {\syst_helpers_sixtuple_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_sixtuple_empty_two_yes#1#2[#3]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_sixtuple_empty_three_yes#1{#2}{#3}}%
+% {\syst_helpers_sixtuple_empty_three_nop#1{#2}{#3}}}
+%
+% \def\syst_helpers_sixtuple_empty_three_yes#1#2#3[#4]%
+% {\thirdargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_sixtuple_empty_four_yes#1{#2}{#3}{#4}}%
+% {\syst_helpers_sixtuple_empty_four_nop#1{#2}{#3}{#4}}}
+%
+% \def\syst_helpers_sixtuple_empty_four_yes#1#2#3#4[#5]%
+% {\fourthargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_sixtuple_empty_five_yes#1{#2}{#3}{#4}{#5}}%
+% {\syst_helpers_sixtuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+%
+% \def\syst_helpers_sixtuple_empty_five_yes#1#2#3#4#5[#6]%
+% {\fifthargumenttrue
+% \doifelsenextoptional
+% {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}%
+% {\syst_helpers_sixtuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}}
+%
+% \def\syst_helpers_sixtuple_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% #1[][][][][][]}
+%
+% \def\syst_helpers_sixtuple_empty_two_nop
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_sixtuple_empty_two_spaced
+% \else
+% \expandafter\syst_helpers_sixtuple_empty_two_normal
+% \fi}
+%
+% \def\syst_helpers_sixtuple_empty_three_nop
+% {\thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_sixtuple_empty_three_spaced
+% \else
+% \expandafter\syst_helpers_sixtuple_empty_three_normal
+% \fi}
+%
+% \def\syst_helpers_sixtuple_empty_four_nop
+% {\fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_sixtuple_empty_four_spaced
+% \else
+% \expandafter\syst_helpers_sixtuple_empty_four_normal
+% \fi}
+%
+% \def\syst_helpers_sixtuple_empty_five_nop
+% {\fifthargumentfalse
+% \sixthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_sixtuple_empty_five_spaced
+% \else
+% \expandafter\syst_helpers_sixtuple_empty_five_normal
+% \fi}
+%
+% \def\syst_helpers_sixtuple_empty_six_nop
+% {\sixthargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_sixtuple_empty_six_spaced
+% \else
+% \expandafter\syst_helpers_sixtuple_empty_six_normal
+% \fi}
+%
+% \def\syst_helpers_sixtuple_empty_two_spaced #1#2{#1[{#2}][][][][][] }
+% \def\syst_helpers_sixtuple_empty_two_normal #1#2{#1[{#2}][][][][][]}
+% \def\syst_helpers_sixtuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][] }
+% \def\syst_helpers_sixtuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][]}
+% \def\syst_helpers_sixtuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][] }
+% \def\syst_helpers_sixtuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][]}
+% \def\syst_helpers_sixtuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][] }
+% \def\syst_helpers_sixtuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][]}
+% \def\syst_helpers_sixtuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][] }
+% \def\syst_helpers_sixtuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][]}
\unexpanded\def\dosixtupleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_sixtuple_empty_one_yes#1}
- {\syst_helpers_sixtuple_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_one_yes#1[#2]%
+\def\syst_helpers_sixtuple_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_sixtuple_empty_two_yes#1{#2}}%
- {\syst_helpers_sixtuple_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_two_yes#1#2[#3]%
+\def\syst_helpers_sixtuple_empty_two_yes[#1]%
{\secondargumenttrue
- \doifelsenextoptional
- {\syst_helpers_sixtuple_empty_three_yes#1{#2}{#3}}%
- {\syst_helpers_sixtuple_empty_three_nop#1{#2}{#3}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_three_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_three_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_three_yes#1#2#3[#4]%
+\def\syst_helpers_sixtuple_empty_three_yes[#1]%
{\thirdargumenttrue
- \doifelsenextoptional
- {\syst_helpers_sixtuple_empty_four_yes#1{#2}{#3}{#4}}%
- {\syst_helpers_sixtuple_empty_four_nop#1{#2}{#3}{#4}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_four_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_four_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_four_yes#1#2#3#4[#5]%
+\def\syst_helpers_sixtuple_empty_four_yes[#1]%
{\fourthargumenttrue
- \doifelsenextoptional
- {\syst_helpers_sixtuple_empty_five_yes#1{#2}{#3}{#4}{#5}}%
- {\syst_helpers_sixtuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_five_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_five_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_five_yes#1#2#3#4#5[#6]%
+\def\syst_helpers_sixtuple_empty_five_yes[#1]%
{\fifthargumenttrue
- \doifelsenextoptional
- {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}%
- {\syst_helpers_sixtuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_sixtuple_empty_six_yes
+ \let\m_syst_action_nop\syst_helpers_sixtuple_empty_six_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_sixtuple_empty_one_nop#1%
+\def\syst_helpers_sixtuple_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
\thirdargumentfalse
\fourthargumentfalse
\fifthargumentfalse
\sixthargumentfalse
- #1[][][][][][]}
+ \the\t_syst_aux[][][][][][]}
\def\syst_helpers_sixtuple_empty_two_nop
{\secondargumentfalse
@@ -2541,9 +3015,9 @@
\fifthargumentfalse
\sixthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_sixtuple_empty_two_spaced
+ \expandafter\syst_helpers_empty_spaced_five
\else
- \expandafter\syst_helpers_sixtuple_empty_two_normal
+ \expandafter\syst_helpers_empty_normal_five
\fi}
\def\syst_helpers_sixtuple_empty_three_nop
@@ -2552,9 +3026,9 @@
\fifthargumentfalse
\sixthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_sixtuple_empty_three_spaced
+ \expandafter\syst_helpers_empty_spaced_four
\else
- \expandafter\syst_helpers_sixtuple_empty_three_normal
+ \expandafter\syst_helpers_empty_normal_four
\fi}
\def\syst_helpers_sixtuple_empty_four_nop
@@ -2562,84 +3036,215 @@
\fifthargumentfalse
\sixthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_sixtuple_empty_four_spaced
+ \expandafter\syst_helpers_empty_spaced_three
\else
- \expandafter\syst_helpers_sixtuple_empty_four_normal
+ \expandafter\syst_helpers_empty_normal_three
\fi}
\def\syst_helpers_sixtuple_empty_five_nop
{\fifthargumentfalse
\sixthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_sixtuple_empty_five_spaced
+ \expandafter\syst_helpers_empty_spaced_two
\else
- \expandafter\syst_helpers_sixtuple_empty_five_normal
+ \expandafter\syst_helpers_empty_normal_two
\fi}
\def\syst_helpers_sixtuple_empty_six_nop
{\sixthargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_sixtuple_empty_six_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_sixtuple_empty_six_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_sixtuple_empty_two_spaced #1#2{#1[{#2}][][][][][] }
-\def\syst_helpers_sixtuple_empty_two_normal #1#2{#1[{#2}][][][][][]}
-\def\syst_helpers_sixtuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][] }
-\def\syst_helpers_sixtuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][]}
-\def\syst_helpers_sixtuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][] }
-\def\syst_helpers_sixtuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][]}
-\def\syst_helpers_sixtuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][] }
-\def\syst_helpers_sixtuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][]}
-\def\syst_helpers_sixtuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][] }
-\def\syst_helpers_sixtuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][]}
+%D Seventuple:
-%D Seven:
+% \unexpanded\def\doseventupleempty#1%
+% {\syst_helpers_argument_reset
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_one_yes#1}%
+% {\syst_helpers_seventuple_empty_one_nop#1}}
+%
+% \def\syst_helpers_seventuple_empty_one_yes#1[#2]%
+% {\firstargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_two_yes#1{#2}}%
+% {\syst_helpers_seventuple_empty_two_nop#1{#2}}}
+%
+% \def\syst_helpers_seventuple_empty_two_yes#1#2[#3]%
+% {\secondargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_three_yes#1{#2}{#3}}%
+% {\syst_helpers_seventuple_empty_three_nop#1{#2}{#3}}}
+%
+% \def\syst_helpers_seventuple_empty_three_yes#1#2#3[#4]%
+% {\thirdargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_four_yes#1{#2}{#3}{#4}}%
+% {\syst_helpers_seventuple_empty_four_nop#1{#2}{#3}{#4}}}
+%
+% \def\syst_helpers_seventuple_empty_four_yes#1#2#3#4[#5]%
+% {\fourthargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_five_yes#1{#2}{#3}{#4}{#5}}%
+% {\syst_helpers_seventuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+%
+% \def\syst_helpers_seventuple_empty_five_yes#1#2#3#4#5[#6]%
+% {\fifthargumenttrue
+% \doifelsenextoptional
+% {\syst_helpers_seventuple_empty_six_yes#1{#2}{#3}{#4}{#5}{#6}}%
+% {\syst_helpers_seventuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}}
+%
+% \def\syst_helpers_seventuple_empty_six_yes#1#2#3#4#5#6[#7]%
+% {\sixthargumenttrue
+% \doifelsenextoptional
+% {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}%
+% {\syst_helpers_seventuple_empty_seven_nop#1{#2}{#3}{#4}{#5}{#6}{#7}}}
+%
+% \def\syst_helpers_seventuple_empty_one_nop#1%
+% {\firstargumentfalse
+% \secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \seventhargumentfalse
+% #1[][][][][][][]}
+%
+% \def\syst_helpers_seventuple_empty_two_nop
+% {\secondargumentfalse
+% \thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_two_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_two_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_three_nop
+% {\thirdargumentfalse
+% \fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_three_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_three_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_four_nop
+% {\fourthargumentfalse
+% \fifthargumentfalse
+% \sixthargumentfalse
+% \seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_four_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_four_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_five_nop
+% {\fifthargumentfalse
+% \sixthargumentfalse
+% \seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_five_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_five_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_six_nop
+% {\sixthargumentfalse
+% \seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_six_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_six_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_seven_nop
+% {\seventhargumentfalse
+% \if_next_blank_space_token
+% \expandafter\syst_helpers_seventuple_empty_seven_spaced
+% \else
+% \expandafter\syst_helpers_seventuple_empty_seven_normal
+% \fi}
+%
+% \def\syst_helpers_seventuple_empty_two_spaced #1#2{#1[{#2}][][][][][][] }
+% \def\syst_helpers_seventuple_empty_two_normal #1#2{#1[{#2}][][][][][][]}
+% \def\syst_helpers_seventuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][][] }
+% \def\syst_helpers_seventuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][][]}
+% \def\syst_helpers_seventuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][] }
+% \def\syst_helpers_seventuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][]}
+% \def\syst_helpers_seventuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][] }
+% \def\syst_helpers_seventuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][]}
+% \def\syst_helpers_seventuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][] }
+% \def\syst_helpers_seventuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][]}
+% \def\syst_helpers_seventuple_empty_seven_spaced#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][] }
+% \def\syst_helpers_seventuple_empty_seven_normal#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][]}
\unexpanded\def\doseventupleempty#1%
{\syst_helpers_argument_reset
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_one_yes#1}%
- {\syst_helpers_seventuple_empty_one_nop#1}}
+ \t_syst_aux{#1}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_one_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_one_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_one_yes#1[#2]%
+\def\syst_helpers_seventuple_empty_one_yes[#1]%
{\firstargumenttrue
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_two_yes#1{#2}}%
- {\syst_helpers_seventuple_empty_two_nop#1{#2}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_two_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_two_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_two_yes#1#2[#3]%
+\def\syst_helpers_seventuple_empty_two_yes[#1]%
{\secondargumenttrue
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_three_yes#1{#2}{#3}}%
- {\syst_helpers_seventuple_empty_three_nop#1{#2}{#3}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_three_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_three_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_three_yes#1#2#3[#4]%
+\def\syst_helpers_seventuple_empty_three_yes[#1]%
{\thirdargumenttrue
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_four_yes#1{#2}{#3}{#4}}%
- {\syst_helpers_seventuple_empty_four_nop#1{#2}{#3}{#4}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_four_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_four_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_four_yes#1#2#3#4[#5]%
+\def\syst_helpers_seventuple_empty_four_yes[#1]%
{\fourthargumenttrue
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_five_yes#1{#2}{#3}{#4}{#5}}%
- {\syst_helpers_seventuple_empty_five_nop#1{#2}{#3}{#4}{#5}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_five_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_five_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_five_yes#1#2#3#4#5[#6]%
+\def\syst_helpers_seventuple_empty_five_yes[#1]%
{\fifthargumenttrue
- \doifelsenextoptional
- {\syst_helpers_seventuple_empty_six_yes#1{#2}{#3}{#4}{#5}{#6}}%
- {\syst_helpers_seventuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_six_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_six_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_six_yes#1#2#3#4#5#6[#7]%
+\def\syst_helpers_seventuple_empty_six_yes[#1]%
{\sixthargumenttrue
- \doifelsenextoptional
- {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}%
- {\syst_helpers_seventuple_empty_seven_nop#1{#2}{#3}{#4}{#5}{#6}{#7}}}
+ \toksapp\t_syst_aux{[{#1}]}%
+ \let\m_syst_action_yes\syst_helpers_seventuple_empty_seven_yes
+ \let\m_syst_action_nop\syst_helpers_seventuple_empty_seven_nop
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
-\def\syst_helpers_seventuple_empty_one_nop#1%
+\def\syst_helpers_seventuple_empty_one_nop
{\firstargumentfalse
\secondargumentfalse
\thirdargumentfalse
@@ -2647,7 +3252,7 @@
\fifthargumentfalse
\sixthargumentfalse
\seventhargumentfalse
- #1[][][][][][][]}
+ \the\t_syst_aux[][][][][][][]}
\def\syst_helpers_seventuple_empty_two_nop
{\secondargumentfalse
@@ -2657,9 +3262,9 @@
\sixthargumentfalse
\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_two_spaced
+ \expandafter\syst_helpers_empty_spaced_six
\else
- \expandafter\syst_helpers_seventuple_empty_two_normal
+ \expandafter\syst_helpers_empty_normal_six
\fi}
\def\syst_helpers_seventuple_empty_three_nop
@@ -2669,9 +3274,9 @@
\sixthargumentfalse
\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_three_spaced
+ \expandafter\syst_helpers_empty_spaced_five
\else
- \expandafter\syst_helpers_seventuple_empty_three_normal
+ \expandafter\syst_helpers_empty_normal_five
\fi}
\def\syst_helpers_seventuple_empty_four_nop
@@ -2680,9 +3285,9 @@
\sixthargumentfalse
\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_four_spaced
+ \expandafter\syst_helpers_empty_spaced_four
\else
- \expandafter\syst_helpers_seventuple_empty_four_normal
+ \expandafter\syst_helpers_empty_normal_four
\fi}
\def\syst_helpers_seventuple_empty_five_nop
@@ -2690,40 +3295,29 @@
\sixthargumentfalse
\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_five_spaced
+ \expandafter\syst_helpers_empty_spaced_three
\else
- \expandafter\syst_helpers_seventuple_empty_five_normal
+ \expandafter\syst_helpers_empty_normal_three
\fi}
\def\syst_helpers_seventuple_empty_six_nop
{\sixthargumentfalse
\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_six_spaced
+ \expandafter\syst_helpers_empty_spaced_two
\else
- \expandafter\syst_helpers_seventuple_empty_six_normal
+ \expandafter\syst_helpers_empty_normal_two
\fi}
\def\syst_helpers_seventuple_empty_seven_nop
{\seventhargumentfalse
\if_next_blank_space_token
- \expandafter\syst_helpers_seventuple_empty_seven_spaced
+ \expandafter\syst_helpers_empty_spaced_one
\else
- \expandafter\syst_helpers_seventuple_empty_seven_normal
+ \expandafter\syst_helpers_empty_normal_one
\fi}
-\def\syst_helpers_seventuple_empty_two_spaced #1#2{#1[{#2}][][][][][][] }
-\def\syst_helpers_seventuple_empty_two_normal #1#2{#1[{#2}][][][][][][]}
-\def\syst_helpers_seventuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][][] }
-\def\syst_helpers_seventuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][][]}
-\def\syst_helpers_seventuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][] }
-\def\syst_helpers_seventuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][]}
-\def\syst_helpers_seventuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][] }
-\def\syst_helpers_seventuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][]}
-\def\syst_helpers_seventuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][] }
-\def\syst_helpers_seventuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][]}
-\def\syst_helpers_seventuple_empty_seven_spaced#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][] }
-\def\syst_helpers_seventuple_empty_seven_normal#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][]}
+%D Aliases:
\let\dosingleargument \dosingleempty
\let\dodoubleargument \dodoubleempty
@@ -2900,7 +3494,7 @@
\begingroup
\def\\ {\syst_helpers_get_grouped_argument\syst_helpers_get_grouped_argument_yes\syst_helpers_get_grouped_argument_nop}
- \global\let\syst_helpers_get_grouped_argument_e\\
+ \glet\syst_helpers_get_grouped_argument_e\\
\endgroup
\def\syst_helpers_get_grouped_argument_f
@@ -3031,13 +3625,13 @@
%D
%D Trivial:
-\unexpanded\def\letempty #1{\let#1\empty}
-\unexpanded\def\globalletempty#1{\global\let#1\empty}
+\unexpanded\def\letempty #1{\let #1\empty}
+\unexpanded\def\globalletempty#1{\glet#1\empty}
-\unexpanded\def\letvalueempty #1{\expandafter\let\csname#1\endcsname\empty}
-\unexpanded\def\letgvalueempty#1{\global\expandafter\let\csname#1\endcsname\empty}
-\unexpanded\def\letvaluerelax #1{\expandafter\let\csname#1\endcsname\relax}
-\unexpanded\def\letgvalurelax #1{\global\expandafter\let\csname#1\endcsname\relax}
+\unexpanded\def\letvalueempty #1{\expandafter\let \csname#1\endcsname\empty}
+\unexpanded\def\letgvalueempty#1{\expandafter\glet\csname#1\endcsname\empty}
+\unexpanded\def\letvaluerelax #1{\expandafter\let \csname#1\endcsname\relax}
+\unexpanded\def\letgvalurelax #1{\expandafter\glet\csname#1\endcsname\relax}
\unexpanded\def\relaxvalueifundefined#1%
{\ifcsname#1\endcsname \else
@@ -3183,17 +3777,25 @@
%D Apart from the prefixes, a few more \type{\expandafters}
%D are needed:
-\unexpanded\def\newif#1%
- {\privatescratchcounter\escapechar
- \escapechar\minusone
- \expandafter\expandafter\expandafter
- \redoglobal\expandafter\expandafter\expandafter
- \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}%
- \expandafter\expandafter\expandafter
- \redoglobal\expandafter\expandafter\expandafter
- \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}%
- \dodoglobal\@if#1{false}%
- \escapechar\privatescratchcounter}
+% \unexpanded\def\newif#1% uses the original plain \@if
+% {\privatescratchcounter\escapechar
+% \escapechar\minusone
+% \expandafter\expandafter\expandafter
+% \redoglobal\expandafter\expandafter\expandafter
+% \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}%
+% \expandafter\expandafter\expandafter
+% \redoglobal\expandafter\expandafter\expandafter
+% \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}%
+% \dodoglobal\@if#1{false}%
+% \escapechar\privatescratchcounter}
+
+\normalprotected\def\newif#1% see syst-ini.mkiv
+ {\let\new_if_saved\newif
+ \let\newif\new_if_check
+ \expandafter\redoglobal\expandafter\def\csname\expandafter\newif\csstring#1true\endcsname {\let#1\iftrue }%
+ \expandafter\redoglobal\expandafter\def\csname\expandafter\newif\csstring#1false\endcsname{\let#1\iffalse}%
+ \dodoglobal\csname\expandafter\newif\csstring#1false\endcsname
+ \let\newif\new_if_saved}
%D Also new:
@@ -3245,7 +3847,7 @@
% \bgroup \obeylines
%
-% \global\let\stoptexdefinition\relax
+% \glet\stoptexdefinition\relax
%
% \unexpanded\gdef\starttexdefinition%
% {\bgroup%
@@ -3302,7 +3904,7 @@
% \bgroup \obeylines
%
-% \global\let\stoptexdefinition\relax
+% \glet\stoptexdefinition\relax
%
% \unexpanded\gdef\starttexdefinition%
% {\bgroup%
@@ -3321,7 +3923,7 @@
\bgroup \obeylines
-\global\let\stoptexdefinition\relax
+\glet\stoptexdefinition\relax
\unexpanded\gdef\starttexdefinition%
{\bgroup%
@@ -3538,8 +4140,8 @@
\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
{\global\advance\outerrecurse \plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname{#4}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#4}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\ifnum#3>\zerocount\relax
\ifnum#2<#1\relax
\let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
@@ -3567,7 +4169,7 @@
\fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
\unexpanded\def\syst_helpers_recurse_content
- {\csname\??recurseaction\recursedepth\endcsname}
+ {\csname\??recurseaction\the\outerrecurse\endcsname}
\unexpanded\def\syst_helpers_stepwise_recurse_yes
{\syst_helpers_recurse_content
@@ -3591,11 +4193,11 @@
{\syst_helpers_stepwise_recurse_nop\relax}
\unexpanded\def\syst_helpers_stepwise_recurse_nop#1#2#3#4%
- {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+ {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse\minusone}
% \unexpanded\def\nonostepwiserecurse#1#2#3%
-% {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+% {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
% \global\advance\outerrecurse\minusone}
\unexpanded\def\dorecurse#1%
@@ -3636,16 +4238,16 @@
\unexpanded\def\syst_helpers_recurse_x#1#2%
{\global\advance\outerrecurse \plusone
- \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname{#2}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#2}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\expandafter\syst_helpers_recurse_indeed\expandafter1\expandafter{\number#1}}
\unexpanded\def\syst_helpers_recurse_y#1#2%
{\global\advance\outerrecurse \plusone
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\glet\csname\??recurseindex\the\outerrecurse\endcsname\recurselevel
\let\recurselevel\!!plusone
#2%
- \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+ \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse \minusone}
\unexpanded\def\syst_helpers_recurse_indeed#1#2% from to
@@ -3670,7 +4272,7 @@
\syst_helpers_recurse_indeed}
\unexpanded\def\syst_helpers_recurse_indeed_nop#1#2#3%
- {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+ {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse \minusone }
%D \macros
@@ -3708,8 +4310,8 @@
\unexpanded\def\doloop#1%
{\global\advance\outerrecurse \plusone
- \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname{#1}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#1}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\let\endofloop\syst_helpers_loop
\syst_helpers_loop1} % no \plusone else \recurselevel wrong
@@ -3723,7 +4325,7 @@
\unexpanded\def\syst_helpers_loop_nop#1%
{\let\endofloop\syst_helpers_loop % new, permits nested \doloop's
- \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+ \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse\minusone}
\unexpanded\def\exitloop % \exitloop quits at end
@@ -3771,59 +4373,61 @@
%D \stoptyping
\def\syst_helpers_recurse_content
- {\csname\??recurseaction\recursedepth\expandafter\expandafter\expandafter\endcsname
- \expandafter\expandafter\expandafter{\expandafter\recurselevel\expandafter}\expandafter{\recursedepth}}
+ {\csname\??recurseaction\the\outerrecurse\expandafter\expandafter\expandafter\endcsname
+ \expandafter\expandafter\expandafter{\expandafter\recurselevel\expandafter}\expandafter{\the\outerrecurse}}
\unexpanded\def\syst_helpers_recurse_x#1#2%
{\global\advance\outerrecurse \plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#2}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#2}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\expandafter\syst_helpers_recurse_indeed\expandafter1\expandafter{\number#1}}
\unexpanded\def\syst_helpers_recurse_y#1#2%
{\global\advance\outerrecurse \plusone
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\let\recurselevel\!!plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#2}%
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#2}%
\syst_helpers_recurse_content
- \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname
+ \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse \minusone}
-\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
- {\global\advance\outerrecurse \plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
- \ifnum#3>\zerocount\relax
- \ifnum#2<#1\relax
- \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
- \else
- \let\syst_helpers_stepwise_next\syst_helpers_stepwise_recurse
- \fi
- \else
- \ifnum#3<\zerocount\relax
- \ifnum#1<#2\relax
- \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
- \else
- \let\syst_helpers_stepwise_next\syst_helpers_stepwise_reverse
- \fi
- \else
- \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
- \fi
- \fi\normalexpanded{\syst_helpers_stepwise_next{\number#1}{\number#2}{\number#3}}}
-
\unexpanded\def\doloop#1%
{\global\advance\outerrecurse \plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#1}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#1}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\let\endofloop\syst_helpers_loop
\syst_helpers_loop1} % no \plusone else \recurselevel wrong
-% faster
-
+% for instance:
+%
+% \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
+% {\global\advance\outerrecurse \plusone
+% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}%
+% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
+% \ifnum#3>\zerocount\relax
+% \ifnum#2<#1\relax
+% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
+% \else
+% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_recurse
+% \fi
+% \else
+% \ifnum#3<\zerocount\relax
+% \ifnum#1<#2\relax
+% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
+% \else
+% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_reverse
+% \fi
+% \else
+% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit
+% \fi
+% \fi\normalexpanded{\syst_helpers_stepwise_next{\number#1}{\number#2}{\number#3}}}
+%
+% faster:
+%
% \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
% {\global\advance\outerrecurse \plusone
-% \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}%
-% \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}%
+% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
% \csname @swr%
% \ifnum#3>\zerocount
% \ifnum#2<#1\else d\fi
@@ -3831,17 +4435,19 @@
% \ifnum#1<#2\else r\fi
% \fi\fi
% \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}}
-
+%
% \let\@swr \syst_helpers_stepwise_exit
% \let\@swrd\syst_helpers_stepwise_recurse
% \let\@swrr\syst_helpers_stepwise_reverse
+%
+% nicer:
\installsystemnamespace{recursestepwise}
\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
{\global\advance\outerrecurse \plusone
- \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}%
- \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
\csname\??recursestepwise
% we need the x in order to avoid the \relax that tex adds
\ifnum#3>\zerocount
@@ -3860,8 +4466,8 @@
%
% \def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
% {\global\advance\outerrecurse \plusone
-% \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}%
-% \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel
+% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}%
+% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel
% \normalexpanded
% {\ifnum#3>\zerocount
% \ifnum#2<#1
@@ -3936,10 +4542,10 @@
\unexpanded\def\doloopoverlist#1#2%
{\global\advance\outerrecurse\plusone
- \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname##1{\edef\recursestring{##1}#2}%
- \expandafter\glet\csname\??recurseindex\recursedepth\endcsname\recursestring
- \normalexpanded{\processcommalist[#1]{\expandafter\noexpand\csname\??recurseaction\recursedepth\endcsname}}%
- \expandafter\let\expandafter\recursestring\csname\??recurseindex\recursedepth\endcsname
+ \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1{\edef\recursestring{##1}#2}%
+ \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recursestring
+ \normalexpanded{\processcommalist[#1]{\expandafter\noexpand\csname\??recurseaction\the\outerrecurse\endcsname}}%
+ \expandafter\let\expandafter\recursestring\csname\??recurseindex\the\outerrecurse\endcsname
\global\advance\outerrecurse\minusone}
%D \macros
@@ -4113,14 +4719,22 @@
\def\syst_helpers_check_if_assignment_else#1=#2#3\_e_o_p_{\if#2@}%
-\unexpanded\def\doifelseassignment#1% expandable
+\unexpanded\def\doifelseassignment#1%
{\expandafter\syst_helpers_check_if_assignment_else\detokenize{#1}=@@\_e_o_p_
\expandafter\secondoftwoarguments
\else
\expandafter\firstoftwoarguments
\fi}
-\let\doifassignmentelse\doifelseassignment
+\unexpanded\def\doifelseassignmentcs#1#2#3%
+ {\expandafter\syst_helpers_check_if_assignment_else\detokenize{#1}=@@\_e_o_p_
+ \expandafter#3%
+ \else
+ \expandafter#2%
+ \fi}
+
+\let\doifassignmentelse \doifelseassignment
+\let\doifassignmentelsecs\doifelseassignmentcs
\newif\ifassignment
@@ -4415,16 +5029,14 @@
%D \def\doezomaarwat#1{....#1....}
%D \stoptyping
%D
-%D A disadvantage of this approach is that the tokens that
-%D form \type{#1} are fixed the the moment the argument is read
-%D in. Normally this is no problem, but for instance verbatim
-%D environments adapt the \CATCODES\ of characters and therefore
+%D A disadvantage of this approach is that the tokens that form \type{#1} are fixed
+%D the the moment the argument is read in. Normally this is no problem, but for
+%D instance verbatim environments adapt the \CATCODES\ of characters and therefore
%D are not always happy with already fixed tokens.
%D
-%D Another problem arises when the argument is grouped not by
-%D \type{{}} but by \type{\bgroup} and \type{\egroup}. Such an
-%D argument fails, because the \type{\bgroup} is een as the
-%D argument (which is quite normal).
+%D Another problem arises when the argument is grouped not by \type {{}} but by
+%D \type {\bgroup} and \type {\egroup}. Such an argument fails, because the \type
+%D {\bgroup} is een as the argument (which is quite normal).
%D
%D The next macro offers a solution for both unwanted
%D situations:
@@ -4454,9 +5066,8 @@
%D .......... \rightword{the right way}
%D \stoptyping
%D
-%D Here \TEX\ typesets \type{\bf the right way} unbreakable
-%D at the end of the line. The solution mentioned before does
-%D not work here. We also handle
+%D Here \TEX\ typesets \type {\bf the right way} unbreakable at the end of the line.
+%D The solution mentioned before does not work here. We also handle
%D
%D \starttyping
%D to be \bold{bold} or not, that's the question
@@ -4485,80 +5096,150 @@
% \afterassignment\m_syst_helpers_handle_group_before
% \let\next=}
-\unexpanded\def\syst_helpers_handle_group_normal#1#2%
+% \unexpanded\def\syst_helpers_handle_group_normal#1#2%
+% {\bgroup
+% \def\m_syst_helpers_handle_group_before{#1}%
+% \def\m_syst_helpers_handle_group_after {#2}%
+% \afterassignment\m_syst_helpers_handle_group_normal_before
+% \let\next=}
+%
+% \def\m_syst_helpers_handle_group_normal_before
+% {\bgroup
+% \m_syst_helpers_handle_group_before
+% \bgroup
+% \aftergroup\m_syst_helpers_handle_group_normal_after}
+%
+% \def\m_syst_helpers_handle_group_normal_after
+% {\m_syst_helpers_handle_group_after
+% \egroup
+% \egroup}
+%
+% \unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference)
+% {\bgroup
+% \def\m_syst_helpers_handle_group_before{#1}%
+% \def\m_syst_helpers_handle_group_after {#2}%
+% \afterassignment\m_syst_helpers_handle_group_simple_before
+% \let\next=}
+%
+% \def\m_syst_helpers_handle_group_simple_before
+% {\bgroup
+% \aftergroup\m_syst_helpers_handle_group_simple_after
+% \m_syst_helpers_handle_group_before}
+%
+% \def\m_syst_helpers_handle_group_simple_after
+% {\m_syst_helpers_handle_group_after
+% \egroup}%
+%
+% \unexpanded\def\syst_helpers_handle_group_pickup#1#2#3% no inner group (so no kerning interference)
+% {\bgroup
+% \def\m_syst_helpers_handle_group_before{#1}%
+% \def\m_syst_helpers_handle_group_after {#2\egroup#3}%
+% \afterassignment\m_syst_helpers_handle_group_pickup_before
+% \let\next=}
+%
+% \def\m_syst_helpers_handle_group_pickup_before
+% {\bgroup
+% \aftergroup\m_syst_helpers_handle_group_after
+% \m_syst_helpers_handle_group_before}
+%
+% \unexpanded\def\syst_helpers_handle_group_nop
+% {\ifnum\currentgrouptype=\semisimplegroupcode
+% \expandafter\syst_helpers_handle_group_nop_a
+% \else
+% \expandafter\syst_helpers_handle_group_nop_b
+% \fi}
+%
+% \def\syst_helpers_handle_group_nop_a#1#2%
+% {\def\m_syst_helpers_handle_group_after{#2\endgroup}%
+% \begingroup
+% \aftergroup\m_syst_helpers_handle_group_after
+% #1}
+%
+% \def\syst_helpers_handle_group_nop_b#1#2%
+% {\def\m_syst_helpers_handle_group_after{#2\egroup}%
+% \bgroup
+% \aftergroup\m_syst_helpers_handle_group_after
+% #1}
+
+\unexpanded\def\syst_helpers_handle_group_nop
+ {\ifnum\currentgrouptype=\semisimplegroupcode
+ \expandafter\syst_helpers_handle_group_nop_a
+ \else
+ \expandafter\syst_helpers_handle_group_nop_b
+ \fi}
+
+\def\syst_helpers_handle_group_nop_a
+ {\begingroup
+ \aftergroup\m_syst_helpers_handle_group_a
+ \aftergroup\endgroup
+ \m_syst_helpers_handle_group_b}
+
+\def\syst_helpers_handle_group_nop_b
+ {\bgroup
+ \aftergroup\m_syst_helpers_handle_group_a
+ \aftergroup\egroup
+ \m_syst_helpers_handle_group_b}
+
+\unexpanded\def\syst_helpers_handle_group_normal
{\bgroup
- \def\m_syst_helpers_handle_group_before{#1}%
- \def\m_syst_helpers_handle_group_after {#2}%
\afterassignment\m_syst_helpers_handle_group_normal_before
\let\next=}
\def\m_syst_helpers_handle_group_normal_before
{\bgroup
- \m_syst_helpers_handle_group_before
+ \m_syst_helpers_handle_group_b
\bgroup
- \aftergroup\m_syst_helpers_handle_group_normal_after}
-
-\def\m_syst_helpers_handle_group_normal_after
- {\m_syst_helpers_handle_group_after
- \egroup
- \egroup}
-
-% keep:
-%
-% \unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference)
-% {\bgroup
-% %def\m_syst_helpers_handle_group_before{\bgroup#1\aftergroup\m_syst_helpers_handle_group_after}% interferes
-% \def\m_syst_helpers_handle_group_before{\bgroup\aftergroup\m_syst_helpers_handle_group_after#1}%
-% \def\m_syst_helpers_handle_group_after {#2\egroup}%
-% \afterassignment\m_syst_helpers_handle_group_before
-% \let\next=}
+ \aftergroup\m_syst_helpers_handle_group_a
+ \aftergroup\egroup
+ \aftergroup\egroup}
-\unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference)
+\unexpanded\def\syst_helpers_handle_group_simple% no inner group (so no kerning interference)
{\bgroup
- \def\m_syst_helpers_handle_group_before{#1}%
- \def\m_syst_helpers_handle_group_after {#2}%
\afterassignment\m_syst_helpers_handle_group_simple_before
\let\next=}
\def\m_syst_helpers_handle_group_simple_before
{\bgroup
\aftergroup\m_syst_helpers_handle_group_simple_after
- \m_syst_helpers_handle_group_before}
+ \m_syst_helpers_handle_group_b}
\def\m_syst_helpers_handle_group_simple_after
- {\m_syst_helpers_handle_group_after
+ {\m_syst_helpers_handle_group_a
\egroup}%
-\unexpanded\def\syst_helpers_handle_group_pickup#1#2#3% no inner group (so no kerning interference)
+\unexpanded\def\syst_helpers_handle_group_pickup% no inner group (so no kerning interference)
{\bgroup
- \def\m_syst_helpers_handle_group_before{#1}%
- \def\m_syst_helpers_handle_group_after {#2\egroup#3}%
\afterassignment\m_syst_helpers_handle_group_pickup_before
\let\next=}
\def\m_syst_helpers_handle_group_pickup_before
{\bgroup
- \aftergroup\m_syst_helpers_handle_group_after
- \m_syst_helpers_handle_group_before}
+ \aftergroup\m_syst_helpers_handle_group_a
+ \aftergroup\egroup
+ \aftergroup\m_syst_helpers_handle_group_p
+ \m_syst_helpers_handle_group_b}
-\unexpanded\def\syst_helpers_handle_group_nop
+\unexpanded\def\syst_helpers_handle_group_nop_x
{\ifnum\currentgrouptype=\semisimplegroupcode
- \expandafter\syst_helpers_handle_group_nop_a
+ \begingroup
+ \aftergroup\endgroup
\else
- \expandafter\syst_helpers_handle_group_nop_b
- \fi}
+ \bgroup
+ \aftergroup\egroup
+ \fi
+ \m_syst_helpers_handle_group_b}
-\def\syst_helpers_handle_group_nop_a#1#2%
- {\def\m_syst_helpers_handle_group_after{#2\endgroup}%
- \begingroup
- \aftergroup\m_syst_helpers_handle_group_after
- #1}
+\unexpanded\def\syst_helpers_handle_group_normal_x
+ {\bgroup
+ \afterassignment\m_syst_helpers_handle_group_normal_before_x
+ \let\next=}
-\def\syst_helpers_handle_group_nop_b#1#2%
- {\def\m_syst_helpers_handle_group_after{#2\egroup}%
+\def\m_syst_helpers_handle_group_normal_before_x
+ {\bgroup
+ \m_syst_helpers_handle_group_b
\bgroup
- \aftergroup\m_syst_helpers_handle_group_after
- #1}
+ \aftergroup\egroup
+ \aftergroup\egroup}
%D I considered it a nuisance that
%D
@@ -4567,25 +5248,61 @@
%D {as grass}
%D \stoptyping
%D
-%D was not interpreted as one would expect. This is due to the
-%D fact that \type{\futurelet} obeys blank spaces, and a
-%D line||ending token is treated as a blank space. So the final
-%D implementation became:
+%D was not interpreted as one would expect. This is due to the fact that \type
+%D {\futurelet} obeys blank spaces, and a line||ending token is treated as a blank
+%D space. So the final implementation became:
+
+% \unexpanded\def\groupedcommand#1#2%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+%
+% \unexpanded\def\groupedcommandcs#1#2%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+%
+% \unexpanded\def\triggergroupedcommand#1%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{}}{\syst_helpers_handle_group_nop{#1}{}}}
+%
+% \unexpanded\def\triggergroupedcommandcs#1%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{}}{\syst_helpers_handle_group_nop{#1}{}}}
+%
+% \unexpanded\def\simplegroupedcommand#1#2%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_simple{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+%
+% \unexpanded\def\pickupgroupedcommand#1#2#3%
+% {\doifelsenextbgroup{\syst_helpers_handle_group_pickup{#1}{#2}{#3}}{\syst_helpers_handle_group_nop{#1}{#2}}}
\unexpanded\def\groupedcommand#1#2%
- {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+ {\def\m_syst_helpers_handle_group_b{#1}%
+ \def\m_syst_helpers_handle_group_a{#2}%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop}
+
+\unexpanded\def\groupedcommandcs#1#2%
+ {\let\m_syst_helpers_handle_group_b#1%
+ \let\m_syst_helpers_handle_group_a#2%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop}
\unexpanded\def\simplegroupedcommand#1#2%
- {\doifelsenextbgroup{\syst_helpers_handle_group_simple{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+ {\def\m_syst_helpers_handle_group_b{#1}%
+ \def\m_syst_helpers_handle_group_a{#2}%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_simple\syst_helpers_handle_group_nop}
\unexpanded\def\pickupgroupedcommand#1#2#3%
- {\doifelsenextbgroup{\syst_helpers_handle_group_pickup{#1}{#2}{#3}}{\syst_helpers_handle_group_nop{#1}{#2}}}
+ {\def\m_syst_helpers_handle_group_b{#1}%
+ \def\m_syst_helpers_handle_group_a{#2}%
+ \def\m_syst_helpers_handle_group_p{#2}%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_pickup\syst_helpers_handle_group_nop}
-%D Users should be aware of the fact that grouping can
-%D interfere with ones paragraph settings that are executed
-%D after the paragraph is closed. One should therefore
-%D explictly close the paragraph with \type{\par}, else the
-%D settings will be forgotten and not applied. So it's:
+\unexpanded\def\triggergroupedcommand#1%
+ {\def\m_syst_helpers_handle_group_b{#1}%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x}
+
+\unexpanded\def\triggergroupedcommandcs#1%
+ {\let\m_syst_helpers_handle_group_b#1%
+ \doifelsenextbgroupcs\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x}
+
+%D Users should be aware of the fact that grouping can interfere with ones paragraph
+%D settings that are executed after the paragraph is closed. One should therefore
+%D explictly close the paragraph with \type {\par}, else the settings will be
+%D forgotten and not applied. So it's:
%D
%D \starttyping
%D \def\BoldRaggedCenter%
@@ -5392,7 +6109,7 @@
\fi}
\unexpanded\def\globalprocesscommalist[#1]#2%
- {\global\let\m_syst_helpers_comma_list_command_global#2%
+ {\glet\m_syst_helpers_comma_list_command_global#2%
\expandafter\syst_helpers_comma_list_command_global_step#1,],}
%D \macros
@@ -5454,9 +6171,9 @@
\unexpanded\def\swapcounts#1#2{\c_syst_helpers_swapped #1\relax#1#2\relax#2\c_syst_helpers_swapped}
\unexpanded\def\swapmacros#1#2{\let\m_syst_helpers_swapped#1\let #1#2\let #2\m_syst_helpers_swapped}
-\unexpanded\def\globalswapdimens#1#2{\d_syst_helpers_swapped #1\global #1#2\global #2\d_syst_helpers_swapped}
-\unexpanded\def\globalswapcounts#1#2{\c_syst_helpers_swapped #1\global #1#2\global #2\c_syst_helpers_swapped}
-\unexpanded\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\global\let#1#2\global\let#2\m_syst_helpers_swapped}
+\unexpanded\def\globalswapdimens#1#2{\d_syst_helpers_swapped #1\global#1#2\global#2\d_syst_helpers_swapped}
+\unexpanded\def\globalswapcounts#1#2{\c_syst_helpers_swapped #1\global#1#2\global#2\c_syst_helpers_swapped}
+\unexpanded\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\glet #1#2\glet #2\m_syst_helpers_swapped}
%D \macros
%D {pushmacro,popmacro}
@@ -5481,11 +6198,11 @@
% \expandafter\newcount\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname
% \fi
% \global\advance\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \plusone
-% \global\expandafter\let\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1}
+% \expandafter\glet\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1}
%
% \unexpanded\def\globalpopmacro#1%
% {\xdef\m_syst_helpers_push_macro{\string#1}%
-% \global\expandafter\let\expandafter#1\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname
+% \expandafter\glet\expandafter#1\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname
% \global\advance\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \minusone}
%
% \unexpanded\def\localpushmacro#1% this one can be used to push a value over an \egroup
@@ -5494,7 +6211,7 @@
% \expandafter\newcount\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname
% \fi
% \global\advance\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname \plusone
-% \global\expandafter\let\csname\the\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1}
+% \expandafter\glet\csname\the\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1}
%
% \unexpanded\def\localpopmacro#1%
% {\xdef\m_syst_helpers_push_macro{\string#1}%
@@ -5505,6 +6222,8 @@
% \let\popmacro \localpopmacro
%
% slightly faster but more important: less tracing
+%
+% possible optimization \installmacrostack\foo: \syst_push_foo \syst_pop_foo
\let\m_syst_helpers_push_macro\empty
@@ -5525,7 +6244,7 @@
\else
\syst_helpers_push_macro_new_global
\fi
- \global\expandafter\let\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1}
+ \expandafter\glet\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1}
\unexpanded\def\localpushmacro#1% this one can be used to push a value over an \egroup
{\xdef\m_syst_helpers_push_macro{\csstring#1}%
@@ -5534,13 +6253,13 @@
\else
\syst_helpers_push_macro_new_local
\fi
- \global\expandafter\let\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1}
+ \expandafter\glet\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1}
\unexpanded\def\globalpopmacro#1%
{\xdef\m_syst_helpers_push_macro{\csstring#1}%
\c_syst_helpers_pop_count\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname
\global\advance\lastnamedcs \minusone
- \global\expandafter\let\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname}
+ \expandafter\glet\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname}
\unexpanded\def\localpopmacro#1%
{\xdef\m_syst_helpers_push_macro{\csstring#1}%
@@ -6060,7 +6779,7 @@
\unexpanded\def\processassignlist#1[#2]#3%
{\def\syst_helpers_process_assign_list_assign[##1=##2=##3]%
- {\doifnot{##3}\relax{#3{##1}}}%
+ {\doif{##3}\relax{#3{##1}}}%
\def\syst_helpers_process_assign_list_step##1%
{\syst_helpers_process_assign_list_assign[##1==\relax]}%
\processcommalist[#2]\syst_helpers_process_assign_list_step}
@@ -6996,14 +7715,6 @@
{\unprotect
\syst_helpers_unprotected}
-% awaiting the definitive implementation
-
-% \ifdefined\resettimer \else
-% \let\resettimer \relax
-% \newcount\elapsedtime
-% \fi
-% \def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax}
-
\let\resettimer \clf_resettimer
\let\elapsedtime \clf_elapsedtime
\let\elapsedseconds \elapsedtime
@@ -7172,6 +7883,12 @@
\unexpanded\def\signalcharacter{\char\zerocount} % \zwj
+% \unexpanded\def\signalcharacter
+% {\scratchcounter\normallanguage
+% \normallanguage\zerocount
+% \char\zerocount
+% \normallanguage\scratchcounter}
+
%D A few secial variants of commands defined here. Some more will be moved here (e.g.
%D from table modules.
@@ -7486,3 +8203,23 @@
% \edef\tempstring{\the#1}%
% \tx\ttbf\string#1: \tttf\meaning\tempstring
% \endgroup}
+
+%D Not needed now, but more efficient that expanding
+%
+% \chardef\_E_O_T_0
+%
+% \unexpanded\def\doifelsetokens#1%
+% {\dodoifelsetokens#1\_E_O_T_\_e_o_t_}
+%
+% \def\dodoifelsetokens#1#2\_e_o_t_
+% {\ifx#1\_E_O_T_
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\firstoftwoarguments
+% \fi}
+%
+% \def\emptytokscondition#1%
+% {\doemptytokscondition#1\_E_O_T_\_e_o_t_}
+%
+% \def\doemptytokscondition#1#2\_e_o_t_
+% {\ifx#1\_E_O_T_}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.lua b/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.lua
new file mode 100644
index 00000000000..67595d04381
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.lua
@@ -0,0 +1,8 @@
+if not modules then modules = { } end modules ['syst-cmp'] = {
+ version = 1.001,
+ comment = "companion to syst-cmp.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.mkiv
new file mode 100644
index 00000000000..a5ebdd8e33d
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-cmp.mkiv
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=syst-cmp,
+%D version=2018.12.05,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Compatibility,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Some code that has been laying around for generic compatibility is (and will be)
+%D moved here, for instance because tikz needs it. At some point I will make an
+%D indirect interface for generic code (if needed).
+
+\registerctxluafile{syst-cmp}{}
+
+\unprotect
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkiv
index 4b5cc616b46..7ce48c79f66 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkiv
@@ -19,116 +19,124 @@
%D Characters can have special states, that can be triggered by setting their
%D category coded. Some are preset, others are to be set as soon as possible,
%D otherwise we cannot define any useful macros.
-
-%catcode`\^^@ = 9 % ascii null is ignored
-%catcode`\\ = 0 % backslash is TeX escape character
-
-\catcode`\{ = 1 % left brace is begin-group character
-\catcode`\} = 2 % right brace is end-group character
-\catcode`\$ = 3 % dollar sign is math shift
-\catcode`\& = 4 % ampersand is alignment tab
-\catcode`\# = 6 % hash mark is macro parameter character
-\catcode`\^ = 7 % circumflex and uparrow are for superscripts
-\catcode`\_ = 8 % underline and downarrow are for subscripts
-\catcode`\^^I = 10 % ascii tab is a blank space
-
-%catcode`\^^M = 5 % ascii return is end-line
-%catcode`\% = 14 % percent sign is comment character
-%catcode`\ = 10 % ascii space is blank space
-%catcode`\^^? = 15 % ascii delete is invalid
-
-\catcode`\~ = 13 % tilde is active
-\catcode`\^^L = 13 % ascii form-feed
-
-%catcode`\A = 11
-%.......
-%catcode`\Z = 11
-
-%catcode`\a = 11
-%.......
-%catcode`\z = 11
-
-\def ^^L{\par}
-\def\^^M{\ } % control = control
-\def\^^I{\ } % same for
-
-%D In \CONTEXT, we simply ignore end||of||file tokens:
-
-\catcode`\^^Z=9
-
-%D It makes sense to know what engine we're running so let's try to deduce it.
-
-\chardef\unknownengine = 0
-\chardef\pdftexengine = 1
-\chardef\xetexengine = 2
-\chardef\luatexengine = 3
-
-\chardef\statuswrite = 128
-
-\ifx\directlua\undefined
- \ifx\XeTeXversion\undefined
- \ifx\pdftexversion\undefined
- \let\texengine\unknownengine
- \else
- \let\texengine\pdftexengine
- \fi
- \else
- \let\texengine\xetexengine
- \fi
-\else
- \let\texengine\luatexengine
-\fi
-
-\ifnum\texengine=\luatexengine
- % for historic reasons we keep some mkii code around
-\else
- \immediate\write\statuswrite{>>>}
- \immediate\write\statuswrite{>>> only luatex is supported}
- \immediate\write\statuswrite{>>>}
- \let\dump\relax
- \expandafter\end
-\fi
+%D
+%D First we define a bunch of constants. Normally we would \type {\setconstant}
+%D but we're prestine and have no macros defined yet. Abstraction also makes it
+%D possible to avoid the \type {^^} in the input.
+
+\chardef\escapecatcode 0
+\chardef\begingroupcatcode 1
+\chardef\endgroupcatcode 2
+\chardef\mathshiftcatcode 3
+\chardef\alignmentcatcode 4
+\chardef\endoflinecatcode 5
+\chardef\parametercatcode 6
+\chardef\superscriptcatcode 7
+\chardef\subscriptcatcode 8
+\chardef\ignorecatcode 9
+\chardef\spacecatcode 10
+\chardef\lettercatcode 11
+\chardef\othercatcode 12 % finally obsolete: \let\other \othercatcode
+\chardef\activecatcode 13 % finally obsolete: \let\active\activecatcode
+\chardef\commentcatcode 14
+\chardef\invalidcatcode 15
+
+%chardef\zeroasciicode 0
+\chardef\tabasciicode 9
+\chardef\newlineasciicode 10 % don't confuse this one with \endoflineasciicode
+\chardef\formfeedasciicode 12
+\chardef\endoflineasciicode 13 % somewhat messy but this can be the active \par
+\chardef\endoffileasciicode 26
+\chardef\spaceasciicode 32
+\chardef\exclamationmarkasciicode 33 % ! used in namespace protection
+\chardef\doublequoteasciicode 34 % "
+\chardef\hashasciicode 35
+\chardef\dollarasciicode 36
+\chardef\commentasciicode 37
+\chardef\ampersandasciicode 38
+\chardef\singlequoteasciicode 39 % '
+\chardef\primeasciicode 39 % '
+\chardef\leftparentasciicode 40
+\chardef\rightparentasciicode 41
+\chardef\hyphenasciicode 45
+\chardef\forwardslashasciicode 47 % /
+\chardef\colonasciicode 58
+\chardef\lessthanasciicode 60 % < used as alternative verbatim {
+\chardef\morethanasciicode 62 % > used as alternative verbatim }
+\chardef\questionmarkasciicode 63 % ? used in namespace protection
+\chardef\atsignasciicode 64 % @ used in namespace protection
+\chardef\backslashasciicode 92 % `\\
+\chardef\circumflexasciicode 94
+\chardef\underscoreasciicode 95
+\chardef\leftbraceasciicode 123 % `\{
+\chardef\barasciicode 124 % `\|
+\chardef\rightbraceasciicode 125 % `\}
+\chardef\tildeasciicode 126 % `\~
+\chardef\delasciicode 127
+
+%catcode\zeroasciicode \ignorecatcode % `\^^@ ascii null is ignored
+\catcode\tabasciicode \spacecatcode % `\^^I ascii tab is a blank space
+\catcode\formfeedasciicode \activecatcode % `\^^L ascii form-feed (active, set later)
+%catcode\endoflineasciicode \endoflinecatcode % `\^^M ascii return is end-line
+\catcode\endoffileasciicode \ignorecatcode % `\^^Z endoffile (ignored in ConTeXt)
+%catcode\spaceasciicode \spacecatcode % `\ ascii space is blank space
+\catcode\hashasciicode \parametercatcode % `\# hash mark is macro parameter character
+\catcode\dollarasciicode \mathshiftcatcode % `\$ dollar sign is math shift
+%catcode\commentasciicode \commentcatcode % `\% percent sign is comment character
+\catcode\ampersandasciicode \alignmentcatcode % `\& ampersand is alignment tab
+%catcode\backslashasciicode \escapecatcode % `\\ backslash is TeX escape character
+\catcode\circumflexasciicode \superscriptcatcode % `\^ circumflex and uparrow are for superscripts
+\catcode\underscoreasciicode \subscriptcatcode % `\_ underline and downarrow are for subscripts
+\catcode\leftbraceasciicode \begingroupcatcode % `\{ left brace is begin-group character
+\catcode\rightbraceasciicode \endgroupcatcode % `\} right brace is end-group character
+\catcode\tildeasciicode \activecatcode % `\~ tilde is active
+%catcode\delasciicode \invalidcatcode % `\^^? ascii delete is invalid
+
+\chardef\statuswrite 128
%D Initialization of primitives.
-\directlua 0 { % this info is stored in the format
- lua.name[0] = "main ctx instance"
+\directlua {
+ local baseprimitives = tex.extraprimitives("core","tex")
+ local moreprimitives = tex.extraprimitives("etex","luatex")
- local coreprimitives = tex.extraprimitives("core")
- local texprimitives = tex.extraprimitives("tex")
- local etexprimitives = tex.extraprimitives("etex")
- local luatexprimitives = tex.extraprimitives("luatex")
+ tex.enableprimitives("",moreprimitives)
- tex.enableprimitives("",etexprimitives)
- tex.enableprimitives("",luatexprimitives)
+ tex.enableprimitives("normal",baseprimitives)
+ tex.enableprimitives("normal",moreprimitives)
- tex.enableprimitives("normal",coreprimitives)
- tex.enableprimitives("normal",texprimitives)
- tex.enableprimitives("normal",etexprimitives)
- tex.enableprimitives("normal",luatexprimitives)
+ function tex.enableprimitives() end
}
-%D \ETEX\ has a not so handy way of telling you the version number, i.e. the revision
-%D number has a period in it:
+\def\space{ }
+\def\empty{}
+
+\letcharcode \formfeedasciicode \par % \def ^^L{\par} formfeed
+\letcharcode \tildeasciicode \ % tilde
+\letcharcode \spaceasciicode \space % space
-\def\gobbleoneargument#1{} % will be defined later on anyway
+\expandafter\def\csname\Uchar\tabasciicode \endcsname {\ } % \def\^^I{\ } tab
+\expandafter\def\csname\Uchar\formfeedasciicode \endcsname {\par} % \def\^^L{\par} formfeed
+\expandafter\def\csname\Uchar\endoflineasciicode\endcsname {\ } % \def\^^M{\ } return
-\mathchardef\etexversion = \numexpr\eTeXversion*100+\expandafter\gobbleoneargument\eTeXrevision\relax
+%D For now:
+
+\def\gobbleoneargument#1{} % will be defined later on anyway
%D First we define a simplified version of the \CONTEXT\ protection mechanism.
%D Later we will implement a better variant.
\def\unprotect
{\edef\protect
- {\catcode`@=\the\catcode`@\relax
- \catcode`?=\the\catcode`?\relax
- \catcode`!=\the\catcode`!\relax
- \catcode`_=\the\catcode`_\relax
+ {\catcode\atsignasciicode \the\catcode\atsignasciicode \relax
+ \catcode\exclamationmarkasciicode\the\catcode\exclamationmarkasciicode\relax
+ \catcode\questionmarkasciicode \the\catcode\questionmarkasciicode \relax
+ \catcode\underscoreasciicode \the\catcode\underscoreasciicode \relax
\let\protect\relax}%
- \catcode`@=11
- \catcode`?=11
- \catcode`!=11
- \catcode`_=11 }
+ \catcode\atsignasciicode \lettercatcode
+ \catcode\exclamationmarkasciicode\lettercatcode
+ \catcode\questionmarkasciicode \lettercatcode
+ \catcode\underscoreasciicode \lettercatcode}
\let\protect\relax
@@ -169,13 +177,13 @@
\countdef \c_syst_max_allocated_read = 55 \c_syst_max_allocated_read = 16
\countdef \c_syst_min_allocated_language = 56 \c_syst_min_allocated_language = 0
\countdef \c_syst_max_allocated_language = 57 \c_syst_max_allocated_language = 255
-\countdef \c_syst_max_allocated_insert = 58 \c_syst_max_allocated_insert = 254
-\countdef \c_syst_min_allocated_insert = 59 \c_syst_min_allocated_insert = 128
+\countdef \c_syst_min_allocated_insert = 58 \c_syst_min_allocated_insert = 128
+\countdef \c_syst_max_allocated_insert = 59 \c_syst_max_allocated_insert = 254
\countdef \c_syst_min_allocated_family = 60 \c_syst_min_allocated_family = 128
\countdef \c_syst_max_allocated_family = 61 \c_syst_max_allocated_family = 255
-\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 127-1023 : private
-\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0 % luatex >= 0.82
-\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127 % luatex >= 0.82
+\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 0-1023 : private
+\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0
+\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127
\countdef \c_syst_last_allocated_count = 32 \c_syst_last_allocated_count = \c_syst_min_allocated_register
\countdef \c_syst_last_allocated_dimen = 33 \c_syst_last_allocated_dimen = \c_syst_min_allocated_register
@@ -212,10 +220,10 @@
% A few traditional allocations (these might go):
-\countdef \count@ = 255 % hm, used in \newif .. todo: replace it there
-\dimendef \dimen@ = 0
-\dimendef \dimen@i = 1 % global only
-\dimendef \dimen@ii = 2
+\countdef \count@ 255 % hm, used in \newif .. todo: replace it there
+\dimendef \dimen@ 0
+\dimendef \dimen@i 1 % global only
+\dimendef \dimen@ii 2
%D So, effectively we start allocating from 256 and upwards. The inserts sit in the
%D range 128 upto 254. Page numbers use the counters 0 upto 9 and the pagebox is
@@ -258,8 +266,7 @@
% %D The next definitions are really needed (in \CONTEXT):
-%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
-\newlinechar=10 \edef\outputnewlinechar{^^J}
+\newlinechar\newlineasciicode \edef\outputnewlinechar{\Uchar\newlineasciicode} % {^^J}
%D One reason to start high with allocation is that it permits us to allocate
%D consecutive ranges more easily, for instance if for \MPLIB\ we want to allocate a
@@ -268,7 +275,8 @@
%D as all engines now provide many registers we removed all traces.
\ifdefined\writestatus \else
- \normalprotected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}}
+ %\normalprotected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}}
+ \normalprotected\def\writestatus#1#2{\message{#1: #2}}
\fi
\def\syst_basics_allocate_yes#1#2#3#4#5% last class method max name
@@ -304,6 +312,7 @@
%D 128-1023 are private and should not be touched.
\let\attributeunsetvalue\c_syst_min_counter_value % used to be \minusone
+
\normalprotected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_register}
%D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
@@ -344,6 +353,10 @@
\newtoks \scratchtoksfour \newtoks \scratchtoksfive \newtoks \scratchtokssix
\newbox \scratchboxfour \newbox \scratchboxfive \newbox \scratchboxsix
+\newcount\globalscratchcounterone
+\newcount\globalscratchcountertwo
+\newcount\globalscratchcounterthree
+
%D \macros
%D {tempstring}
@@ -395,19 +408,19 @@
%D More allocations:
-\newskip \zeroskip \zeroskip = 0pt plus 0pt minus 0pt
-\newdimen \zeropoint \zeropoint = 0pt
-\newdimen \onepoint \onepoint = 1pt
-\newdimen \halfapoint \halfapoint = 0.5pt
-\newdimen \maxdimen \maxdimen = 16383.99999pt
-\newcount \maxcount \maxcount = 2147483647
-\newdimen \onebasepoint \onebasepoint = 1bp
-\newdimen \scaledpoint \scaledpoint = 1sp
-\newdimen \thousandpoint \thousandpoint = 1000pt
-\newmuskip\zeromuskip \zeromuskip = 0mu
-\newmuskip\onemuskip \onemuskip = 1mu
+\newskip \zeroskip \zeroskip 0pt plus 0pt minus 0pt
+\newdimen \zeropoint \zeropoint 0pt
+\newdimen \onepoint \onepoint 1pt
+\newdimen \halfapoint \halfapoint 0.5pt
+\newdimen \maxdimen \maxdimen 16383.99999pt
+\newcount \maxcount \maxcount 2147483647
+\newdimen \onebasepoint \onebasepoint 1bp
+\newdimen \scaledpoint \scaledpoint 1sp
+\newdimen \thousandpoint \thousandpoint 1000pt
+\newmuskip\zeromuskip \zeromuskip 0mu
+\newmuskip\onemuskip \onemuskip 1mu
-\newmuskip\muquad \muquad = 18mu
+\newmuskip\muquad \muquad 18mu
\let\points \onepoint
\let\halfpoint\halfapoint
@@ -416,32 +429,35 @@
%D And even more: (todo: countdefs 60+)
-%newcount \minusone \minusone = -1
-\newcount \minustwo \minustwo = -2
-%chardef \zerocount = 0
-%chardef \plusone = 1
-\chardef \plustwo = 2
-\chardef \plusthree = 3
-\chardef \plusfour = 4
-\chardef \plusfive = 5
-\chardef \plussix = 6
-\chardef \plusseven = 7
-\chardef \pluseight = 8
-\chardef \plusnine = 9
-\chardef \plusten = 10
-\chardef \plussixteen = 16
-\chardef \plushundred = 100
-\chardef \plustwohundred = 200
-\chardef \pluscxxvii = 127
-\chardef \pluscxxviii = 128
-\chardef \pluscclv = 255
-\chardef \pluscclvi = 256
-\chardef \plusthousand = 1000
-\chardef \plustenthousand = 10000
-\chardef \plustwentythousand = 20000
-\chardef \medcard = 32768
-\chardef \maxcard = 65536 % pdftex has less mathchars
-\chardef \maxcardminusone = 65535
+%newcount\minusone \minusone -1
+\newcount\minustwo \minustwo -2
+%chardef \zerocount 0
+%chardef \plusone 1
+\chardef \plustwo 2
+\chardef \plusthree 3
+\chardef \plusfour 4
+\chardef \plusfive 5
+\chardef \plussix 6
+\chardef \plusseven 7
+\chardef \pluseight 8
+\chardef \plusnine 9
+\chardef \plusten 10
+\chardef \plussixteen 16
+\chardef \plusfifty 50
+\chardef \plushundred 100
+\chardef \plusonehundred 100
+\chardef \plustwohundred 200
+\chardef \plusfivehundred 500
+\chardef \pluscxxvii 127
+\chardef \pluscxxviii 128
+\chardef \pluscclv 255
+\chardef \pluscclvi 256
+\chardef \plusthousand 1000
+\chardef \plustenthousand 10000
+\chardef \plustwentythousand 20000
+\chardef \medcard 32768
+\chardef \maxcard 65536 % pdftex has less mathchars
+\chardef \maxcardminusone 65535
%D \macros
%D {doubleexpandafter,tripleexpandafter,expanded,startexpanded}
@@ -462,8 +478,8 @@
\def\unvoidbox{\unhbox\voidbox}
\def\emptybox {\box \voidbox} % used in initializations so no attributes
-\def\emptyvbox{\normalvbox{}} % no copy as we need to set attributes
-\def\emptyhbox{\normalhbox{}} % no copy as we need to set attributes
+\def\emptyvbox{\normalvpack{}} % no copy as we need to set attributes
+\def\emptyhbox{\normalhpack{}} % no copy as we need to set attributes
\let\leavevmode\unvoidbox % we prefer to use \dontleavehmode
@@ -506,21 +522,47 @@
%D creates \type {\footrue}, \type {\foofalse} to go with \type {\iffoo}.
%D \stopnarrower
-\normalprotected\def\newif#1%
- {\count@\escapechar
- \escapechar\minusone
- \expandafter\expandafter\expandafter\def\@if #1{true}{\let#1\iftrue }%
- \expandafter\expandafter\expandafter\def\@if#1{false}{\let#1\iffalse}%
- \@if#1{false}% the condition starts out false
- \escapechar\count@}
-
-\def\@if#1#2%
- {\csname\expandafter\if@\string#1#2\endcsname}
+% \normalprotected\def\newif#1%
+% {\count@\escapechar
+% \escapechar\minusone
+% \expandafter\expandafter\expandafter\def\new_if #1{true}{\let#1\iftrue }%
+% \expandafter\expandafter\expandafter\def\new_if#1{false}{\let#1\iffalse}%
+% \new_if#1{false}% the condition starts out false
+% \escapechar\count@}
+%
+% \def\new_if#1#2%
+% {\csname\expandafter\if@\string#1#2\endcsname}
+%
+% \bgroup % `if' is required
+% \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
+% \egroup
-\bgroup % `if' is required
+% We use \csstring so there is no need to push/pop escapechar.
+% We use different names so that we get a better error message.
+%
+% \normalprotected\def\newif#1%
+% {\let\new_if_saved\newif
+% \let\newif\new_if_check
+% \expandafter\expandafter\expandafter\def\new_if_cs #1{true}{\let#1\iftrue }%
+% \expandafter\expandafter\expandafter\def\new_if_cs#1{false}{\let#1\iffalse}%
+% \new_if_cs#1{false}%
+% \let\newif\new_if_saved}
+%
+% \normalprotected\def\new_if_cs#1#2%
+% {\csname\expandafter\newif\csstring#1#2\endcsname}
+%
+% We wrap all into one macro:
- \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
+\normalprotected\def\newif#1%
+ {\let\new_if_saved\newif
+ \let\newif\new_if_check
+ \expandafter\def\csname\expandafter\newif\csstring#1true\endcsname {\let#1\iftrue }%
+ \expandafter\def\csname\expandafter\newif\csstring#1false\endcsname{\let#1\iffalse}%
+ \csname\expandafter\newif\csstring#1false\endcsname
+ \let\newif\new_if_saved}
+\bgroup
+ \normalexpanded{\gdef\noexpand\new_if_check\string i\string f{}}
\egroup
%D Let's test this one:
@@ -534,32 +576,11 @@
%D A few shortcuts:
-\normalprotected\def\glet {\global \let }
\normalprotected\def\udef {\normalprotected\def }
\normalprotected\def\ugdef{\normalprotected\gdef}
\normalprotected\def\uedef{\normalprotected\edef}
\normalprotected\def\uxdef{\normalprotected\xdef}
-%D The catcode constants will be redefined in later catcode related modules
-%D but they can be used in the same way.
-
-\chardef\escapecatcode = 0
-\chardef\begingroupcatcode = 1
-\chardef\endgroupcatcode = 2
-\chardef\mathshiftcatcode = 3
-\chardef\alignmentcatcode = 4
-\chardef\endoflinecatcode = 5
-\chardef\parametercatcode = 6
-\chardef\superscriptcatcode = 7
-\chardef\subscriptcatcode = 8
-\chardef\ignorecatcode = 9
-\chardef\spacecatcode = 10
-\chardef\lettercatcode = 11
-\chardef\othercatcode = 12
-\chardef\activecatcode = 13
-\chardef\commentcatcode = 14
-\chardef\invalidcatcode = 15
-
%D For a while we keep the following, as systems like tikz need it. Best
%D not use that one \CONTEXT.
@@ -789,7 +810,8 @@
\normalprotected\def\newmacro #1{\let#1\empty}
\normalprotected\def\setnewmacro#1{\let#1}
-\def\!!plusone{1}
+\def\!!zerocount{0}
+\def\!!plusone {1}
\normalprotected\def\newfraction#1{\let#1\!!plusone}
@@ -872,28 +894,28 @@
\let\endgraf\par
\let\endline\cr
-\def\space{ }
-\def\empty{}
-
\normalprotected\def\null{\hpack{}}
%D The following two might be overloaded later on but some modules need then
%D earlier. These functionality is reflected in the name and will not change.
-\bgroup
- \catcode`\^^M=\activecatcode%
- \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}%
- \global\let^^M\par%
-\egroup
-
-\bgroup
- \gdef\obeyspaces{\catcode`\ \activecatcode}%
- \obeyspaces\global\let =\space%
-\egroup
+% \bgroup
+% \catcode`\^^M=\activecatcode%
+% \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}%
+% \glet^^M\par%
+% \egroup
+%
+% \bgroup
+% \gdef\obeyspaces{\catcode`\ \activecatcode}%
+% \obeyspaces\glet =\space%
+% \egroup
-%D A constant:
+\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\par}
+\def\obeyspaces{\catcode\spaceasciicode \activecatcode\letcharcode\spaceasciicode \space}
-\let\endoflinetoken=^^M
+% %D A constant:
+%
+% \let\endoflinetoken=^^M
%D Also needed might be a simple loop structure and we borrow plain \TEX's one
%D as it is often expected to be present and it is about the fastest you can
@@ -948,6 +970,12 @@
\lineskip = 1pt
\lineskiplimit = 0pt
+%D Sometimes kerns make more sense than glue but we need to be in the
+%D right mode:
+
+\normalprotected\def\vkern{\ifhmode\par \fi\kern}
+\normalprotected\def\hkern{\ifvmode\dontleavehmode\fi\kern}
+
%D Again a few kind-of-extensions the core. These come from plain \TEX\ but
%D are probably not used in \CONTEXT.
@@ -976,116 +1004,47 @@
%D Backend:
-% For the moment we define some \pdf... helpers but this will move to the backend
-% module after which the official interfaces have to be used. This is needed for
-% modules not made by ctx developers.
-
-\normalprotected\def\pdfliteral {\pdfextension literal }
-\normalprotected\def\pdfcolorstack {\pdfextension colorstack }
-\normalprotected\def\pdfsetmatrix {\pdfextension setmatrix }
-\normalprotected\def\pdfsave {\pdfextension save\relax}
-\normalprotected\def\pdfrestore {\pdfextension restore\relax}
-\normalprotected\def\pdfobj {\pdfextension obj }
-\normalprotected\def\pdfrefobj {\pdfextension refobj }
-\normalprotected\def\pdfannot {\pdfextension annot }
-\normalprotected\def\pdfstartlink {\pdfextension startlink }
-\normalprotected\def\pdfendlink {\pdfextension endlink\relax}
-\normalprotected\def\pdfoutline {\pdfextension outline }
-\normalprotected\def\pdfdest {\pdfextension dest }
-\normalprotected\def\pdfthread {\pdfextension thread }
-\normalprotected\def\pdfstartthread {\pdfextension startthread }
-\normalprotected\def\pdfendthread {\pdfextension endthread\relax}
-\normalprotected\def\pdfinfo {\pdfextension info }
-\normalprotected\def\pdfcatalog {\pdfextension catalog }
-\normalprotected\def\pdfnames {\pdfextension names }
-\normalprotected\def\pdfincludechars {\pdfextension includechars }
-\normalprotected\def\pdffontattr {\pdfextension fontattr }
-\normalprotected\def\pdfmapfile {\pdfextension mapfile }
-\normalprotected\def\pdfmapline {\pdfextension mapline }
-\normalprotected\def\pdftrailer {\pdfextension trailer }
-\normalprotected\def\pdfglyphtounicode {\pdfextension glyphtounicode }
-
-% \chardef\pdfnofullbanner = 1
-% \chardef\pdfnofilename = 2
-% \chardef\pdfnopagenumber = 4
-% \chardef\pdfnoinfodict = 8
-% \chardef\pdfnocreator = 16
-% \chardef\pdfnocreationdate = 32
-% \chardef\pdfnomoddate = 64
-% \chardef\pdfnoproducer = 128
-% \chardef\pdfnotrapped = 256
-% \chardef\pdfnoid = 512
-
-\def\pdftexversion {\numexpr\pdffeedback version\relax}
-\def\pdftexrevision {\pdffeedback revision}
-\def\pdflastlink {\numexpr\pdffeedback lastlink\relax}
-\def\pdfretval {\numexpr\pdffeedback retval\relax}
-\def\pdflastobj {\numexpr\pdffeedback lastobj\relax}
-\def\pdflastannot {\numexpr\pdffeedback lastannot\relax}
-\def\pdfxformname {\numexpr\pdffeedback xformname\relax}
-\def\pdfcreationdate {\pdffeedback creationdate}
-\def\pdffontname {\numexpr\pdffeedback fontname\relax}
-\def\pdffontobjnum {\numexpr\pdffeedback fontobjnum\relax}
-\def\pdffontsize {\dimexpr\pdffeedback fontsize\relax}
-\def\pdfpageref {\numexpr\pdffeedback pageref\relax}
-\def\pdfcolorstackinit {\pdffeedback colorstackinit}
-
-\let\pdfxform \saveboxresource
-\let\pdflastxform \lastsavedboxresourceindex
-\let\pdfrefxform \useboxresource
-\let\pdfximage \saveimageresource
-\let\pdflastximage \lastsavedimageresourceindex
-\let\pdflastximagepages \lastsavedimageresourcepages
-\let\pdfrefximage \useimageresource
-\let\pdfsavepos \savepos
-\let\pdflastxpos \lastxpos
-\let\pdflastypos \lastypos
-
-\edef\pdfcompresslevel {\pdfvariable compresslevel} \pdfcompresslevel \plusnine
-\edef\pdfobjcompresslevel {\pdfvariable objcompresslevel} \pdfobjcompresslevel \plusone
-\edef\pdfdecimaldigits {\pdfvariable decimaldigits} \pdfdecimaldigits \plusfive
-\edef\pdfgamma {\pdfvariable gamma} \pdfgamma \plusthousand
-\edef\pdfimageresolution {\pdfvariable imageresolution} \pdfimageresolution 300
-\edef\pdfimageapplygamma {\pdfvariable imageapplygamma} \pdfimageapplygamma \zerocount
-\edef\pdfimagegamma {\pdfvariable imagegamma} \pdfimagegamma 2200
-\edef\pdfimagehicolor {\pdfvariable imagehicolor} \pdfimagehicolor \plusone
-\edef\pdfimageaddfilename {\pdfvariable imageaddfilename} \pdfimageaddfilename \plusone
-\edef\pdfpkresolution {\pdfvariable pkresolution} \pdfpkresolution 1200
-\edef\pdfinclusioncopyfonts {\pdfvariable inclusioncopyfonts} \pdfinclusioncopyfonts \plusone
-\edef\pdfinclusionerrorlevel {\pdfvariable inclusionerrorlevel} \pdfinclusionerrorlevel \zerocount
-\edef\pdfgentounicode {\pdfvariable gentounicode} \pdfgentounicode \plusone
-\edef\pdfpagebox {\pdfvariable pagebox} \pdfpagebox \zerocount
-\edef\pdfmajorversion {\pdfvariable majorversion} % \pdfmajorversion \plusone
-\edef\pdfminorversion {\pdfvariable minorversion} \pdfminorversion \plusseven
-\edef\pdfuniqueresname {\pdfvariable uniqueresname} \pdfuniqueresname \zerocount
-\edef\pdfhorigin {\pdfvariable horigin} \pdfhorigin 1in
-\edef\pdfvorigin {\pdfvariable vorigin} \pdfvorigin \pdfhorigin
-\edef\pdflinkmargin {\pdfvariable linkmargin} \pdflinkmargin \zeropoint
-\edef\pdfdestmargin {\pdfvariable destmargin} \pdfdestmargin \zeropoint
-\edef\pdfthreadmargin {\pdfvariable threadmargin} \pdfthreadmargin \zeropoint
-\edef\pdfxformmargin {\pdfvariable xformmargin} \pdfxformmargin \zeropoint
-\edef\pdfpkfixeddpi {\pdfvariable pkfixeddpi} \pdfpkfixeddpi \plusone
-\edef\pdfignoreunknownimages {\pdfvariable ignoreunknownimages} \pdfignoreunknownimages \zerocount
-
-\edef\pdfpagesattr {\pdfvariable pagesattr}
-\edef\pdfpageattr {\pdfvariable pageattr}
-\edef\pdfpageresources {\pdfvariable pageresources}
-\edef\pdfxformattr {\pdfvariable xformattr}
-\edef\pdfxformresources {\pdfvariable xformresources}
-\edef\pdfpkmode {\pdfvariable pkmode}
-
-\edef\pdfsuppressoptionalinfo{\pdfvariable suppressoptionalinfo }
-\let \pdfsuppressptexinfo \pdfsuppressoptionalinfo
-\edef\pdftrailerid {\pdfvariable trailerid }
-\edef\pdfinfoomitdate {\pdfvariable suppressoptionalinfo \numexpr32+64\relax}
-
-\normalprotected\def\nopdfcompression {\pdfobjcompresslevel\zerocount \pdfcompresslevel\zerocount}
-\normalprotected\def\maximumpdfcompression{\pdfobjcompresslevel\plusnine \pdfcompresslevel\plusnine }
-\normalprotected\def\normalpdfcompression {\pdfobjcompresslevel\plusthree \pdfcompresslevel\plusthree}
-
-\normalpdfcompression
-
-\outputmode \zerocount % we generate the format in this mode
+\ifdefined\pdfvariable
+
+ \pdfvariable compresslevel \plusthree
+ \pdfvariable objcompresslevel \plusone
+ % \pdfvariable recompress \zerocount
+ \pdfvariable decimaldigits \plussix
+ \pdfvariable gamma \plusthousand
+ \pdfvariable imageresolution 300
+ \pdfvariable imageapplygamma \zerocount
+ \pdfvariable imagegamma 2200
+ \pdfvariable imagehicolor \plusone
+ \pdfvariable imageaddfilename \plusone
+ \pdfvariable pkresolution 1200
+ \pdfvariable inclusioncopyfonts \plusone
+ \pdfvariable inclusionerrorlevel \zerocount
+ \pdfvariable gentounicode \plusone
+ \pdfvariable omitcidset \plusone
+ \pdfvariable omitcharset \plusone
+ \pdfvariable pagebox \zerocount
+ % \pdfvariable majorversion % \plusone
+ \pdfvariable minorversion \plusseven
+ \pdfvariable uniqueresname \zerocount
+ \pdfvariable horigin 1in
+ \pdfvariable vorigin 1in
+ % \pdfvariable linkmargin \zeropoint
+ % \pdfvariable destmargin \zeropoint
+ % \pdfvariable threadmargin \zeropoint
+ % \pdfvariable xformmargin \zeropoint
+ \pdfvariable pkfixeddpi \plusone
+ \pdfvariable ignoreunknownimages \zerocount
+
+\fi
+
+\let\nopdfcompression \relax
+\let\onlypdfobjectcompression\relax
+\let\maximumpdfcompression \relax
+\let\normalpdfcompression \relax
+
+\ifdefined\outputmode
+ \outputmode \zerocount % we generate the format in this mode
+\fi
%D Basic status stuff.
@@ -1102,12 +1061,10 @@
\def\dividenumber#1#2{\the\numexpr(#2-(#1/2))/#1\relax}
\ifdefined\texenginename \else
- %edef\texenginename{luatex}
\edef\texenginename{\directlua{tex.print(LUATEXENGINE)}}
\fi
\ifdefined\texengineversion \else
- %edef\texengineversion{\dividenumber{100}\luatexversion.\modulonumber{100}\luatexversion.\luatexrevision}
\edef\texengineversion{\directlua{tex.print(LUATEXVERSION)}}
\fi
@@ -1120,43 +1077,39 @@
\savingvdiscards\plusone
%D We only can set this one via directives (system.synctex) and we only support
-%D the context variant.
+%D the context variant. This will go away completely.
\let\synctex\undefined \newcount\synctex \let\normalsynctex\synctex
%D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero.
-\voffset\zeropoint \let\voffset\relax \newdimen\voffset % prevent messing up
-\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset % prevent messing up
+\voffset\zeropoint \let\voffset\relax \newdimen\voffset \let\normalvoffset\voffset
+\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset \let\normalhoffset\hoffset
+
+\ifdefined\pageleftoffset
+ \let\pageleftoffset \hoffset \let\normalpageleftoffset \hoffset
+ \let\pagerightoffset \hoffset \let\normalpagerightoffset \hoffset
+ \let\pagetopoffset \voffset \let\normalpagetopoffset \voffset
+ \let\pagebottomoffset\voffset \let\normalpagebottomoffset\voffset
+\fi
%D Handy.
-\suppresslongerror \plusone % \let\suppresslongerror \relax
-\suppressoutererror \plusone % \let\suppressoutererror \relax
-\suppressmathparerror \plusone % \let\suppressmathparerror \relax
-\suppressifcsnameerror\plusone % \let\suppressifcsnameerror\relax
+\suppresslongerror \plusone
+\suppressoutererror \plusone
+\suppressmathparerror \plusone
+\suppressifcsnameerror\plusone
-\matheqnogapstep \zerocount % fr now
+\let \suppresslongerror \relax
+\newcount\suppresslongerror \let\normalsuppresslongerror \suppresslongerror
+\let \suppressoutererror \suppresslongerror \let\normalsuppressoutererror \suppresslongerror
+\let \suppressmathparerror \suppresslongerror \let\normalsuppressmathparerror \suppresslongerror
+\let \suppressifcsnameerror\suppresslongerror \let\normalsuppressifcsnameerror\suppresslongerror
-%D While cleaning this code up a bit I was listening to Heather Nova's \CD\ Redbird.
-%D The first song on that \CD\ ends with a few lines suitable for ending this
-%D initialization module:
-%D
-%D \startlines
-%D And there's so much I can do for you
-%D Given time I know that I can prove
-%D Now my world is opened up to you
-%D Come inside
-%D
-%D Welcome to my life
-%D Welcome to my world
-%D Come inside
-%D \stoplines
-%D
-%D So let's see what \TEX\ can do now that we've opened up the basic machinery.
+\matheqnogapstep\zerocount % for now
-%D Now we define a few helpers that we need in a very early stage. We hav eno message system
-%D yet but redundant definitions are fatal anyway.
+%D Now we define a few helpers that we need in a very early stage. We have no
+%D message system yet but redundant definitions are fatal anyway.
\newcount\c_syst_helpers_n_of_namespaces \c_syst_helpers_n_of_namespaces\pluseight % 1-8 reserved for catcodes
@@ -1183,30 +1136,4 @@
\let\normalstartdmath \Ustartdisplaymath
\let\normalstopdmath \Ustopdisplaymath
-%D For now:
-
-\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi
-\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi
-
-\ifdefined\mathrulesfam \else \newcount\mathrulesfam \fi
-\ifdefined\mathrulesmode \else \newcount\mathrulesmode \fi
-\ifdefined\mathsurroundmode \else \newcount\mathsurroundmode \fi
-\ifdefined\mathitalicsmode \else \newcount\mathitalicsmode \fi
-\ifdefined\mathdelimitersmode \else \newcount\mathdelimitersmode \fi
-\ifdefined\mathscriptboxmode \else \newcount\mathscriptboxmode \fi
-
-\ifdefined\hyphenpenaltymode \else \newcount\hyphenpenaltymode \fi
-\ifdefined\automatichyphenpenalty \else \newcount\automatichyphenpenalty \fi
-\ifdefined\automatichyphenmode \else \newcount\automatichyphenmode \fi
-\ifdefined\explicithyphenpenalty \else \newcount\explicithyphenpenalty \fi
-
-\ifdefined\explicitdiscretionary \else \let\explicitdiscretionary \- \fi
-\ifdefined\automaticdiscretionary \else \def\automaticdiscretionary{\Uchar\exhyphenchar} \fi
-
-\ifdefined\mathpenaltiesmode \else \newcount\mathpenaltiesmode \fi
-\ifdefined\prebinoppenalty \else \newcount\prebinoppenalty \fi
-\ifdefined\prerelpenalty \else \newcount\prerelpenalty \fi
-
-\ifdefined\breakafterdirmode \else \newcount\breakafterdirmode \fi
-
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-lua.lua b/Master/texmf-dist/tex/context/base/mkiv/syst-lua.lua
index 35cd221238f..a63c49e8faf 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/syst-lua.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-lua.lua
@@ -15,10 +15,10 @@ local context = context
local implement = interfaces.implement
local ctx_protected_cs = context.protected.cs -- more efficient
-local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments
-local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments
-local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument
-local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument
+local ctx_firstoftwoarguments = context.firstoftwoarguments
+local ctx_secondoftwoarguments = context.secondoftwoarguments
+local ctx_firstofoneargument = context.firstofoneargument
+local ctx_gobbleoneargument = context.gobbleoneargument
local two_strings = interfaces.strings[2]
@@ -105,7 +105,8 @@ local p_first = C((1-P(",")-P(-1))^0)
implement {
name = "firstinset",
arguments = "string",
- actions = function(str) context(lpegmatch(p_first,str or "")) end
+ actions = function(str) context(lpegmatch(p_first,str or "")) end,
+ public = true,
}
implement {
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-lua.mkiv b/Master/texmf-dist/tex/context/base/mkiv/syst-lua.mkiv
index ca5f9679ff8..3600dac3460 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/syst-lua.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-lua.mkiv
@@ -19,6 +19,42 @@
\def\expdoif #1#2{\clf_doifsame {#1}{#2}}
\def\expdoifnot #1#2{\clf_doifnotsame {#1}{#2}}
+%D Here is variant using a brainwave of the 12\high{+} hour \quotation {Long Road
+%D Out of Eden}\footnote {Eden being Backo\TeX\ 2018, where the virtues of the \type
+%D {\expanded} primitive were mentioned in talks.} trip. For now I don't really see
+%D other useful applications.
+
+\ifdefined\immediateassignment
+
+ \def\expandeddoif#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+ \def\expandeddoifnot#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+ \def\expandeddoifelse#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\fi
+
% \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3
% \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5
diff --git a/Master/texmf-dist/tex/context/base/mkiv/syst-rtp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/syst-rtp.mkiv
new file mode 100644
index 00000000000..82c0778b43f
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/syst-rtp.mkiv
@@ -0,0 +1,18 @@
+%D \module
+%D [ file=syst-rtp,
+%D version=2006.10.13,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Run Time Processes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\let\executesystemcommand\clf_execute
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-com.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-com.mkiv
index e9008636886..01a55e313f7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-com.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-com.mkiv
@@ -15,39 +15,51 @@
\unprotect
-\let\VL\relax
-
-\let\NC\relax
-\let\RC\relax
-\let\HC\relax
-\let\EQ\relax
-
-\let\RQ\relax
-\let\HQ\relax
-
-\let\NG\relax
-\let\NN\relax
-\let\ND\relax
-\let\NR\relax
-\let\NB\relax
-
+\let\AR\relax
+\let\BA\relax
+\let\BC\relax
+\let\BL\relax
\let\CC\relax
\let\CL\relax
\let\CM\relax
\let\CR\relax
-
-\let\SR\relax
+\let\DB\relax
+\let\EQ\relax
+\let\FB\relax
+\let\FL\relax
\let\FR\relax
-\let\MR\relax
+\let\HC\relax
+\let\HL\relax
+\let\HQ\relax
+\let\HR\relax
+\let\LB\relax
+\let\LL\relax
\let\LR\relax
-\let\AR\relax
-
-\let\FL\relax
\let\ML\relax
-\let\LL\relax
+\let\MR\relax
+\let\NA\relax
+\let\NB\relax
+\let\NC\relax
+\let\ND\relax
+\let\NF\relax
+\let\NG\relax
+\let\NI\relax
+\let\NL\relax
+\let\NN\relax
+\let\NP\relax
+\let\NR\relax
+\let\PB\relax
+\let\RC\relax
+\let\RQ\relax
+\let\SR\relax
\let\TL\relax
-\let\BL\relax
-\let\HL\relax
-\let\HR\relax
+\let\VL\relax
+
+\installmacrostack\BC
+\installmacrostack\EC
+\installmacrostack\EQ
+\installmacrostack\NC
+\installmacrostack\NN
+\installmacrostack\NR
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-ltb.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-ltb.mkiv
index 3147fa1cc1a..20ae8bf5a2b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-ltb.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-ltb.mkiv
@@ -705,14 +705,14 @@
\else
\t_tabl_lines_head\emptytoks
\fi
- \pushmacro\BC
- \pushmacro\EC
+ \push_macro_BC
+ \push_macro_EC
\def\BC##1\EC{\appendtoks##1\to\t_tabl_lines_head}%
\let\EC\relax} % signal
\unexpanded\def\tabl_lines_EH
- {\popmacro\EC
- \popmacro\BC
+ {\pop_macro_EC
+ \pop_macro_BC
\expandafter\startlinetablehead\the\t_tabl_lines_head\stoplinetablehead}
\let\startlinetablebody\relax
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-ntb.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-ntb.mkiv
index 9acf2ef363a..ca3d78800ac 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-ntb.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-ntb.mkiv
@@ -271,10 +271,10 @@
\letvalue{\??naturaltablesqueeze\v!broad}\donetrue
\letvalue{\??naturaltablesqueeze\v!local}\donetrue
-\def\tabl_ntb_let_gal{\global\expandafter\let\csname\??naturaltablegal\m_tabl_tbl_level\endcsname}
+\def\tabl_ntb_let_gal{\expandafter\glet\csname\??naturaltablegal\m_tabl_tbl_level\endcsname}
\def\tabl_ntb_get_gal{\csname\??naturaltablegal\m_tabl_tbl_level\endcsname}
-\def\tabl_ntb_let_tal#1{\global\expandafter\let\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname}
+\def\tabl_ntb_let_tal#1{\expandafter\glet\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname}
\def\tabl_ntb_get_tal#1{\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname}
\def\tabl_ntb_set_nob#1{\expandafter\let\csname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone}
@@ -291,8 +291,8 @@
%def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
\def\tabl_ntb_set_ht#1#2{\expandafter\xdef\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
-%def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
-\def\tabl_ntb_let_ht#1#2{\global\expandafter\let\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
+%def\tabl_ntb_let_wd#1#2{\expandafter\glet\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
+\def\tabl_ntb_let_ht#1#2{\expandafter\glet\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
\def\tabl_ntb_get_tag#1#2{\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname}
\def\tabl_ntb_get_col#1#2{\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname}
@@ -306,10 +306,10 @@
\def\tabl_ntb_set_dis#1{\expandafter\xdef\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
\def\tabl_ntb_set_aut#1{\expandafter\xdef\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
-\def\tabl_ntb_let_wid#1{\global\expandafter\let\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
-\def\tabl_ntb_let_hei#1{\global\expandafter\let\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
-\def\tabl_ntb_let_dis#1{\global\expandafter\let\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
-\def\tabl_ntb_let_aut#1{\global\expandafter\let\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
+\def\tabl_ntb_let_wid#1{\expandafter\glet\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
+\def\tabl_ntb_let_hei#1{\expandafter\glet\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
+\def\tabl_ntb_let_dis#1{\expandafter\glet\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
+\def\tabl_ntb_let_aut#1{\expandafter\glet\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
\def\tabl_ntb_get_wid#1{\ifcsname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi}
\def\tabl_ntb_get_hei#1{\ifcsname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi}
@@ -1161,13 +1161,11 @@
\def\tabl_ntb_row_stop_boxed
{% \noindent % no, else double leftskip in narrower
- \normalexpanded
- {\t_tabl_ntb
- {\the\t_tabl_ntb
- % no need for init
- \tabl_ntb_row_align_start
- \the\t_tabl_ntb_row
- \tabl_ntb_row_align_stop}}}
+ \etoksapp\t_tabl_ntb
+ {% no need for init
+ \tabl_ntb_row_align_start
+ \the\t_tabl_ntb_row
+ \tabl_ntb_row_align_stop}}
\def\tabl_ntb_row_stop_split
{\ifcsname\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_current_row\endcsname
@@ -1177,13 +1175,11 @@
\fi}
\def\tabl_ntb_row_stop_split_nop
- {\normalexpanded
- {\t_tabl_ntb
- {\the\t_tabl_ntb
- \tabl_ntb_row_align_reset
- \tabl_ntb_row_align_start
- \the\t_tabl_ntb_row
- \tabl_ntb_row_align_stop}}}
+ {\etoksapp\t_tabl_ntb
+ {\tabl_ntb_row_align_reset
+ \tabl_ntb_row_align_start
+ \the\t_tabl_ntb_row
+ \tabl_ntb_row_align_stop}}
\def\tabl_ntb_row_stop_split_yes
{\begingroup
@@ -1192,13 +1188,11 @@
\xdef\m_tabl_ntb_after_split {\naturaltablelocalparameter\c!after}% to be checked
\xdef\m_tabl_ntb_same_page {\naturaltablelocalparameter\c!samepage}%
\endgroup
- \normalexpanded
- {\t_tabl_ntb
- {\the\t_tabl_ntb
- \tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}%
- \tabl_ntb_row_align_start
- \the\t_tabl_ntb_row
- \tabl_ntb_row_align_stop}}}
+ \etoksapp\t_tabl_ntb
+ {\tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}%
+ \tabl_ntb_row_align_start
+ \the\t_tabl_ntb_row
+ \tabl_ntb_row_align_stop}}
\unexpanded\def\tabl_ntb_row_align_set#1#2#3%
{\xdef\m_tabl_ntb_before_split{#1}%
@@ -1206,9 +1200,9 @@
\xdef\m_tabl_ntb_same_page {#3}}
\unexpanded\def\tabl_ntb_row_align_reset
- {\global\let\m_tabl_ntb_before_split\empty
- \global\let\m_tabl_ntb_after_split \empty
- \global\let\m_tabl_ntb_same_page \empty}
+ {\glet\m_tabl_ntb_before_split\empty
+ \glet\m_tabl_ntb_after_split \empty
+ \glet\m_tabl_ntb_same_page \empty}
\def\tabl_ntb_prelocate_error
{\writestatus\m!TABLE{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \the\c_tabl_prelocated_rows)}}
@@ -1225,12 +1219,10 @@
\tabl_ntb_prelocate_error
\fi}%
\def\tabl_ntb_row_stop
- {\normalexpanded
- {\t_tabl_ntb
- {\the\t_tabl_ntb
- \tabl_ntb_row_align_start
- \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname
- \tabl_ntb_row_align_stop}}}%
+ {\etoksapp\t_tabl_ntb
+ {\tabl_ntb_row_align_start
+ \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname
+ \tabl_ntb_row_align_stop}}%
\global\c_tabl_prelocated_rows#1\relax}
\def\tabl_ntb_prelocate_okay
@@ -1344,37 +1336,23 @@
{\global\advance\c_tabl_ntb_col\plusone
\kern\d_tabl_ntb_columndistance}
-% \setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
-% {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
-% \ifnum\scratchcounter>\zerocount
-% \normalexpanded
-% {\t_tabl_ntb_row
-% {\the\t_tabl_ntb_row
-% \tabl_ntb_span{\the\scratchcounter}%
-% \tabl_ntb_plus}}%
-% \fi}
-
\setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
{\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
\ifnum\scratchcounter>\zerocount
- \normalexpanded
- {\t_tabl_ntb_row
- {\the\t_tabl_ntb_row
- \tabl_ntb_span{\the\scratchcounter}}}%
+ \etoksapp\t_tabl_ntb_row
+ {\tabl_ntb_span{\the\scratchcounter}}%
\fi}
\setvalue{\??naturaltablecell\the\c_tabl_ntb_cell}#1#2%
- {\t_tabl_ntb_row\expandafter{\the\t_tabl_ntb_row\tabl_ntb_pass #1 #2 }% space delimited -> less tokens
+ {\toksapp\t_tabl_ntb_row{\tabl_ntb_pass #1 #2 }% space delimited -> less tokens
\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
\ifnum\scratchcounter>\zerocount
- \normalexpanded
- {\t_tabl_ntb_row
- {\the\t_tabl_ntb_row
- \ifnum\scratchcounter=\plusone
- \tabl_ntb_plus
- \else
- \tabl_ntb_skip{\the\scratchcounter}%
- \fi}}%
+ \etoksapp\t_tabl_ntb_row
+ {\ifnum\scratchcounter=\plusone
+ \tabl_ntb_plus
+ \else
+ \tabl_ntb_skip{\the\scratchcounter}%
+ \fi}%
\fi}
\unexpanded\def\tabl_ntb_cell#1#2%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-tab.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-tab.mkiv
index 54b18a38590..631f29bc084 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-tab.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-tab.mkiv
@@ -417,7 +417,7 @@
% Key "a": a{TOKENS} adds TOKENS to the right of (after) the template
\newtableformatkey a#1%
- {\!taDataColumnTemplate\expandafter{\the\!taDataColumnTemplate #1}%
+ {\toksapp\!taDataColumnTemplate{#1}%
\doreadtableformatkeys}
% Key "\{": Enclose template in braces.
@@ -435,7 +435,7 @@
\scratchtoks\emptytoks
\!thLoop
\ifnum\scratchcounter>\zerocount
- \scratchtoks\expandafter{\the\scratchtoks#2}%
+ \toksapp\scratchtoks{#2}%
\advance\scratchcounter\minusone
\repeat
\expandafter\doreadtableformatkeys\the\scratchtoks}
@@ -688,7 +688,7 @@
% extensions
\newtableformatkey q%
- {\letempty\!tqStyle
+ {\let\!tqStyle\empty
\futurelet\!tnext\!tqTestForBracket}
\newtableformatkey Q%
@@ -928,7 +928,7 @@
\global\c_tabl_table_n_of_vrules\plusone
\unskip
\fi
- \global\let\m_tabl_table_vrule_color\empty
+ \glet\m_tabl_table_vrule_color\empty
\hfil
\aligntab}
@@ -1370,8 +1370,8 @@
{\tabl_tables_chuck_auto_row % before the tail, else noalign problem
\tabl_table_insert_tail
\starttablenoalign
- \global\let\tabl_table_head\empty
- \global\let\tabl_table_tail\empty
+ \glet\tabl_table_head\empty
+ \glet\tabl_table_tail\empty
\stoptablenoalign
\tabl_table_finish
\ifx\p_tabl_table_frame\empty
@@ -1481,7 +1481,7 @@
\tabl_table_restart
% \starttablenoalign
% \globalpushmacro\simpletableHL
-% \global\let\simpletableHL\doverysimpletableHL
+% \glet\simpletableHL\doverysimpletableHL
% \stoptablenoalign
\tabl_table_insert_head
\ifsplittables \ifconditional \c_tabl_table_repeat_tail
@@ -1593,8 +1593,8 @@
\egroup
\dontcomplain
\tabl_table_split_box\tablecontentbox
- \global\let\tabl_table_head\empty % new here
- \global\let\tabl_table_tail\empty % new here
+ \glet\tabl_table_head\empty % new here
+ \glet\tabl_table_tail\empty % new here
\flushnotes
\egroup}
@@ -1691,8 +1691,8 @@
\starttablenoalign
\nobreak
\tabl_table_set_action\tableunknownstate
- \globalletempty\tabl_tables_check_auto_row
- \globalletempty\tabl_tables_chuck_auto_row
+ \glet\tabl_tables_check_auto_row\empty
+ \glet\tabl_tables_chuck_auto_row\empty
\global\currenttablecolumn\zerocount
\stoptablenoalign}
@@ -1816,21 +1816,21 @@
%D the last row.
\unexpanded\def\tabl_table_AR
- {\globallet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed
- \globallet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed}
+ {\glet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed
+ \glet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed}
\let\tabl_tables_check_auto_row\empty
\let\tabl_tables_chuck_auto_row\empty
\def\tabl_tables_check_auto_row_indeed
- {\globallet\tabl_tables_check_auto_row\empty
+ {\glet\tabl_tables_check_auto_row\empty
\ifnum\tableactionstate=\tablerulestate \FR\else
\ifnum\tableactionstate=\tableunknownstate\FR\else
\MR\fi\fi}
\def\tabl_tables_chuck_auto_row_indeed
- {\globalletempty\tabl_tables_check_auto_row
- \globalletempty\tabl_tables_chuck_auto_row
+ {\glet\tabl_tables_check_auto_row\empty
+ \glet\tabl_tables_chuck_auto_row\empty
\ifnum\tableactionstate=\tablerulestate \SR\else
\ifnum\tableactionstate=\tableunknownstate\SR\else
\LR\fi\fi}
@@ -1914,7 +1914,7 @@
\dosingleempty\table_tabl_VL_indeed}
\def\table_tabl_VL_indeed[#1]%
- {\global\let\m_tabl_table_vrule_color\empty
+ {\glet\m_tabl_table_vrule_color\empty
\global\c_tabl_table_vrule_thickness_factor\m_tabl_table_VLwidth\relax
\iffirstargument
\rawprocesscommalist[#1]\tabl_table_vrulecommand
@@ -1961,7 +1961,7 @@
\bgroup
\global\c_tabl_table_hrule_thickness_factor\m_tabl_table_HLheight\relax
\iffirstargument
- \global\let\m_tabl_table_hrule_color\empty
+ \glet\m_tabl_table_hrule_color\empty
\rawprocesscommalist[#1]\tabl_table_hrulecommand
\ifx\m_tabl_table_hrule_color\empty\else
\switchtocolor[\m_tabl_table_hrule_color]%
@@ -2083,7 +2083,7 @@
\global\c_tabl_table_hrule_thickness_factor\m_tabl_table_HLheight\relax
\global\c_tabl_table_drule_span\zerocount
\iffirstargument
- \global\let\m_tabl_table_hrule_color\empty
+ \glet\m_tabl_table_hrule_color\empty
\rawprocesscommalist[#1]\tabl_table_drulecommand
% \ifx\m_tabl_table_hrule_color\empty\else
% \switchtocolor[\m_tabl_table_hrule_color]% see *DL*
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv
index 7a0d2c8a81c..75839caed16 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv
@@ -158,6 +158,7 @@
\newtoks \t_tabl_tabulate_dummy
\newtoks \t_tabl_tabulate_every_row
\newtoks \t_tabl_tabulate_every_after_row
+\newtoks \t_tabl_tabulate_every_real_row
\newtoks \t_tabl_tabulate_initializers_first
\newtoks \t_tabl_tabulate_initializers_second
@@ -174,6 +175,8 @@
\newcount \c_tabl_tabulate_totalnoflines
\newcount \c_tabl_tabulate_minusnoflines
\newcount \c_tabl_tabulate_align
+\newcount \c_tabl_tabulate_nofrealrows
+\newcount \c_tabl_tabulate_autocolor
\newcount \c_tabl_tabulate_nofcolumns % set at the lua end by parser
\newcount \c_tabl_tabulate_has_rule_spec_first % set at the lua end by parser (for the moment a count)
@@ -250,6 +253,18 @@
\installcorenamespace{tabulatefoot}
\installcorenamespace{tabulatenext}
+\prependtoks
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+\to \t_tabl_tabulate_initializers_first
+
+\prependtoks
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+\to \t_tabl_tabulate_initializers_second
+
+\prependtoks
+ \global\advance\c_tabl_tabulate_nofrealrows\plusone
+\to \t_tabl_tabulate_every_real_row
+
\def\b_tabl_tabulate_current#1%
{\csname\??tabulatebox\number#1\endcsname} % beware, a synonym
@@ -354,8 +369,8 @@
\ifx\m_tabl_tabulate_color_local\empty
\xdef\m_tabl_tabulate_color{#1}%
\else
- \global\let\m_tabl_tabulate_color\m_tabl_tabulate_color_local
- \global\let\m_tabl_tabulate_color_local\empty
+ \glet\m_tabl_tabulate_color\m_tabl_tabulate_color_local
+ \glet\m_tabl_tabulate_color_local\empty
\fi
\ifcase\c_tabl_tabulate_localcolorspan
\global\c_tabl_tabulate_colorspan#2\relax
@@ -381,8 +396,8 @@
\ifx\m_tabl_tabulate_vrule_color_local\empty
\xdef\m_tabl_tabulate_vrule_color{#1}%
\else
- \global\let\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local
- \global\let\m_tabl_tabulate_vrule_color_local\empty
+ \glet\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local
+ \glet\m_tabl_tabulate_vrule_color_local\empty
\fi}
\let\tabl_tabulate_check_local_color \gobbletwoarguments
@@ -553,13 +568,13 @@
\installtabulatepreambleoption{i}{\tabl_tabulate_set_preskip}
\installtabulatepreambleoption{j}{\tabl_tabulate_set_posskip}
\installtabulatepreambleoption{k}{\tabl_tabulate_set_preposskip}
-\installtabulatepreambleoption{e}{\t_tabl_tabulate_settings\expandafter{\the\t_tabl_tabulate_settings\global\settrue\c_tabl_tabulate_equal}%
+\installtabulatepreambleoption{e}{\toksapp\t_tabl_tabulate_settings{\global\settrue\c_tabl_tabulate_equal}%
\tabl_tabulate_set_preamble}
\installtabulatepreambleoption{g}{\tabl_tabulate_set_align}
\installtabulatepreambleoption{.}{\tabl_tabulate_set_align.}
\installtabulatepreambleoption{,}{\tabl_tabulate_set_align,}
\installtabulatepreambleoption{C}{\tabl_tabulate_set_color_span}
-\installtabulatepreambleoption{d}{\t_tabl_tabulate_settings\expandafter{\the\t_tabl_tabulate_settings\fixedspaces}%
+\installtabulatepreambleoption{d}{\toksapp\t_tabl_tabulate_settings{\fixedspaces}%
\tabl_tabulate_set_preamble}
\installtabulatepreambleoption{ }{\tabl_tabulate_set_preamble}
\installtabulatepreambleoption{A}{\tabl_tabulate_set_alignment}
@@ -607,18 +622,18 @@
\tabl_tabulate_set_preamble}
\def\tabl_tabulate_set_preskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_posskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_post.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_preposskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_setups#1%
@@ -704,6 +719,28 @@
\fi
\tabl_tabulate_set_preamble}
+% faster but seldom used
+%
+% \installcorenamespace{tabulatewidth}
+%
+% \setvalue{\??tabulatewidth\v!fit }{\c_tabl_tabulate_modus\plusthree}
+% \setvalue{\??tabulatewidth\v!fixed}{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_nopbreak}
+% \setvalue{\??tabulatewidth\v!auto }{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_reshape}
+%
+% \def\tabl_tabulate_set_width_step#1%
+% {\ifcsname\??tabulatewidth#1\endcsname
+% \lastnamedcs
+% \else
+% \d_tabl_tabulate_width#1\relax
+% \fi}
+%
+% \def\tabl_tabulate_set_width_indeed(#1)%
+% {\rawprocesscommacommand[#1]\tabl_tabulate_set_width_step
+% \ifconditional\c_tabl_tabulate_pwidth_set
+% \global\advance\d_tabl_tabulate_width_p\d_tabl_tabulate_width % accumulated parwidth
+% \fi
+% \tabl_tabulate_set_preamble}
+%
\def\tabl_tabulate_set_raggedright {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedright \fi}
\def\tabl_tabulate_set_raggedcenter{\ifnum\c_tabl_tabulate_type=\plusone \else\raggedcenter\fi}
\def\tabl_tabulate_set_raggedleft {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedleft \fi}
@@ -772,10 +809,10 @@
\t_tabl_tabulate_emath\emptytoks
\t_tabl_tabulate_font\emptytoks
\t_tabl_tabulate_settings\emptytoks
- \global\let\m_tabl_tabulate_alignment\empty
- \global\let\m_tabl_tabulate_color\empty
- \global\let\m_tabl_tabulate_text_color\empty
- \global\let\m_tabl_tabulate_vrule_color\empty
+ \glet\m_tabl_tabulate_alignment\empty
+ \glet\m_tabl_tabulate_color\empty
+ \glet\m_tabl_tabulate_text_color\empty
+ \glet\m_tabl_tabulate_vrule_color\empty
\global\c_tabl_tabulate_colorspan\zerocount
\global\setfalse\c_tabl_auto_align_mode
\global\advance\c_tabl_tabulate_columns\plusone
@@ -799,8 +836,8 @@
\fi}
\def\tabl_tabulate_set_last_entry#1% rulespec
- {\global\let\m_tabl_tabulate_color\empty
- \global\let\m_tabl_tabulate_vrule_color\empty
+ {\glet\m_tabl_tabulate_color\empty
+ \glet\m_tabl_tabulate_vrule_color\empty
\edef\currenttabulationtrulespec{#1}%
\ifx\currenttabulationtrulespec\empty
\global\d_tabl_tabulate_vrulethickness\zeropoint
@@ -1176,9 +1213,12 @@
\expandafter\tabl_start_regular_one
\fi}
+\def\tabl_default_format{|l|p|}
+
\def\tabl_start_regular_one[#1][#2]%
{\doifelseassignment{#1}
- {\setupcurrenttabulation[\c!format={|l|p|},#1]}
+ {\lettabulationparameter\c!format\tabl_default_format
+ \setupcurrenttabulation[#1]}
{\def\p_format{#1}%
\ifx\p_format\empty
\def\p_format{|l|p|}%
@@ -1189,7 +1229,7 @@
\def\tabl_start_regular_two[#1][#2]%
{\def\p_format{#1}%
\ifx\p_format\empty
- \def\p_format{|l|p|}%
+ \let\p_format\tabl_default_format
\fi
\lettabulationparameter\c!format\p_format
\setupcurrenttabulation[#2]%
@@ -1278,7 +1318,7 @@
\fi\fi}
\def\tabl_tabulate_outside_after_indeed
- {\tabulationparameter\c!after}%
+ {\tabulationparameter\c!after}
\def\tabl_tabulate_outside_inbetween_indeed
{\doifempty{\tabulationparameter\c!after}
@@ -1313,6 +1353,7 @@
\edef\p_bodyfont {\tabulationparameter\c!bodyfont}
\edef\p_indenting {\tabulationparameter\c!indenting}%
\edef\p_keeptogether {\tabulationparameter\c!keeptogether}%
+ \edef\p_blank {\tabulationparameter\c!blank}%
%
\ifx\p_keeptogether\v!no
\settrue \c_tabl_tabulate_tolerant_break
@@ -1325,6 +1366,8 @@
\settrue\c_tabl_tabulate_split
\csname\??tabulatesplit\tabulationparameter\c!split\endcsname
%
+ \let\m_tabl_tabulate_blank_default\p_blank
+ %
\d_tabl_tabulate_unit\tabulationparameter\c!unit
\d_tabl_tabulate_margin\tabulationparameter\c!margin
\let\m_tabl_tabulate_vrule_color_default\p_rulecolor
@@ -1371,14 +1414,15 @@
\let\m_tabl_tabulate_vrule_color_local \empty
\let\m_tabl_tabulate_vrule_color_default\empty % used local
\let\m_tabl_tabulate_hrule_color_default\empty % used local
+\let\m_tabl_tabulate_blank_default \empty
\appendtoks
- \global\let\m_tabl_tabulate_color_previous \empty
- \global\let\m_tabl_tabulate_color \empty
- \global\let\m_tabl_tabulate_text_color \empty
- \global\let\m_tabl_tabulate_color_local \empty
- \global\let\m_tabl_tabulate_vrule_color \empty
- \global\let\m_tabl_tabulate_vrule_color_local \empty
+ \glet\m_tabl_tabulate_color_previous \empty
+ \glet\m_tabl_tabulate_color \empty
+ \glet\m_tabl_tabulate_text_color \empty
+ \glet\m_tabl_tabulate_color_local \empty
+ \glet\m_tabl_tabulate_vrule_color \empty
+ \glet\m_tabl_tabulate_vrule_color_local \empty
\global \d_tabl_tabulate_vrulethickness_local\zeropoint
\to \t_tabl_tabulate_every_row
@@ -1470,7 +1514,7 @@
% ruled columns
\def\tabl_tabulate_column_vruled_preset
- {\global\let\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default
+ {\glet\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default
\global\d_tabl_tabulate_vrulethickness_local\d_tabl_tabulate_vrulethickness_default}
\def\tabl_tabulate_column_vruled#1#2%
@@ -1513,7 +1557,7 @@
\global\c_tabl_tabulate_max_vrulecolumn\zerocount}
\def\tabl_tabulate_vrule_reset_step % undefined or relax
- {\global\expandafter\let\csname\??tabulatevrule\the\fastloopindex\endcsname\undefined}
+ {\expandafter\glet\csname\??tabulatevrule\the\fastloopindex\endcsname\undefined}
\appendtoks
\tabl_tabulate_vrule_reset
@@ -1606,12 +1650,12 @@
\egroup}
\def\tabl_tabulate_hrule_spec_ignore#1%
- {%\global\let\currenttabulationlocalhrulecolor\empty
+ {%\glet\currenttabulationlocalhrulecolor\empty
%\global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default
\doifelsefastoptionalcheck#1#1}
\def\tabl_tabulate_hrule_spec_pickup#1%
- {\global\let\currenttabulationlocalhrulecolor\m_tabl_tabulate_hrule_color_default
+ {\glet\currenttabulationlocalhrulecolor\m_tabl_tabulate_hrule_color_default
\global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default
\doifelsefastoptionalcheck{\tabl_tabulate_hrule_preset#1}#1}
@@ -1625,10 +1669,11 @@
#1}
\def\tabl_tabulate_hrule_inject_normal
- {\hrule
- \s!height.5\d_tabl_tabulate_hrulethickness_local
- \s!depth .5\d_tabl_tabulate_hrulethickness_local
- \relax}
+ {\autorule
+ \s!height .5\d_tabl_tabulate_hrulethickness_local
+ \s!depth .5\d_tabl_tabulate_hrulethickness_local
+ \s!left \d_tabl_tabulate_indent
+ \relax}
\def\tabl_tabulate_hrule_inject_colored
{\dousecolorparameter\currenttabulationlocalhrulecolor
@@ -1686,21 +1731,21 @@
\unexpanded\def\tabl_tabulate_color_set#1% we could store the attributes at the cost of a lua call
{\begingroup
\clf_enablebackgroundalign % was \node_backgrounds_align_initialize
- \global\let\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second
+ \glet\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second
\global\settrue\c_tabl_tabulate_has_colors
\ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_colorcolumn
\global\c_tabl_tabulate_max_colorcolumn\c_tabl_tabulate_column
\fi
- \global\expandafter\xdef\csname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}%
- \hbox \thealignbackgroundcolorattr{#1}{}% pack ?
+ \expandafter\xdef\csname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}%
+ \hpack \thealignbackgroundcolorattr{#1}{}% pack ?
\endgroup}
\def\tabl_tabulate_color_repeat_second % for split off lines
{\begingroup
\scratchcounter\numexpr\c_tabl_tabulate_column-\plusone\relax % ugly !
\ifcsname\??tabulatecolor\the\scratchcounter\endcsname
- %\hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ?
- \hbox \thealignbackgroundcolorattr{\lastnamedcs}{}% pack ?
+ % \hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ?
+ \hpack \expandafter\thealignbackgroundcolorattr\expandafter{\lastnamedcs}{}% pack ?
\fi
\endgroup}
@@ -1722,7 +1767,7 @@
{\dofastloopcs\c_tabl_tabulate_max_colorcolumn\tabl_tabulate_color_reset_step}
\def\tabl_tabulate_color_reset_step % undefined or empty?
- {\global\expandafter\let\csname\??tabulatecolor\number\fastloopindex\endcsname\undefined}
+ {\expandafter\glet\csname\??tabulatecolor\number\fastloopindex\endcsname\undefined}
\appendtoks
\tabl_tabulate_color_reset
@@ -1771,17 +1816,20 @@
\tabl_tabulate_register_par_options
\to \t_tabl_tabulate_every_row
+\def\tabl_tabulate_flush_indent_indeed
+ {\hbox to \d_tabl_tabulate_indent % pack ?
+ {% we now have a local hsize, and since we want to
+ % register positional info (i.e. real hsizes) we
+ % need to reconstitute the original hsize
+ \advance\hsize\d_tabl_tabulate_indent
+ % this is indeed rather messy and took a few hours
+ % to dis/uncover
+ \the\t_tabl_tabulate_every_row
+ \hss}}
+
\def\tabl_tabulate_flush_indent
{\ifnum\c_tabl_tabulate_column=\zerocount
- \hbox to \d_tabl_tabulate_indent % pack ?
- {% we now have a local hsize, and since we want to
- % register positional info (i.e. real hsizes) we
- % need to reconstitute the original hsize
- \advance\hsize\d_tabl_tabulate_indent
- % this is indeed rather messy and took a few hours
- % to dis/uncover
- \the\t_tabl_tabulate_every_row
- \hss}%
+ \tabl_tabulate_flush_indent_indeed
\fi}
\def\tabl_tabulate_digits{\digits}
@@ -1800,7 +1848,7 @@
\unexpanded\def\tabl_tabulate_bskip_first {\setbox\b_tabl_tabulate\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
\unexpanded\def\tabl_tabulate_eskip_first {\par\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
-\unexpanded\def\tabl_tabulate_xbskip_first{\hbox\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
+\unexpanded\def\tabl_tabulate_xbskip_first{\hpack\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
\unexpanded\def\tabl_tabulate_xeskip_first{\par\egroup\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
\let\tabl_tabulate_bbskip\relax
@@ -1831,12 +1879,12 @@
% \def\tabl_tabulate_break_state_set
% {%\writestatus{SET}{\the\c_tabl_tabulate_noflines}%
-% \global\expandafter\let\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\conditionaltrue}
+% \expandafter\glet\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\conditionaltrue}
%
% \def\tabl_tabulate_break_state_reset
% {\ifcsname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname
% %\writestatus{RESET}{\the\c_tabl_tabulate_noflines}%
-% \global\expandafter\let\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\undefined
+% \expandafter\glet\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\undefined
% \fi}
%
% \def\tabl_tabulate_break_state_allowbreak
@@ -1912,8 +1960,6 @@
%D
%D \typebuffer \getbuffer
-\let\NI\relax
-
\unexpanded\def\tabl_tabulate_NI_first{\doifelsefastoptionalcheck\tabl_tbl_NI_yes\tabl_tbl_NI_nop}
\def\tabl_tbl_NI_yes[#1]{\NC \itemtag[#1]\NC}
@@ -2189,7 +2235,7 @@
% \def\tabulatedoHRfive % horizontal rule line (break untested)
% {\starttabulatenoalign
-% \globallet\dotabulateautoline\dotabulatelinerule
+% \glet\dotabulateautoline\dotabulatelinerule
% %\ifcase#1\or % todo: check what this does
% \ifnum\noftabulatelines=\zerocount
% \glet\dotabulateautoline\donothing
@@ -2204,9 +2250,9 @@
% \tabl_tabulate_break_no
% \ifx\dotabulateautoline\dotabulatelinerule\kern-\lineheight\fi
% \ifnum\noftabulatelines=\totalnoftabulatelines
-% \@EA\dotabulatenobreak
+% \expandafter\dotabulatenobreak
% \else
-% \@EA\tabl_tabulate_break_allow
+% \expandafter\tabl_tabulate_break_allow
% \fi
% \stoptabulatenoalign
% \dotabulateautoline
@@ -2403,8 +2449,8 @@
\dostarttaggedchained\t!tabulate\empty\??tabulation
\dostarttagged\t!tabulaterow\empty
\setfalse\inhibitmargindata % new per 2012.06.13 ... really needed
- \everycr\expandafter{\the\everycr\dostoptagged\dostarttagged\t!tabulaterow\empty}%
- % \toksapp\everycr{\dostoptagged\dostarttagged\t!tabulaterow\empty}%
+ % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
+ \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
\expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}%
\dostoptagged
\dostoptagged
@@ -2504,9 +2550,11 @@
\def\tabl_tabulate_TB_indeed[#1]%
{\iffirstargument
\blank[#1]
- \else
+ \else\ifx\m_tabl_tabulate_blank_default\empty
\blank
- \fi
+ \else
+ \blank[\m_tabl_tabulate_blank_default]%
+ \fi\fi
\stoptabulatenoalign}
% to be tested:
@@ -2729,4 +2777,295 @@
\unexpanded\def\tabulaterowtype{\tabl_tabulate_compact_row\type}
\unexpanded\def\tabulaterowtyp {\tabl_tabulate_compact_row\typ}
+%D Here we plug in a row background feature. As we only have support for
+%D \type {frame=name} we can use these variables.
+%D
+%D \starttyping
+%D \startuseMPgraphic{foo}
+%D fill unitsquare
+%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+%D randomized ExHeight
+%D shifted (-ExHeight/8,ExHeight/16)
+%D withcolor RuleColor ;
+%D \stopuseMPgraphic
+%D
+%D \setuptabulate % wel only have frame=name so we can use these:
+%D [background=foo,
+%D backgroundcolor=darkred,
+%D foregroundcolor=white]
+%D
+%D \definelinefiller[foo][mp=foo,color=darkgreen]
+%D \definelinefiller[bar][mp=foo,color=darkred]
+%D
+%D \starttabulate[|||]
+%D \DB foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate[|||]
+%D \PB foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate[|||]
+%D \FB[bar] foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \startnarrower
+%D \starttabulate[|||]
+%D \DB foo \DB bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D \stopnarrower
+%D
+%D \starttabulate[|||]
+%D \BC foo \BC bar \BC \NR
+%D \NL[magenta] foo \NC bar \NC \NR
+%D \NL[yellow] foo \NC bar \NC \NR
+%D \NL[cyan] foo \NC bar \NC \NR
+%D \NL[gray] foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate
+%D \NL[red] foo \NC bar \NC \NR
+%D \NL[green] foo \NL[red] bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NL[blue] foo \NC \input tufte \NC \NR
+%D \NL[gray] foo \NC bar \NC \NR
+%D \NL[yellow] foo \NC bar \NC \NR
+%D \stoptabulate
+%D \stoptyping
+
+% \setuptabulate
+% [\c!background=,
+% \c!backgroundcolor=,
+% \c!foregroundcolor=,
+% \c!foregroundstyle=]
+
+\let\m_table_current_row_background \empty
+\let\m_table_current_row_background_default \empty
+\let\m_table_current_row_background_filler \empty
+\let\m_table_current_row_background_defaultfiller\empty
+\let\m_table_current_row_background_auto \empty
+
+\unexpanded\def\tabl_register_row_background#1%
+ {\xdef\m_table_current_row_background{#1}}
+
+\unexpanded\def\tabl_register_row_background_filler#1%
+ {\xdef\m_table_current_row_background_filler{#1}}
+
+\unexpanded\def\tabl_synchronize_row_background
+ {\iftrialtypesetting\else
+ \ifx\m_table_current_row_background_filler\empty
+ \ifx\m_table_current_row_background\empty
+ % nothing
+ \tabl_synchronize_row_background_dummy
+ \else
+ \tabl_synchronize_row_background_indeed\m_table_current_row_background
+ \fi
+ \else
+ \tabl_synchronize_row_background_filler_indeed\m_table_current_row_background_filler
+ \fi
+ \fi}
+
+\unexpanded\def\tabl_synchronize_row_background_dummy
+ {\iftrialtypesetting\else
+ \begingroup
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\zerocount\zeropoint
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\zerocount\zeropoint
+ \endgroup
+ \fi}
+
+\unexpanded\def\tabl_synchronize_row_background_indeed#1%
+ {\iftrialtypesetting\else
+ \begingroup
+ \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
+ \dousecolorparameter{#1}%
+ \setbox\scratchbox\hpack{}%
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
+ \endgroup
+ \fi}
+
+\unexpanded\def\tabl_synchronize_row_background_filler_indeed#1%
+ {\iftrialtypesetting\else
+ \begingroup
+ \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
+ \node_linefiller_set{#1}%
+ \setbox\scratchbox\hpack{}%
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
+ \endgroup
+ \fi}
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+ \global\c_tabl_tabulate_autocolor\zerocount
+ \clf_resetbackgroundrowdata
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+ \global\c_tabl_tabulate_autocolor\zerocount
+ \clf_resetbackgroundrowdata
+\to \t_tabl_tabulate_initializers_second
+
+\appendtoks
+ \tabl_synchronize_row_background
+\to \t_tabl_tabulate_every_real_row
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+\to \t_tabl_tabulate_every_after_row
+
+\unexpanded\def\tabl_tabulate_NL_first[#1]%
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background{#1}%
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_ND_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background\m_table_current_row_background_default
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_LB_first[#1]%
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background{#1}%
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_DB_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background\m_table_current_row_background_default
+ \fi
+ \let\fontstyle\globalfontstyle
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_NF_first[#1]%
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler{#1}%
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_NP_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler\m_table_current_row_background_default_filler
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_FB_first[#1]%
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler{#1}%
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_PB_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler\m_table_current_row_background_default_filler
+ \fi
+ \let\fontstyle\globalfontstyle
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_BC_first % overloaded
+ {\tabl_tabulate_column_normal\plusone\zerocount
+ \let\fontstyle\globalfontstyle
+ \ifx\m_table_current_row_background\empty
+ \ifx\m_table_current_row_background_filler\empty
+ \usetabulationstyleandcolor\c!headstyle\c!headcolor
+ \else
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \fi
+ \else
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \fi}
+
+\unexpanded\def\tabl_tabulate_A_first
+ {\global\advance\c_tabl_tabulate_autocolor\plusone
+ \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}%
+ \ifx\m_table_current_row_background_auto\empty
+ \global\c_tabl_tabulate_autocolor\plusone
+ \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}%
+ \fi
+ \ifx\m_table_current_row_background_auto\empty
+ \let\m_table_current_row_background_auto\empty % \m_table_current_row_background_default
+ \fi
+ \tabl_register_row_background{\m_table_current_row_background_auto}}
+
+\unexpanded\def\tabl_tabulate_NA_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \iftrialtypesetting\else
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_tabulate_A_first
+ \fi
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\tabl_tabulate_BA_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \iftrialtypesetting\else
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_tabulate_A_first
+ \fi
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\appendtoks
+ \let\NL\tabl_tabulate_NL_first % NC with Line
+ \let\ND\tabl_tabulate_ND_first % NC with Default Line
+ \let\LB\tabl_tabulate_LB_first % BC with Line
+ \let\DB\tabl_tabulate_DB_first % BC with Default Line
+ \let\NF\tabl_tabulate_NF_first % NC with Filler
+ \let\NP\tabl_tabulate_NP_first % NC with Predefined Filler
+ \let\FB\tabl_tabulate_FB_first % BC with Filler
+ \let\PB\tabl_tabulate_PB_first % BC with Predefined Filler
+ \let\NA\tabl_tabulate_NA_first % NC with Auto Line
+ \let\BA\tabl_tabulate_BA_first % NC with Auto Line
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \edef\m_table_current_row_background_default {\tabulateparameter\c!backgroundcolor}%
+ \edef\m_table_current_row_background_default_filler{\tabulateparameter\c!background}%
+ \let \m_table_current_row_background_auto \empty
+\to \everytabulate
+
+\setuptabulate
+ [\c!headcolor=,
+ \c!headstyle=\bf,
+ \c!backgroundcolor=\tabulationparameter\c!rulecolor,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=\tabulationparameter\c!headstyle]
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-tsp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/tabl-tsp.mkiv
index 2c4b694b332..e0ddce38a58 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-tsp.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-tsp.mkiv
@@ -441,6 +441,35 @@
\exitloop
\fi\fi}
+%D Maybe handy:
+%D
+%D \starttyping
+%D \splitfloat
+%D {\placefigure{some caption}}
+%D {\startsplittext
+%D \typefile[option=TEX,before=,after=]{oeps.tex}
+%D \stopsplittext}
+%D \stoptyping
+
+\def\handlesplittext#1%
+ {\setbox\tsplitresult\vbox
+ {\vsplit\tsplitcontent to \dimexpr#1-\lineheight\relax}}
+
+\unexpanded\def\startsplittext
+ {\begingroup
+ \resettsplit
+ \let\tsplitminimumfreelines\!!zerocount
+ \let\tsplitminimumfreespace\!!zeropoint
+ \let\extrasplitfloatlines \!!plusone
+ \let\tsplitdirectsplitter \handlesplittext
+ \setbox\tsplitcontent\vbox\bgroup
+ \insidefloattrue}
+
+\unexpanded\def\stopsplittext
+ {\egroup
+ \handledirecttsplit
+ \endgroup}
+
\protect \endinput
% test cases
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.lua b/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.lua
index 524ca109c61..c9d50638e67 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.lua
@@ -70,7 +70,7 @@ local getbox = nuts.getbox
local getwhd = nuts.getwhd
local setlink = nuts.setlink
-local setdir = nuts.setdir
+local setdirection = nuts.setdirection
local setshift = nuts.setshift
local copy_node_list = nuts.copy_list
@@ -84,6 +84,8 @@ local new_glue = nodepool.glue
local new_kern = nodepool.kern
local new_hlist = nodepool.hlist
+local lefttoright_code = nodes.dirvalues.lefttoright
+
local v_stretch = variables.stretch
local v_normal = variables.normal
local v_width = variables.width
@@ -375,7 +377,8 @@ function xtables.set_reflow_width()
--
drc.dimensionstate = dimensionstate
--
- local nx, ny = drc.nx, drc.ny
+ local nx = drc.nx
+ local ny = drc.ny
if nx > 1 or ny > 1 then
-- local spans = data.spans -- not used
local self = true
@@ -886,13 +889,13 @@ function xtables.construct()
-- we have a direction issue here but hpack_node_list(list,0,"exactly","TLT") cannot be used
-- due to the fact that we need the width
local hbox = hpack_node_list(list)
- setdir(hbox,"TLT")
+ setdirection(hbox,lefttoright_code)
result[nofr] = {
hbox,
size,
i < nofrange and rowdistance > 0 and rowdistance or false, -- might move
false,
- rp and rp.samepage or false,
+ rp or false,
}
end
end
@@ -901,7 +904,7 @@ function xtables.construct()
result[1] [5] = false
result[nofr][5] = false
for i=2,nofr-1 do
- local r = result[i]
+ local r = result[i][5]
if r == v_both or r == v_before then
result[i-1][5] = true
elseif r == v_after then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.mkvi b/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.mkvi
index dc4a30e2b0c..1483043316d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/tabl-xtb.mkvi
@@ -102,6 +102,10 @@
\newcount\c_tabl_x_nesting
\newcount\c_tabl_x_skip_mode % 1 = skip
\newdimen\d_tabl_x_textwidth
+\newcount\c_tabl_x_swapped
+\newcount\c_tabl_x_swapped_max
+
+\let\m_tabl_x_swapped_settings\empty
\let\currentxtablerow \clf_x_table_r
\let\currentxtablecolumn\clf_x_table_c
@@ -112,6 +116,7 @@
\installcorenamespace{xtable}
\installcorenamespace{xtablecheck}
+\installcorenamespace{xtableswap}
\installframedautocommandhandler \??xtable {xtable} \??xtable
@@ -271,6 +276,8 @@
\let\tabl_x_start_cell_nop\relax
\let\tabl_x_stop_cell \relax
+\newtoks\t_table_x_cleanup
+
\unexpanded\def\tabl_x_process
{\begingroup % *
\forgetall % moved here
@@ -296,6 +303,7 @@
% not so nice but needed as we use this in the setup
\linewidth\xtableparameter\c!rulethickness\relax
% so we freeze it
+ \c_tabl_x_swapped_max\zerocount
\begingroup
\let\tabl_x_start_row_yes \tabl_x_start_row_reflow_width_yes
\let\tabl_x_start_row_nop \tabl_x_start_row_reflow_width_nop
@@ -305,6 +313,10 @@
\let\tabl_x_stop_cell \tabl_x_stop_cell_reflow_width
\settrialtypesetting
\tabl_x_get_buffer
+ \ifcase\c_tabl_x_swapped_max
+ \else
+ \tabl_x_flush_swapped
+ \fi
\clf_x_table_reflow_width
\endgroup
\begingroup
@@ -315,7 +327,11 @@
\let\tabl_x_start_cell_nop\tabl_x_start_cell_reflow_height_nop
\let\tabl_x_stop_cell \tabl_x_stop_cell_reflow_height
\settrialtypesetting
- \tabl_x_get_buffer
+ \ifcase\c_tabl_x_swapped_max
+ \tabl_x_get_buffer
+ \else
+ \tabl_x_flush_swapped
+ \fi
\clf_x_table_reflow_height
\endgroup
\begingroup
@@ -325,7 +341,11 @@
\let\tabl_x_start_cell_yes\tabl_x_start_cell_construct_yes
\let\tabl_x_start_cell_nop\tabl_x_start_cell_construct_nop
\let\tabl_x_stop_cell \tabl_x_stop_cell_construct
- \tabl_x_get_buffer
+ \ifcase\c_tabl_x_swapped_max
+ \tabl_x_get_buffer
+ \else
+ \tabl_x_flush_swapped
+ \fi
\clf_x_table_construct
\endgroup
\endgroup % *
@@ -340,6 +360,7 @@
\dostoptagged
\resetbuffer[\tabl_x_current_buffer]%
\resetcharacteralign
+ \the\t_table_x_cleanup
\egroup}
% text flow split modes
@@ -477,10 +498,6 @@
\unexpanded\def\stopxcell
{\tabl_x_stop_cell}
-\unexpanded\def\dummyxcell#1%
- {\tabl_x_start_cell_nop
- \tabl_x_stop_cell}
-
\unexpanded\def\dummyxcell
{\tabl_x_start_cell_nop
\tabl_x_stop_cell}
@@ -879,4 +896,124 @@
\let\NR\tabl_x_nr
\to \everypreparextable
+%D Another bonus, suggested by Taco at the 2018 \CONTEXT\ meeting.
+
+\unexpanded\def\tabl_x_c_cell_start#settings%
+ {\begingroup
+ \tabl_x_set_checked{#settings}%
+ \doifelsenextoptionalcs\tabl_x_start_cell_yes\tabl_x_start_cell_nop}
+
+\unexpanded\def\tabl_x_c_cell_stop
+ {\tabl_x_stop_cell
+ \endgroup}
+
+% \unexpanded\def\dummyxcell
+% {\tabl_x_start_cell_nop
+% \tabl_x_stop_cell}
+
+\def\tabl_x_flush_swapped
+ {\dorecurse\c_tabl_x_swapped_max
+ {\expandafter
+ \startxrow
+ \the\csname\??xtableswap##1\endcsname\relax
+ \stopxrow}}
+
+\def\tabl_x_collect_allocate
+ {\expandafter\newtoks\csname\??xtableswap\number\c_tabl_x_swapped\endcsname
+ \expandafter\let\expandafter\t_tabl_x_swapped\csname\??xtableswap\number\c_tabl_x_swapped\endcsname}
+
+\def\tabl_x_collect_advance
+ {\global\advance\c_tabl_x_swapped\plusone
+ \ifnum\c_tabl_x_swapped>\c_tabl_x_swapped_max
+ \global\c_tabl_x_swapped_max\c_tabl_x_swapped
+ \fi
+ \expandafter\let\expandafter\t_tabl_x_swapped\csname\??xtableswap\number\c_tabl_x_swapped\endcsname
+ \ifx\t_tabl_x_swapped\relax
+ \tabl_x_collect_allocate
+ \fi}
+
+\unexpanded\def\tabl_x_collect_cell_start
+ {\doifelsenextoptionalcs
+ \tabl_x_collect_cell_start_yes
+ \tabl_x_collect_cell_start_nop}
+
+\def\tabl_x_collect_cell_start_nop#content\stopxcell
+ {\tabl_x_collect_advance
+ \ifx\m_tabl_x_swapped_settings\empty
+ \gtoksapp\t_tabl_x_swapped{\tabl_x_c_cell_start{}#content\tabl_x_c_cell_stop}%
+ \else
+ \gtoksapp\t_tabl_x_swapped\expandafter{\expandafter\tabl_x_c_cell_start\expandafter{\m_tabl_x_swapped_settings}#content\tabl_x_c_cell_stop}%
+ \fi}
+
+\def\tabl_x_collect_cell_start_yes[#settings]#content\stopxcell
+ {\tabl_x_collect_advance
+ \ifx\m_tabl_x_swapped_settings\empty
+ \gtoksapp\t_tabl_x_swapped{\tabl_x_c_cell_start{}[#settings]#content\tabl_x_c_cell_stop}%
+ \else
+ \gtoksapp\t_tabl_x_swapped\expandafter{\expandafter\tabl_x_c_cell_start\expandafter{\m_tabl_x_swapped_settings}[#settings]#content\tabl_x_c_cell_stop}%
+ \fi
+ \getdummyparameters[\c!ny=1,#settings]%
+ \scratchcounter\numexpr\dummyparameter\c!ny-\plusone\relax
+ \ifcase\scratchcounter\else
+ \dorecurse\scratchcounter\tabl_x_collect_advance
+ \fi}
+
+\unexpanded\def\startxcolumn % todo: arguments
+ {\begingroup
+ \global\c_tabl_x_swapped\zerocount
+ \let\startxcell\tabl_x_collect_cell_start
+ \let\stopxcell \relax
+ \doifelsenextoptionalcs\tabl_x_start_column_yes\tabl_x_start_column_nop}
+
+\def\tabl_x_start_column_yes[#1]%
+ {\xdef\m_tabl_x_swapped_settings{#1}}
+
+\def\tabl_x_start_column_nop
+ {\glet\m_tabl_x_swapped_settings\empty}
+
+\unexpanded\def\stopxcolumn
+ {\endgroup}
+
+\appendtoks
+ \dorecurse\c_tabl_x_swapped_max
+ {\global\csname\??xtableswap\number#1\endcsname\emptytoks}%
+\to \t_table_x_cleanup
+
+%D \stopbuffer
+%D \setupxtable[one][foregroundcolor=red]
+%D \setupxtable[two][foregroundcolor=blue]
+%D
+%D \startlinecorrection
+%D \startxtable
+%D \startxrow[one]
+%D \startxcell[width=5cm] Row 1, Column 1 \stopxcell
+%D \startxcell Row 1, Column 2 \stopxcell
+%D \startxcell Row 1, Column 3 \stopxcell
+%D \stopxrow
+%D \startxrow[two]
+%D \startxcell Row 2, Column 1 \stopxcell
+%D \startxcell Row 2, Column 2 \stopxcell
+%D \startxcell Row 2, Column 3 \stopxcell
+%D \stopxrow
+%D \stopxtable
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \startxtable
+%D \startxcolumn[one]
+%D \startxcell[width=5cm] Row 1, Column 1 \stopxcell
+%D \startxcell Row 1, Column 2 \stopxcell
+%D \startxcell Row 1, Column 3 \stopxcell
+%D \stopxcolumn
+%D \startxcolumn[two]
+%D \startxcell Row 2, Column 1 \stopxcell
+%D \startxcell Row 2, Column 2 \stopxcell
+%D \startxcell Row 2, Column 3 \stopxcell
+%D \stopxcolumn
+%D \stopxtable
+%D \stoplinecorrection
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/task-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/task-ini.lua
index f41fb9b0885..19fff66b8f4 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/task-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/task-ini.lua
@@ -18,224 +18,132 @@ if not modules then modules = { } end modules ['task-ini'] = {
-- not apply the font handler, we can remove all checks for subtypes 255
local tasks = nodes.tasks
-local prependaction = tasks.prependaction
local appendaction = tasks.appendaction
local disableaction = tasks.disableaction
local enableaction = tasks.enableaction
local freezegroup = tasks.freezegroup
local freezecallbacks = callbacks.freeze
-appendaction("processors", "normalizers", "languages.replacements.handler") -- disabled
-
-appendaction("processors", "normalizers", "typesetters.wrappers.handler") -- disabled
-appendaction("processors", "normalizers", "typesetters.characters.handler") -- always on
-appendaction("processors", "normalizers", "fonts.collections.process") -- disabled
-appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled
-
-appendaction("processors", "characters", "scripts.autofontfeature.handler")
-appendaction("processors", "characters", "scripts.splitters.handler") -- disabled
-appendaction("processors", "characters", "typesetters.cleaners.handler") -- disabled
-appendaction("processors", "characters", "typesetters.directions.handler") -- disabled
-appendaction("processors", "characters", "typesetters.cases.handler") -- disabled
-appendaction("processors", "characters", "typesetters.breakpoints.handler") -- disabled
-appendaction("processors", "characters", "scripts.injectors.handler") -- disabled
-
-------------("processors", "words", "languages.replacements.handler") -- disabled
-appendaction("processors", "words", "languages.words.check") -- disabled -- might move up, no disc check needed then
-appendaction("processors", "words", "languages.hyphenators.handler") -- always on
-appendaction("processors", "words", "typesetters.initials.handler") -- disabled -- might move up
-appendaction("processors", "words", "typesetters.firstlines.handler") -- disabled
-
-appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental
-appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo
-appendaction("processors", "fonts", "nodes.injections.handler")
-appendaction("processors", "fonts", "typesetters.fontkerns.handler")
-appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo
-appendaction("processors", "fonts", "builders.kernel.ligaturing") -- not always on (could be selective: if only node mode)
-appendaction("processors", "fonts", "builders.kernel.kerning") -- not always on (could be selective: if only node mode)
-appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move)
-------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling)
-appendaction("processors", "fonts", "nodes.handlers.flatten")
-
-appendaction("processors", "lists", "typesetters.rubies.check") -- disabled (maybe someplace else)
-appendaction("processors", "lists", "typesetters.characteralign.handler") -- disabled (we need to to this after otf appliance)
-appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled
-appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled
-appendaction("processors", "lists", "typesetters.digits.handler") -- disabled (after otf handling)
-appendaction("processors", "lists", "typesetters.italics.handler") -- disabled (after otf/kern handling)
-appendaction("processors", "lists", "languages.visualizediscretionaries") -- disabled
-
-appendaction("processors", "after", "typesetters.marksuspects")
-
-appendaction("shipouts", "normalizers", "typesetters.showsuspects")
-appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled
-------------("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled
-appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled
-appendaction("shipouts", "normalizers", "typesetters.alignments.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.references.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.destinations.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.rules.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.shifts.handler") -- disabled
-appendaction("shipouts", "normalizers", "structures.tags.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") -- disabled
-appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled
-appendaction("shipouts", "normalizers", "nodes.handlers.alignbackgrounds") -- disabled
-------------("shipouts", "normalizers", "nodes.handlers.export") -- disabled
-appendaction("shipouts", "normalizers", "typesetters.rubies.attach") -- disabled
-
-appendaction("shipouts", "finishers", "nodes.visualizers.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.transparencies.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.colorintents.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.negatives.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.effects.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.viewerlayers.handler") -- disabled
-
---maybe integrate relocate and families
-
-appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nohead")
-
-appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nohead") -- always on (maybe disabled)
-appendaction("math", "normalizers", "noads.handlers.variants", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.families", nil, "nohead") -- always on
-
-appendaction("math", "normalizers", "noads.handlers.render", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.fixscripts",nil, "nohead") -- * first-- always on
-appendaction("math", "normalizers", "noads.handlers.domains", nil, "nohead") -- * last -- disabled
-appendaction("math", "normalizers", "noads.handlers.autofences",nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on
-------------("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled
-
-appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on
-------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled
-appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late)
-appendaction("math", "builders", "noads.handlers.makeup", nil, "nohead") -- disabled (has to happen last)
-appendaction("math", "builders", "noads.handlers.align", nil, "nohead")
-
-appendaction("finalizers", "lists", "typesetters.paragraphs.normalize") -- moved here
-appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled
-appendaction("finalizers", "lists", "builders.paragraphs.keeptogether")
-------------("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo
-appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental
-appendaction("finalizers", "lists", "builders.paragraphs.tag")
-
--- the next can also be in contributers normalizers (when we remove the loop in the handler)
-
-appendaction("finalizers", "lists", "nodes.linefillers.handler")
-
-appendaction("contributers", "normalizers", "nodes.handlers.flattenline")
-appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds")
-
--- still experimental
-
-appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -- disabled
-appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate")
-
-appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler") -- last !
-appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here !
-
-------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler")
-appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler")
-appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here !
-
--- experimental too
-
-appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler")
-appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler")
-
--- rather special (this might get hardcoded):
-
-prependaction("processors", "before", "nodes.properties.attach") -- enabled but optimized for quick abort
-appendaction ("shipouts", "normalizers", "nodes.properties.delayed") -- enabled but optimized for quick abort
-
--- speedup: only kick in when used
-
-disableaction("processors", "typesetters.wrappers.handler")
-disableaction("processors", "languages.replacements.handler")
-disableaction("processors", "typesetters.characteralign.handler")
-disableaction("processors", "scripts.autofontfeature.handler")
-disableaction("processors", "scripts.splitters.handler")
-disableaction("processors", "scripts.injectors.handler") -- was enabled
-disableaction("processors", "fonts.collections.process")
-disableaction("processors", "fonts.checkers.missing")
-disableaction("processors", "chars.handle_breakpoints")
-disableaction("processors", "typesetters.cleaners.handler")
-disableaction("processors", "typesetters.cases.handler")
-disableaction("processors", "typesetters.digits.handler")
-disableaction("processors", "typesetters.breakpoints.handler")
-disableaction("processors", "typesetters.directions.handler")
-disableaction("processors", "languages.words.check")
-disableaction("processors", "typesetters.initials.handler")
-disableaction("processors", "typesetters.firstlines.handler")
-disableaction("processors", "typesetters.spacings.handler")
-disableaction("processors", "typesetters.kerns.handler")
-disableaction("processors", "typesetters.italics.handler")
-disableaction("processors", "languages.visualizediscretionaries")
-disableaction("processors", "nodes.handlers.stripping")
-disableaction("processors", "builders.paragraphs.solutions.splitters.split")
-disableaction("processors", "typesetters.rubies.check")
-disableaction("processors", "typesetters.fontkerns.handler")
-disableaction("processors", "nodes.handlers.flatten")
-disableaction("processors", "typesetters.marksuspects")
-
-disableaction("shipouts", "typesetters.showsuspects")
-disableaction("shipouts", "typesetters.margins.finalhandler")
-disableaction("shipouts", "builders.paragraphs.expansion.trace")
-disableaction("shipouts", "typesetters.alignments.handler")
-disableaction("shipouts", "nodes.rules.handler")
-disableaction("shipouts", "nodes.shifts.handler")
-disableaction("shipouts", "attributes.colors.handler")
-disableaction("shipouts", "attributes.transparencies.handler")
-disableaction("shipouts", "attributes.colorintents.handler")
-disableaction("shipouts", "attributes.effects.handler")
-disableaction("shipouts", "attributes.negatives.handler")
-disableaction("shipouts", "attributes.viewerlayers.handler")
-disableaction("shipouts", "structures.tags.handler")
-disableaction("shipouts", "nodes.visualizers.handler")
-disableaction("shipouts", "nodes.handlers.accessibility")
-disableaction("shipouts", "nodes.handlers.backgrounds")
-disableaction("shipouts", "nodes.handlers.alignbackgrounds")
-disableaction("shipouts", "nodes.references.handler")
-disableaction("shipouts", "nodes.destinations.handler")
--------------("shipouts", "nodes.handlers.export")
-disableaction("shipouts", "typesetters.rubies.attach")
-
-disableaction("finalizers", "typesetters.margins.localhandler")
-disableaction("finalizers", "builders.paragraphs.keeptogether")
-disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize")
--------------("finalizers", "nodes.handlers.graphicvadjust") -- sort of obsolete
-disableaction("finalizers", "builders.paragraphs.tag")
-disableaction("finalizers", "nodes.linefillers.handler")
-
-disableaction("contributers","nodes.handlers.flattenline")
-disableaction("contributers","nodes.handlers.textbackgrounds")
-
-disableaction("math", "noads.handlers.showtree")
-disableaction("math", "noads.handlers.tags")
-disableaction("math", "noads.handlers.italics")
-disableaction("math", "noads.handlers.collapse")
-disableaction("math", "noads.handlers.kernpairs")
-disableaction("math", "noads.handlers.domains")
-disableaction("math", "noads.handlers.classes")
-disableaction("math", "noads.handlers.autofences")
-disableaction("math", "noads.handlers.makeup")
-disableaction("math", "typesetters.directions.processmath")
-
-disableaction("mvlbuilders", "typesetters.margins.globalhandler")
-disableaction("mvlbuilders", "nodes.handlers.migrate")
-disableaction("mvlbuilders", "typesetters.checkers.handler")
-disableaction("mvlbuilders", "builders.profiling.pagehandler")
-
--------------("vboxbuilders","typesetters.margins.localhandler")
-disableaction("vboxbuilders","typesetters.checkers.handler")
-disableaction("vboxbuilders","builders.profiling.vboxhandler")
+------------("processors", "before", "nodes.properties.attach", 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", "builders.kernel.cleanup", nil, "nut", "enabled" )
+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", "typesetters.showsuspects", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler", nil, "nut", "disabled" )
+------------("shipouts", "normalizers", "nodes.handlers.cleanuppage", 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", "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.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", "typesetters.paragraphs.normalize", nil, "nut", "enabled" ) -- "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("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")
@@ -253,8 +161,12 @@ 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")
@@ -265,15 +177,14 @@ freezegroup("vboxbuilders", "normalizers")
freezegroup("math", "normalizers")
freezegroup("math", "builders")
--- new: disabled here
+freezegroup("everypar", "normalizers")
-disableaction("processors", "builders.kernel.ligaturing")
-disableaction("processors", "builders.kernel.kerning")
+-- new: disabled here
directives.register("nodes.basepass", function(v)
if v then
- enableaction("processors", "builders.kernel.ligaturing")
- enableaction("processors", "builders.kernel.kerning")
+ enableaction("processors", "builders.kernel.ligaturing")
+ enableaction("processors", "builders.kernel.kerning")
else
disableaction("processors", "builders.kernel.ligaturing")
disableaction("processors", "builders.kernel.kerning")
diff --git a/Master/texmf-dist/tex/context/base/mkiv/toks-aux.mkiv b/Master/texmf-dist/tex/context/base/mkiv/toks-aux.mkiv
new file mode 100644
index 00000000000..5b43de596f3
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/toks-aux.mkiv
@@ -0,0 +1,51 @@
+%D \module
+%D [ file=toks-aux,
+%D version=2018.11.29,
+%D title=\CONTEXT\ Token Support,
+%D subtitle=Helpers,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Token Support / Helpers}
+
+\unprotect
+
+\installcorenamespace {tokenlist}
+
+\unexpanded\def\definetokenlist[#1]%
+ {\ifcsname\??tokenlist#1\endcsname
+ \global\lastnamedcs\emptytoks
+ \else
+ \expandafter\newtoks\csname\??tokenlist#1\endcsname
+ \fi}
+
+\unexpanded\def\starttokenlist[#1]#2\stoptokenlist
+ {\ifcsname\??tokenlist#1\endcsname \else
+ \expandafter\newtoks\csname\??tokenlist#1\endcsname
+ \fi
+ \toksapp\lastnamedcs{#2}}
+
+\let\stoptokenlist\relax
+
+\def\gettokenlist[#1]%
+ {\ifcsname\??tokenlist#1\endcsname
+ \the\lastnamedcs
+ \fi}
+
+\def\settokenlist[#1]#2%
+ {\ifcsname\??tokenlist#1\endcsname \else
+ \expandafter\newtoks\csname\??tokenlist#1\endcsname
+ \fi
+ \toksapp\lastnamedcs{#2}}
+
+\unexpanded\def\resettokenlist[#1]%
+ {\ifcsname\??tokenlist#1\endcsname
+ \lastnamedcs\emptytoks
+ \fi}
+
+\protect
diff --git a/Master/texmf-dist/tex/context/base/mkiv/toks-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/toks-ini.lua
index 15e5df267ef..43e2d80a32b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/toks-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/toks-ini.lua
@@ -18,41 +18,15 @@ local printtable = table.print
local concat = table.concat
local format = string.format
-if setinspector then
+if token.commands then
- local istoken = token.is_token
- local simple = { letter = "letter", other_char = "other" }
+ local commands = token.commands()
- local function astable(t)
- if t and istoken(t) then
- local cmdname = t.cmdname
- local simple = simple[cmdname]
- if simple then
- return {
- category = simple,
- character = utfchar(t.mode) or nil,
- }
- else
- return {
- command = t.command,
- id = t.id,
- tok = t.tok,
- csname = t.csname,
- active = t.active,
- expandable = t.expandable,
- protected = t.protected,
- mode = t.mode,
- index = t.index,
- cmdname = cmdname,
- }
- end
- end
- end
+ tokens.commands = utilities.storage.allocate(table.swapped(commands,commands))
- tokens.istoken = istoken
- tokens.astable = astable
+else
- setinspector("token",function(v) if istoken(v) then printtable(astable(v),tostring(v)) return true end end)
+ tokens.commands = { }
end
@@ -69,6 +43,8 @@ local scan_token = token.scan_token
local scan_word = token.scan_word
local scan_number = token.scan_number
local scan_csname = token.scan_csname
+local scan_real = token.scan_real
+local scan_float = token.scan_float
local get_next = token.get_next
@@ -77,25 +53,26 @@ local get_macro = token.get_macro
local get_meaning = token.get_meaning
local get_cmdname = token.get_cmdname
local set_char = token.set_char
+local set_lua = token.set_lua
+
local create_token = token.create
+local new_token = token.new
+local is_defined = token.is_defined
+local is_token = token.is_token
-if not set_char then -- for a while
- local contextsprint = context.sprint
- local ctxcatcodes = catcodes.numbers.ctxcatcodes
- set_char = function(n,u) contextsprint(ctxcatcodes,format("\\chardef\\%s=%s",n,u)) end
-end
+if not is_defined then
+
+ is_defined = function(name)
+ return get_cmdname(create_token(name)) ~= "undefined_cs"
+ end
-function tokens.defined(name)
- return get_cmdname(create_token(name)) ~= "undefined_cs"
end
--- set_macro = function(k,v,g)
--- if g == "global" then
--- context.setgvalue(k,v or '')
--- else
--- context.setvalue(k,v or '')
--- end
--- end
+tokens.new = new_token
+tokens.create = create_token
+tokens.istoken = is_token
+tokens.isdefined = is_defined
+tokens.defined = is_defined
local bits = {
escape = 0x00000001, -- 2^00
@@ -240,6 +217,8 @@ tokens.scanners = { -- these expand
glue = scan_glue,
skip = scan_glue,
integer = scan_int,
+ real = scan_real,
+ float = scan_float,
count = scan_int,
string = scan_string,
argument = scan_argument,
@@ -268,6 +247,7 @@ tokens.getters = { -- these don't expand
tokens.setters = {
macro = set_macro,
char = set_char,
+ lua = set_lua,
count = tex.setcount,
dimen = tex.setdimen,
skip = tex.setglue,
@@ -297,3 +277,48 @@ tokens.setters = {
-- /* unsave_tex_scanner(texstate); */
-- return 1;
-- }
+
+if setinspector then
+
+ local simple = { letter = "letter", other_char = "other" }
+
+ local function astable(t)
+ if t and is_token(t) then
+ local cmdname = t.cmdname
+ local simple = simple[cmdname]
+ if simple then
+ return {
+ category = simple,
+ character = utfchar(t.mode) or nil,
+ }
+ else
+ return {
+ command = t.command,
+ id = t.id,
+ tok = t.tok,
+ csname = t.csname,
+ active = t.active,
+ expandable = t.expandable,
+ protected = t.protected,
+ mode = t.mode,
+ index = t.index,
+ cmdname = cmdname,
+ }
+ end
+ end
+ end
+
+ tokens.astable = astable
+
+ setinspector("token",function(v) local t = astable(v) if t then printtable(t,tostring(v)) return true end end)
+
+end
+
+tokens.cache = table.setmetatableindex(function(t,k)
+ if not is_defined(k) then
+ set_macro(k,"","global")
+ end
+ local v = create_token(k)
+ t[k] = v
+ return v
+end)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/toks-ini.mkiv b/Master/texmf-dist/tex/context/base/mkiv/toks-ini.mkiv
index 9d3375432c8..af22d53933e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/toks-ini.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/toks-ini.mkiv
@@ -15,11 +15,6 @@
\unprotect
-\newtoks\t_get_macro % will go away
-
\registerctxluafile{toks-ini}{}
-\registerctxluafile{toks-scn}{}
-\registerctxluafile{cldf-scn}{}
-\registerctxluafile{cldf-stp}{}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/toks-scn.lua b/Master/texmf-dist/tex/context/base/mkiv/toks-scn.lua
index fe32a1de4d8..f73ecc86c50 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/toks-scn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/toks-scn.lua
@@ -106,7 +106,40 @@ local function scanconditional()
return nil
end
+local function scantable(t,data)
+ if not data then
+ data = { }
+ end
+ local wrapped = scanopen()
+ while true do
+ local key = scanword()
+ if key then
+ local get = t[key]
+ if get then
+ data[key] = get()
+ else
+ -- catch all we can get
+ end
+ else
+ break
+ end
+ end
+ if wrapped then
+ scanclose()
+ end
+ return data
+end
+
+function tokens.constant(s)
+ if type(s) == "string" then
+ return "'" .. s .. "'"
+ else
+ return s
+ end
+end
+
scanners.list = scanlist
+scanners.table = scantable
scanners.conditional = scanconditional
local shortcuts = {
@@ -118,6 +151,7 @@ local shortcuts = {
scanstring = scanstring,
scaninteger = scaninteger,
scannumber = scannumber,
+ scantable = scantable,
scankeyword = scankeyword,
scankeywordcs = scankeywordcs,
scanword = scanword,
@@ -254,6 +288,8 @@ local presets = {
["8 strings"] = { "string", "string", "string", "string", "string", "string", "string", "string" },
}
+tokens.presets = presets
+
function tokens.compile(specification)
local f = { }
local n = 0
@@ -319,7 +355,7 @@ function tokens.compile(specification)
return c
end
end
- local p = t and presets[t]
+ local p = t and presets[t] -- already done in implement
if p then
t = p
end
@@ -460,35 +496,3 @@ end
-- }
--
-- os.exit()
-
-function tokens.scantable(t,data)
- if not data then
- data = { }
- end
- local wrapped = scanopen()
- while true do
- local key = scanword()
- if key then
- local get = t[key]
- if get then
- data[key] = get()
- else
- -- catch all we can get
- end
- else
- break
- end
- end
- if wrapped then
- scanclose()
- end
- return data
-end
-
-function tokens.constant(s)
- if type(s) == "string" then
- return "'" .. s .. "'"
- else
- return s
- end
-end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/toks-scn.mkiv b/Master/texmf-dist/tex/context/base/mkiv/toks-scn.mkiv
new file mode 100644
index 00000000000..49edf0c242a
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/toks-scn.mkiv
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=toks-ini,
+%D version=2007.03.03,
+%D title=\CONTEXT\ Token Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Token Support / Scanners}
+
+\unprotect
+
+\registerctxluafile{toks-scn}{}
+\registerctxluafile{cldf-scn}{}
+\registerctxluafile{cldf-stp}{}
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-deb.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-deb.lua
index 03df8682541..95f3052fe6f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-deb.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-deb.lua
@@ -220,7 +220,13 @@ function tracers.printerror(specification)
else
report_nl()
if luaerrorline then
- report("lua error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror)
+ if linenumber == 0 or not filename or filename == "" then
+ print("\nfatal lua error:\n\n",lastluaerror,"\n")
+ os.exit(1)
+ return
+ else
+ report("lua error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror)
+ end
elseif lastmpserror then
report("mp error on line %s in file %s:\n\n%s",linenumber,filename,lastmpserror)
else
@@ -341,22 +347,25 @@ directives.register("system.showerror", lmx.overloaderror)
-- trace_calls(n)
-- end) -- indirect is needed for nilling
-local editor = [[scite "-open:%filename%" -goto:%linenumber%]]
-
-directives.register("system.editor",function(v)
- editor = v
-end)
+-- Obsolete ... not that usefull as normally one runs from an editor and
+-- when run unattended it makes no sense either.
-callback.register("call_edit",function(filename,linenumber)
- if editor then
- editor = gsub(editor,"%%s",filename)
- editor = gsub(editor,"%%d",linenumber)
- editor = gsub(editor,"%%filename%%",filename)
- editor = gsub(editor,"%%linenumber%%",linenumber)
- logs.report("system","starting editor: %s",editor)
- os.execute(editor)
- end
-end)
+-- local editor = [[scite "-open:%filename%" -goto:%linenumber%]]
+--
+-- directives.register("system.editor",function(v)
+-- editor = v
+-- end)
+--
+-- callback.register("call_edit",function(filename,linenumber)
+-- if editor then
+-- editor = gsub(editor,"%%s",filename)
+-- editor = gsub(editor,"%%d",linenumber)
+-- editor = gsub(editor,"%%filename%%",filename)
+-- editor = gsub(editor,"%%linenumber%%",linenumber)
+-- logs.report("system","starting editor: %s",editor)
+-- os.execute(editor)
+-- end
+-- end)
implement { name = "showtrackers", actions = trackers.show }
implement { name = "enabletrackers", actions = trackers.enable, arguments = "string" }
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua
index 439e8b2dc7c..7a5c35fd5fa 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua
@@ -82,9 +82,13 @@ local seconds = function(n) return n or 0 end
--
-- end
-local function starttiming(instance)
+local function starttiming(instance,reset)
local timer = timers[instance or "notimer"]
local it = timer.timing
+ if reset then
+ it = 0
+ timer.loadtime = 0
+ end
if it == 0 then
timer.starttime = ticks()
if not timer.loadtime then
@@ -123,6 +127,24 @@ local function elapsed(instance)
end
end
+local function currenttime(instance)
+ if type(instance) == "number" then
+ return instance
+ else
+ local timer = timers[instance or "notimer"]
+ local it = timer.timing
+ if it > 1 then
+ -- whatever
+ else
+ local starttime = timer.starttime
+ if starttime and starttime > 0 then
+ return seconds(timer.loadtime + ticks() - starttime)
+ end
+ end
+ return 0
+ end
+end
+
local function elapsedtime(instance)
return format("%0.3f",elapsed(instance))
end
@@ -141,6 +163,7 @@ statistics.hastiming = hastiming
statistics.resettiming = resettiming
statistics.starttiming = starttiming
statistics.stoptiming = stoptiming
+statistics.currenttime = currenttime
statistics.elapsed = elapsed
statistics.elapsedtime = elapsedtime
statistics.elapsedindeed = elapsedindeed
@@ -229,17 +252,26 @@ end
function statistics.runtime()
stoptiming(statistics)
- -- stoptiming(statistics) -- somehow we can start the timer twice, but where
- return statistics.formatruntime(elapsedtime(statistics))
+ -- stoptiming(statistics) -- somehow we can start the timer twice, but where
+ local runtime = lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report = logs.reporter("system")
-function statistics.timed(action)
+function statistics.timed(action,all)
starttiming("run")
action()
stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+ local runtime = tonumber(elapsedtime("run"))
+ if all then
+ local alltime = tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
+ if alltime and alltime > 0 then
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ return
+ end
+ end
+ report("total runtime: %0.3f seconds",runtime)
end
-- goodie
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-jus.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-jus.lua
index e7a030257aa..aec1844ec5a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-jus.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-jus.lua
@@ -15,7 +15,6 @@ local a_alignstate = attributes.private("alignstate")
local a_justification = attributes.private("justification")
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getfield = nuts.getfield
local getlist = nuts.getlist
@@ -26,8 +25,9 @@ local setlink = nuts.setlink
local getwidth = nuts.getwidth
local findtail = nuts.tail
-local traverse_id = nuts.traverse_id
-local list_dimensions = nuts.dimensions
+local nexthlist = nuts.traversers.hlist
+
+local getdimensions = nuts.dimensions
local copy_list = nuts.copy_list
local tracedrule = nodes.tracers.pool.nuts.rule
@@ -77,14 +77,14 @@ trackers.register("visualizers.justification", function(v)
end)
function checkers.handler(head)
- for current in traverse_id(hlist_code,tonut(head)) do
+ for current in nexthlist, head do
if getattr(current,a_justification) == 1 then
setattr(current,a_justification,0) -- kind of reset
local width = getwidth(current)
if width > 0 then
local list = getlist(current)
if list then
- local naturalwidth, naturalheight, naturaldepth = list_dimensions(list)
+ local naturalwidth, naturalheight, naturaldepth = getdimensions(list)
local delta = naturalwidth - width
if naturalwidth == 0 or delta == 0 then
-- special box
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-log.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-log.lua
index 1471bd4c7f2..206af566803 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-log.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-log.lua
@@ -405,6 +405,15 @@ if runningtex then
setlogfile = ignore
settimedlog = ignore
+ -- settimedlog = function()
+ -- local localtime = os.localtime
+ -- local writeline = write_nl
+ -- write_nl = function(f,...)
+ -- writeline(f,localtime() .. " | " .. concat { ... })
+ -- end
+ -- settimedlog = ignore
+ -- end
+
else
local report_yes, subreport_yes, status_yes
@@ -758,7 +767,7 @@ if tex then
local report = logs.reporter("pages") -- not needed but saves checking when we grep for it
local texgetcount = tex and tex.getcount
- local real, user, sub
+ local real, user, sub = 0, 0, 0
function logs.start_page_number()
real = texgetcount("realpageno")
@@ -766,47 +775,35 @@ if tex then
sub = texgetcount("subpageno")
end
- local timing = false
- local starttime = nil
- local lasttime = nil
+ local timing = false
+ local lasttime = nil
trackers.register("pages.timing", function(v) -- only for myself (diagnostics)
- starttime = os.clock() -- todo: use other timer
- timing = true
+ timing = ""
end)
function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average
if timing then
- local elapsed, average
- local stoptime = os.clock()
+ local elapsed = statistics.currenttime(statistics)
+ local average, page
if not lasttime or real < 2 then
- elapsed = stoptime
- average = stoptime
- starttime = stoptime
- else
- elapsed = stoptime - lasttime
- average = (stoptime - starttime) / (real - 1)
- end
- lasttime = stoptime
- if real <= 0 then
- report("flushing page, time %0.04f / %0.04f",elapsed,average)
- elseif user <= 0 then
- report("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average)
- elseif sub <= 0 then
- report("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average)
+ average = elapsed
+ page = elapsed
else
- report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
+ average = elapsed / (real - 1)
+ page = elapsed - lasttime
end
+ lasttime = elapsed
+ timing = formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
+ end
+ if real <= 0 then
+ report("flushing page%s",timing)
+ elseif user <= 0 then
+ report("flushing realpage %s%s",real,timing)
+ elseif sub <= 0 then
+ report("flushing realpage %s, userpage %s%s",real,user,timing)
else
- if real <= 0 then
- report("flushing page")
- elseif user <= 0 then
- report("flushing realpage %s",real)
- elseif sub <= 0 then
- report("flushing realpage %s, userpage %s",real,user)
- else
- report("flushing realpage %s, userpage %s, subpage %s",real,user,sub)
- end
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
end
logs.flush()
end
@@ -1031,7 +1028,7 @@ end
if tex and tex.error then
function logs.texerrormessage(...) -- for the moment we put this function here
- tex.error(format(...), { })
+ tex.error(format(...))
end
else
function logs.texerrormessage(...)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua
index 56291f8c83d..03f0a67d107 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua
@@ -15,13 +15,13 @@ local concat = table.concat
local nuts = nodes.nuts
local tonut = nuts.tonut
-local getfield = nuts.getfield
local getid = nuts.getid
local getnext = nuts.getnext
local getlist = nuts.getlist
-local getfont = nuts.getfont
-local getchar = nuts.getchar
local getwidth = nuts.getwidth
+local getexpansion = nuts.getexpansion
+
+local isglyph = nuts.isglyph
local nodecodes = nodes.nodecodes
local hlist_code = nodecodes.hlist
@@ -63,23 +63,23 @@ local function colorize(n)
-- tricky: the built-in method creates dummy fonts and the last line normally has the
-- original font and that one then has ex.auto set
while n do
- local id = getid(n)
- if id == glyph_code then
- local ne = getfield(n,"expansion_factor")
+ local char, id = isglyph(n)
+ if char then
+ local ne = getexpansion(n)
if ne == 0 then
if length > 0 then flush() end
setnodecolor(n,"hz:zero")
else
- local f = getfont(n)
- if f ~= font then
+ -- id == font
+ if id ~= font then
if length > 0 then
flush()
end
- local pf = parameters[f]
+ local pf = parameters[id]
local ex = pf.expansion
if ex and ex.auto then
size = pf.size
- font = f -- save lookups
+ font = id -- save lookups
else
size = false
end
@@ -100,7 +100,7 @@ local function colorize(n)
end
if trace_verbose then
length = length + 1
- list[length] = utfchar(getchar(n))
+ list[length] = utfchar(char)
width = width + getwidth(n) -- no kerning yet
end
end
@@ -109,7 +109,10 @@ local function colorize(n)
if length > 0 then
flush()
end
- colorize(getlist(n),flush)
+ local list = getlist(n)
+ if list then
+ colorize(list,flush)
+ end
else -- nothing to show on kerns
if length > 0 then
flush()
@@ -125,7 +128,7 @@ end
builders.paragraphs.expansion = builders.paragraphs.expansion or { }
function builders.paragraphs.expansion.trace(head)
- colorize(tonut(head),true)
+ colorize(head,true)
return head
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-set.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-set.lua
index 530915fe0a2..6311d638296 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-set.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-set.lua
@@ -396,3 +396,20 @@ if texconfig then
directives.register("luatex.stacksize", function(v) set("stack_size",v) end)
end
+
+-- for now here:
+
+local data = table.setmetatableindex("table")
+
+updaters = {
+ register = function(what,f)
+ local d = data[what]
+ d[#d+1] = f
+ end,
+ apply = function(what,...)
+ local d = data[what]
+ for i=1,#d do
+ d[i](...)
+ end
+ end,
+}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua b/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
index 0e37752db36..b61dadb515a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
@@ -28,8 +28,6 @@ local compactfloat = number.compactfloat
-- todo: inline concat (more efficient)
-- todo: tags can also be numbers (just add to hash)
--- todo: dir and localpar nodes
-
local nodecodes = nodes.nodecodes
local nuts = nodes.nuts
@@ -47,12 +45,10 @@ local setattr = nuts.setattr
local setwidth = nuts.setwidth
local setshift = nuts.setshift
-local getfield = nuts.getfield
local getid = nuts.getid
local getfont = nuts.getfont
local getattr = nuts.getattr
local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
local getbox = nuts.getbox
local getlist = nuts.getlist
local getleader = nuts.getleader
@@ -63,22 +59,26 @@ local getdisc = nuts.getdisc
local getwhd = nuts.getwhd
local getkern = nuts.getkern
local getpenalty = nuts.getpenalty
-local getdir = nuts.getdir
local getwidth = nuts.getwidth
local getdepth = nuts.getdepth
local getshift = nuts.getshift
+local getexpansion = nuts.getexpansion
+
+local isglyph = nuts.isglyph
local hpack_nodes = nuts.hpack
local vpack_nodes = nuts.vpack
local copy_list = nuts.copy_list
+local copy_node = nuts.copy_node
local flush_node_list = nuts.flush_list
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local traverse_nodes = nuts.traverse
local apply_to_nodes = nuts.apply
local find_tail = nuts.tail
local effectiveglue = nuts.effective_glue
+local nextnode = nuts.traversers.node
+
local hpack_string = nuts.typesetters.tohpack
local texgetattribute = tex.getattribute
@@ -188,13 +188,16 @@ end
-- we can preset a bunch of bits
-local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local outlinerule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
-local function enable()
+local function initialize()
+ --
if not usedfont then
-- we use a narrow monospaced font -- infofont ?
visualizers.setfont(fonts.definers.define { name = "lmmonoltcond10regular", size = tex.sp("4pt") })
end
+ --
for mode, value in next, modes do
local tag = formatters["v_%s"](mode)
attributes.viewerlayers.define {
@@ -225,14 +228,25 @@ local function enable()
l_line = layers.line
l_space = layers.space
l_depth = layers.depth
- enableaction("shipouts","nodes.visualizers.handler")
- report_visualize("enabled")
- enabled = true
- tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end
--
if not userrule then
userrule = nuts.rules.userrule
end
+ --
+ if not outlinerule then
+ outlinerule = nuts.pool.outlinerule
+ end
+ initialize = false
+end
+
+local function enable()
+ if initialize then
+ initialize()
+ end
+ enableaction("shipouts","nodes.visualizers.handler")
+ report_visualize("enabled")
+ enabled = true
+ tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end
end
local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in
@@ -454,7 +468,7 @@ local fontkern, italickern do
local function somekern(head,current,cache,color,layer)
local width = getkern(current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
local kern = width + extra
local info = cache[kern]
if not info then
@@ -495,7 +509,7 @@ local glyphexpansion do
local f_cache = caches["glyphexpansion"]
glyphexpansion = function(head,current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
if extra ~= 0 then
extra = extra / 1000
local info = f_cache[extra]
@@ -529,7 +543,7 @@ local kernexpansion do
local f_cache = caches["kernexpansion"]
kernexpansion = function(head,current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
if extra ~= 0 then
extra = extra / 1000
local info = f_cache[extra]
@@ -564,29 +578,17 @@ local whatsit do
local w_cache = caches["whatsit"]
local tags = {
- open = "FIC",
- write = "FIW",
- close = "FIC",
- special = "SPE",
- latelua = "LUA",
- savepos = "POS",
- userdefined = "USR",
- -- backend stuff
- pdfliteral = "PDF",
- pdfrefobj = "PDF",
- pdfannot = "PDF",
- pdfstartlink = "PDF",
- pdfendlink = "PDF",
- pdfdest = "PDF",
- pdfthread = "PDF",
- pdfstartthread = "PDF",
- pdfendthread = "PDF",
- pdfthreaddata = "PDF",
- pdflinkdata = "PDF",
- pdfcolorstack = "PDF",
- pdfsetmatrix = "PDF",
- pdfsave = "PDF",
- pdfrestore = "PDF",
+ open = "OPN",
+ write = "WRI",
+ close = "CLS",
+ special = "SPE",
+ latelua = "LUA",
+ savepos = "POS",
+ userdefined = "USR",
+ literal = "LIT",
+ setmatrix = "MAT",
+ save = "SAV",
+ restore = "RES",
}
whatsit = function(head,current)
@@ -700,40 +702,11 @@ local ruledbox do
local wd, ht, dp = getwhd(current)
if wd ~= 0 then
local shift = getshift(current)
- local dir = getdir(current)
- -- if dir == "LTL" or dir == "RRT" then
- -- wd, ht, dp = ht + dp, wd, 0
- -- end
local next = getnext(current)
local prev = previous
- -- local prev = getprev(current) -- prev can be wrong in math mode < 0.78.3
setboth(current)
local linewidth = emwidth/fraction
local size = 2*linewidth
- -- local baseline, baseskip
- -- if dp ~= 0 and ht ~= 0 then
- -- if wd > 20*linewidth then
- -- local targetsize = wd - size
- -- baseline = b_cache[targetsize]
- -- if not baseline then
- -- -- due to an optimized leader color/transparency we need to set the glue node in order
- -- -- to trigger this mechanism
- -- local leader = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size))
- -- leader = hpack_nodes(leader)
- -- baseline = new_glue(0,65536,0,2,0)
- -- setleader(baseline,leader)
- -- setsubtype(baseline,cleaders_code)
- -- setlisttransparency(baseline,c_text)
- -- baseline = hpack_nodes(baseline,targetsize)
- -- b_cache[targetsize] = baseline
- -- end
- -- baseline = copy_list(baseline)
- -- baseskip = new_kern(-wd+linewidth)
- -- else
- -- baseline = new_rule(wd-size,linewidth,0)
- -- baseskip = new_kern(-wd+size)
- -- end
- -- end
local this
if not simple then
this = b_cache[what]
@@ -746,22 +719,9 @@ local ruledbox do
end
end
-- we need to trigger the right mode (else sometimes no whatits)
- -- local info = setlink(
- -- this and copy_list(this) or nil,
- -- new_rule(linewidth,ht,dp),
- -- new_rule(wd-size,-dp+linewidth,dp),
- -- new_rule(linewidth,ht,dp),
- -- new_kern(-wd+linewidth),
- -- new_rule(wd-size,ht,-ht+linewidth),
- -- baseskip,
- -- baseskip and baseline or nil
- -- )
- --
- -- userrules:
- --
local info = setlink(
this and copy_list(this) or nil,
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -772,7 +732,7 @@ local ruledbox do
)
--
setlisttransparency(info,c_text)
- info = new_hlist(info)
+ info = new_hlist(info) -- important
--
setattr(info,a_layer,layer)
if vertical then
@@ -846,56 +806,16 @@ local ruledglyph do
ruledglyph = function(head,current,previous) -- wrong for vertical glyphs
local wd = getwidth(current)
- -- local wd = chardata[getfont(current)][getchar(current)].width
if wd ~= 0 then
local wd, ht, dp = getwhd(current)
- -- local dir = getdir(current)
- -- if dir == "LTL" or dir = "RTT" then
- -- wd, ht, dp = ht + dp, wd, 0
- -- end
local next = getnext(current)
local prev = previous
setboth(current)
local linewidth = emwidth/(2*fraction)
local info
--
- -- original
- --
- -- local baseline
- -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then
- -- baseline = new_rule(wd-2*linewidth,linewidth,0)
- -- end
- -- local doublelinewidth = 2*linewidth
- -- -- could be a pdf rule (or a user rule now)
- -- info = setlink(
- -- new_rule(linewidth,ht,dp),
- -- new_rule(wd-doublelinewidth,-dp+linewidth,dp),
- -- new_rule(linewidth,ht,dp),
- -- new_kern(-wd+linewidth),
- -- new_rule(wd-doublelinewidth,ht,-ht+linewidth),
- -- new_kern(-wd+doublelinewidth),
- -- baseline
- -- )
- --
- -- experiment with subtype outline
- --
- -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then
- -- baseline = new_rule(wd,linewidth/2,0)
- -- end
- -- local r = new_rule(wd-linewidth,ht-linewidth/4,dp-linewidth/4)
- -- setsubtype(r,nodes.rulecodes.outline)
- -- setfield(r,"transform",linewidth)
- -- info = setlink(
- -- new_kern(linewidth/4),
- -- r,
- -- new_kern(-wd+linewidth/2),
- -- baseline
- -- )
- --
- -- userrules:
- --
info = setlink(
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -905,7 +825,8 @@ local ruledglyph do
new_kern(-wd)
)
--
- local char = chardata[getfont(current)][getchar(current)]
+ local c, f = isglyph(current)
+ local char = chardata[f][c]
if char and type(char.unicode) == "table" then -- hackery test
setlistcolor(info,c_ligature)
setlisttransparency(info,c_ligature_d)
@@ -942,19 +863,22 @@ end
local ruledglue do
- local gluecodes = nodes.gluecodes
- local cleaders_code = gluecodes.cleaders
- local userskip_code = gluecodes.userskip
- local space_code = gluecodes.spaceskip
- local xspace_code = gluecodes.xspaceskip
- local leftskip_code = gluecodes.leftskip
- local rightskip_code = gluecodes.rightskip
+ local gluecodes = nodes.gluecodes
+ local leadercodes = nodes.gluecodes
+
+ local userskip_code = gluecodes.userskip
+ local spaceskip_code = gluecodes.spaceskip
+ local xspaceskip_code = gluecodes.xspaceskip
+ local leftskip_code = gluecodes.leftskip
+ local rightskip_code = gluecodes.rightskip
+
+ local cleaders_code = leadercodes.cleaders
local g_cache_v = caches["vglue"]
local g_cache_h = caches["hglue"]
local tags = {
- -- userskip = "US",
+ -- [gluecodes.userskip] = "US",
[gluecodes.lineskip] = "LS",
[gluecodes.baselineskip] = "BS",
[gluecodes.parskip] = "PS",
@@ -973,12 +897,12 @@ local ruledglue do
[gluecodes.thinmuskip] = "MS",
[gluecodes.medmuskip] = "MM",
[gluecodes.thickmuskip] = "ML",
- [gluecodes.leaders] = "NL",
- [gluecodes.cleaders] = "CL",
- [gluecodes.xleaders] = "XL",
- [gluecodes.gleaders] = "GL",
- -- true = "VS",
- -- false = "HS",
+ [leadercodes.leaders] = "NL",
+ [leadercodes.cleaders] = "CL",
+ [leadercodes.xleaders] = "XL",
+ [leadercodes.gleaders] = "GL",
+ -- true = "VS",
+ -- false = "HS",
}
-- we sometimes pass previous as we can have issues in math (not watertight for all)
@@ -991,7 +915,7 @@ local ruledglue do
if info then
-- print("glue hit")
else
- if subtype == space_code or subtype == xspace_code then
+ if subtype == spaceskip_code or subtype == xspaceskip_code then
info = sometext(amount,l_glue,c_space)
elseif subtype == leftskip_code or subtype == rightskip_code then
info = sometext(amount,l_glue,c_skip_a)
@@ -1018,7 +942,7 @@ local ruledglue do
-- ruledspace = function(head,current,parent)
-- local subtype = getsubtype(current)
- -- if subtype == space_code or subtype == xspace_code then
+ -- if subtype == spaceskip_code or subtype == xspaceskip_code then
-- local width = effectiveglue(current,parent)
-- local amount = formatters["%s:%0.3f"](tags[subtype] or "HS",width*pt_factor)
-- local info = g_cache_h[amount]
@@ -1041,10 +965,10 @@ local ruledglue do
ruledspace = function(head,current,parent)
local subtype = getsubtype(current)
- if subtype == space_code or subtype == xspace_code then -- not yet all space
+ if subtype == spaceskip_code or subtype == xspaceskip_code then -- not yet all space
local width = effectiveglue(current,parent)
local info
- if subtype == space_code then
+ if subtype == spaceskip_code then
info = g_cache_s[width]
if not info then
info = someblob("SP",l_glue,c_space,nil,width)
@@ -1179,24 +1103,26 @@ end
do
- local disc_code = nodecodes.disc
- local kern_code = nodecodes.kern
- local glyph_code = nodecodes.glyph
- local glue_code = nodecodes.glue
- local penalty_code = nodecodes.penalty
- local whatsit_code = nodecodes.whatsit
- local user_code = nodecodes.user
- local math_code = nodecodes.math
- local hlist_code = nodecodes.hlist
- local vlist_code = nodecodes.vlist
-
- local kerncodes = nodes.kerncodes
- local font_kern_code = kerncodes.fontkern
- local italic_kern_code = kerncodes.italiccorrection
- ----- user_kern_code = kerncodes.userkern
-
- local listcodes = nodes.listcodes
- local line_code = listcodes.line
+ local disc_code = nodecodes.disc
+ local kern_code = nodecodes.kern
+ local glyph_code = nodecodes.glyph
+ local glue_code = nodecodes.glue
+ local penalty_code = nodecodes.penalty
+ local whatsit_code = nodecodes.whatsit
+ local user_code = nodecodes.user
+ local math_code = nodecodes.math
+ local hlist_code = nodecodes.hlist
+ local vlist_code = nodecodes.vlist
+
+ local kerncodes = nodes.kerncodes
+ local fontkern_code = kerncodes.fontkern
+ local italickern_code = kerncodes.italiccorrection
+ ----- userkern_code = kerncodes.userkern
+
+ local listcodes = nodes.listcodes
+ local linelist_code = listcodes.line
+
+ local cache
local function visualize(head,vertical,forced,parent)
local trace_hbox = false
@@ -1225,6 +1151,58 @@ do
local prev_trace_fontkern = nil
local prev_trace_italic = nil
local prev_trace_expansion = nil
+
+ -- local function setthem(t,k)
+ -- local v_trace_hbox = band(k, 1) ~= 0
+ -- local v_trace_vbox = band(k, 2) ~= 0
+ -- local v_trace_vtop = band(k, 4) ~= 0
+ -- local v_trace_kern = band(k, 8) ~= 0
+ -- local v_trace_glue = band(k, 16) ~= 0
+ -- local v_trace_penalty = band(k, 32) ~= 0
+ -- local v_trace_fontkern = band(k, 64) ~= 0
+ -- local v_trace_strut = band(k, 128) ~= 0
+ -- local v_trace_whatsit = band(k, 256) ~= 0
+ -- local v_trace_glyph = band(k, 512) ~= 0
+ -- local v_trace_simple = band(k, 1024) ~= 0
+ -- local v_trace_user = band(k, 2048) ~= 0
+ -- local v_trace_math = band(k, 4096) ~= 0
+ -- local v_trace_italic = band(k, 8192) ~= 0
+ -- local v_trace_origin = band(k, 16384) ~= 0
+ -- local v_trace_discretionary = band(k, 32768) ~= 0
+ -- local v_trace_expansion = band(k, 65536) ~= 0
+ -- local v_trace_line = band(k,131072) ~= 0
+ -- local v_trace_space = band(k,262144) ~= 0
+ -- local v_trace_depth = band(k,524288) ~= 0
+ -- local v = function()
+ -- trace_hbox = v_trace_hbox
+ -- trace_vbox = v_trace_vbox
+ -- trace_vtop = v_trace_vtop
+ -- trace_kern = v_trace_kern
+ -- trace_glue = v_trace_glue
+ -- trace_penalty = v_trace_penalty
+ -- trace_fontkern = v_trace_fontkern
+ -- trace_strut = v_trace_strut
+ -- trace_whatsit = v_trace_whatsit
+ -- trace_glyph = v_trace_glyph
+ -- trace_simple = v_trace_simple
+ -- trace_user = v_trace_user
+ -- trace_math = v_trace_math
+ -- trace_italic = v_trace_italic
+ -- trace_origin = v_trace_origin
+ -- trace_discretionary = v_trace_discretionary
+ -- trace_expansion = v_trace_expansion
+ -- trace_line = v_trace_line
+ -- trace_space = v_trace_space
+ -- trace_depth = v_trace_depth
+ -- end
+ -- t[k] = v
+ -- return v
+ -- end
+ --
+ -- if not cache then
+ -- cache = setmetatableindex(setthem)
+ -- end
+
while current do
local id = getid(current)
local a = forced or getattr(current,a_visual) or unsetvalue
@@ -1254,6 +1232,7 @@ do
trace_space = false
trace_depth = false
else -- dead slow:
+ -- cache[a]()
trace_hbox = band(a, 1) ~= 0
trace_vbox = band(a, 2) ~= 0
trace_vtop = band(a, 4) ~= 0
@@ -1303,14 +1282,14 @@ do
setdisc(current,pre,post,replace)
elseif id == kern_code then
local subtype = getsubtype(current)
- if subtype == font_kern_code then
+ if subtype == fontkern_code then
if trace_fontkern or prev_trace_fontkern then
head, current = fontkern(head,current)
end
if trace_expansion or prev_trace_expansion then
head, current = kernexpansion(head,current)
end
- elseif subtype == italic_kern_code then
+ elseif subtype == italickern_code then
if trace_italic or prev_trace_italic then
head, current = italickern(head,current)
elseif trace_kern then
@@ -1342,7 +1321,7 @@ do
if trace_depth then
ruleddepth(current)
end
- if trace_line and getsubtype(current) == line_code then
+ if trace_line and getsubtype(current) == linelist_code then
head, current = ruledbox(head,current,false,l_line,"L__",trace_simple,previous,trace_origin,parent)
elseif trace_hbox then
head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous,trace_origin,parent)
@@ -1390,9 +1369,9 @@ do
local function handler(head)
if usedfont then
starttiming(visualizers)
- head = visualize(tonut(head),true)
+ head = visualize(head,true)
stoptiming(visualizers)
- return tonode(head), true
+ return head, true
else
return head, false
end
@@ -1433,8 +1412,7 @@ do
}
local function markfonts(list)
- for n in traverse_nodes(list) do
- local id = getid(n)
+ for n, id in nextnode, list do
if id == glyph_code then
local font = getfont(n)
local okay = used[font]
@@ -1507,3 +1485,57 @@ do
}
end
+
+-- Here for now:
+
+do
+
+ local function make(str,forecolor,rulecolor,layer)
+ if initialize then
+ initialize()
+ end
+ local rule = new_rule(emwidth/fraction,exheight,4*exheight)
+ setcolor(rule,rulecolor)
+ settransparency(rule,rulecolor)
+ local info
+ if str == "" then
+ info = new_hlist(rule)
+ else
+ local text = hpack_string(str,usedfont)
+ local list = getlist(text)
+ setlistcolor(list,textcolor)
+ setlisttransparency(list,textcolor)
+ setshift(text,3.5 * exheight)
+ info = new_hlist(setlink(rule,text))
+ end
+ setattr(info,a_layer,layer)
+ return info
+ end
+
+ function visualizers.register(name,textcolor,rulecolor)
+ if rawget(layers,name) then
+ -- message
+ return
+ end
+ local cache = caches[name]
+ local layer = layers[name]
+ if not textcolor then
+ textcolor = c_text_d
+ end
+ if not rulecolor then
+ rulecolor = c_origin_d
+ end
+ return function(str)
+ if not str then
+ str = ""
+ end
+ local info = cache[str]
+ if not info then
+ info = make(str,textcolor,rulecolor,layer)
+ cache[str] = info
+ end
+ return copy_node(info)
+ end
+ end
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/trac-vis.mkiv b/Master/texmf-dist/tex/context/base/mkiv/trac-vis.mkiv
index a6a3fa5a2c0..570e6a7c730 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/trac-vis.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/trac-vis.mkiv
@@ -76,7 +76,7 @@
\to \everyshipout
\appendtoks
- \global\let\syst_visualizers_speedup\relax
+ \glet\syst_visualizers_speedup\relax
\to \t_syst_visualizers_optimize
\def\syst_visualizers_speedup{\the\t_syst_visualizers_optimize}
@@ -122,6 +122,11 @@
\unexpanded\def\showfontitalics
{\clf_setvisual{italic}}
+\unexpanded\def\showglyphdata
+ {\showglyphs
+ \showfontkerns
+ \showfontitalics}
+
\unexpanded\def\showfontexpansion
{\clf_setvisual{expansion}}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/type-ini.mkvi b/Master/texmf-dist/tex/context/base/mkiv/type-ini.mkvi
index 2ac3ee2071f..ac5f6af2f95 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/type-ini.mkvi
+++ b/Master/texmf-dist/tex/context/base/mkiv/type-ini.mkvi
@@ -45,18 +45,30 @@
\let\currenttypescripts\empty
\let\currenttypefile \empty
+\installmacrostack\currenttypefile
+
\let\typescriptone \empty % public, used in typescripts
\let\typescripttwo \empty % public, used in typescripts
\let\typescriptthree\empty % public, used in typescripts
+\installmacrostack\typescriptone
+\installmacrostack\typescripttwo
+\installmacrostack\typescriptthree
+
\let\fontclassstyle \empty
+\installmacrostack\fontclassstyle
+
\let\m_font_typescripts_one \empty
\let\m_font_typescripts_two \empty
\let\m_font_typescripts_three\empty
\let\m_font_typescripts_check\empty
\let\m_font_typescripts_match\empty
+\installmacrostack\m_font_typescripts_one
+\installmacrostack\m_font_typescripts_two
+\installmacrostack\m_font_typescripts_three
+
\let\t_font_typescripts\relax % uses as synonym
\installcorenamespace{typescriptcache}
@@ -75,6 +87,9 @@
\let\typescriptmethod\plusone % 1: empty==all==true 2: empty==false
\let\typescriptstate \plustwo % 1: process 2: store
+\installmacrostack\typescriptmethod
+\installmacrostack\typescriptstate
+
\unexpanded\def\starttypescriptcollection
{\dosingleempty\font_typescripts_collection_start}
@@ -95,19 +110,21 @@
\def\font_typescripts_use_one{\let\typescriptmethod\plusone\font_typescripts_use}
\def\font_typescripts_use_two{\let\typescriptmethod\plustwo\font_typescripts_use}
+\installmacrostack\stoptypescript
+
\unexpanded\def\font_typescripts_use[#one][#two][#three]%
- {\pushmacro\m_font_typescripts_one
- \pushmacro\m_font_typescripts_two
- \pushmacro\m_font_typescripts_three
+ {\push_macro_m_font_typescripts_one
+ \push_macro_m_font_typescripts_two
+ \push_macro_m_font_typescripts_three
\edef\m_font_typescripts_one {\truetypescript{#one}}%
\edef\m_font_typescripts_two {\truetypescript{#two}}%
\edef\m_font_typescripts_three{\truetypescript{#three}}%
- \pushmacro\typescriptone
- \pushmacro\typescripttwo
- \pushmacro\typescriptthree
- \pushmacro\typescriptmethod
- \pushmacro\typescriptstate
- \pushmacro\stoptypescript
+ \push_macro_typescriptone
+ \push_macro_typescripttwo
+ \push_macro_typescriptthree
+ \push_macro_typescriptmethod
+ \push_macro_typescriptstate
+ \push_macro_stoptypescript
\typescriptfoundfalse
\let\typescriptstate\plusone % why
\iftracetypescripts
@@ -119,15 +136,15 @@
\font_typescripts_use_display
\fi
\setfalse\c_font_typescripts_first_pass
- \popmacro\stoptypescript
- \popmacro\typescriptstate
- \popmacro\typescriptmethod
- \popmacro\typescriptthree
- \popmacro\typescripttwo
- \popmacro\typescriptone
- \popmacro\m_font_typescripts_three
- \popmacro\m_font_typescripts_two
- \popmacro\m_font_typescripts_one}
+ \pop_macro_stoptypescript
+ \pop_macro_typescriptstate
+ \pop_macro_typescriptmethod
+ \pop_macro_typescriptthree
+ \pop_macro_typescripttwo
+ \pop_macro_typescriptone
+ \pop_macro_m_font_typescripts_three
+ \pop_macro_m_font_typescripts_two
+ \pop_macro_m_font_typescripts_one}
\def\font_typescripts_use_display
{\processcommacommand[\typescriptfiles]\font_typescripts_load_file
@@ -170,10 +187,10 @@
% 1 then, it doesn't get stored without doing that explicitly
\unexpanded\def\loadtypescriptfile[#1]%
- {\pushmacro\typescriptstate
+ {\push_macro_typescriptstate
\let\typescriptstate\plustwo % assumes 2 at the outer level
\clf_loadtypescriptfile{#1}%
- \popmacro\typescriptstate}
+ \pop_macro_typescriptstate}
\unexpanded\def\loadfoundtypescriptfile#1%
{\startreadingfile
@@ -191,30 +208,26 @@
{\global\advance\c_font_typescripts_n_of_preloaded\plusone
\expandafter\normalgdef\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname
{\starttypescript#definitions\stoptypescript}%
- %\normalexpanded{\global\t_font_typescripts{\the\expandafter\t_font_typescripts\noexpand\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}}
- \global\t_font_typescripts\expandafter\expandafter\expandafter
- {\expandafter\the\expandafter\t_font_typescripts
- \csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}
+ \gtoksapp\t_font_typescripts\expandafter
+ {\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}
\def\font_typescripts_collection_start_store#definitions\stoptypescriptcollection
{\global\advance\c_font_typescripts_n_of_preloaded\plusone
\expandafter\normalgdef\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname
{\starttypescriptcollection#definitions\stoptypescriptcollection}%
- %\normalexpanded{\global\t_font_typescripts{\the\expandafter\t_font_typescripts\noexpand\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}}
- \global\t_font_typescripts\expandafter\expandafter\expandafter
- {\expandafter\the\expandafter\t_font_typescripts
- \csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}
+ \gtoksapp\t_font_typescripts\expandafter
+ {\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}
\def\font_typescripts_load_file#filename%
{\setfalse\c_font_typescripts_quit
- \pushmacro\currenttypefile
+ \push_macro_currenttypefile
\def\currenttypefile{#filename}%
\ifconditional\c_font_typescripts_preload
\font_typescript_process_typescript_file_and_store
\else
\font_typescript_process_typescript_file
\fi
- \popmacro\currenttypefile
+ \pop_macro_currenttypefile
\ifconditional\c_font_typescripts_quit
\quitcommalist
\setfalse\c_font_typescripts_quit
@@ -294,8 +307,7 @@
\def\font_typescripts_start_gobble#definitions\stoptypescript{}
\def\font_typescripts_start_document#definitions\stoptypescript
- %{\appendtoks\starttypescript#definitions\stoptypescript\to\c_font_typescripts_document}
- {\c_font_typescripts_document\expandafter{\the\c_font_typescripts_document\starttypescript#definitions\stoptypescript}}
+ {\toksapp\c_font_typescripts_document{\starttypescript#definitions\stoptypescript}}
\def\font_typescripts_start_process % could be a faster \doifelsenextoptionalif needed
{\let\typescriptone \m_font_typescripts_one
@@ -344,10 +356,10 @@
\let\font_typescripts_start_process_again_three\font_typescripts_start_process_yes
\def\font_typescripts_start_process_indeed
- {\pushmacro\fontclass}
+ {\push_macro_fontclass}
\unexpanded\def\stoptypescript
- {\popmacro\fontclass}
+ {\pop_macro_fontclass}
\def\font_typescripts_check#asked#target#followup[#value]% script use value next
{\donefalse
@@ -521,8 +533,8 @@
\let\@@tsdirection \empty
\let\@@tsdesignsize\empty
\geteparameters[\??ts][#settings]% todo raw
- \pushmacro\fontclass
- \pushmacro\fontclassstyle
+ \push_macro_fontclass
+ \push_macro_fontclassstyle
\setcurrentfontclass{#name}%
\savefontclassparameters{#style}\@@tsrscale\@@tsfeatures\@@tsfallbacks\@@tsgoodies\@@tsdesignsize\@@tsdirection
\the\everybeforedefinetypeface}
@@ -536,8 +548,8 @@
\def\font_typefaces_defining_stop
{\the\everyafterdefinetypeface
- \popmacro\fontclassstyle
- \popmacro\fontclass}
+ \pop_macro_fontclassstyle
+ \pop_macro_fontclass}
\def\dofastdefinetypeface#name#style#fontshape#fontsize#settings% called from the lua end (via case d)
{\font_typefaces_define_indeed[#name][#style]%
@@ -597,7 +609,7 @@
{\doifelsenothing{#styles}
{\font_typescripts_inherit_indeed[#name][\s!rm,\s!ss,\s!tt,\s!mm][\fontclass]}
{\doifnot{#name}{#parentclass}
- {\global\let\font_typescripts_inherit_check\font_typescripts_inherit_check_indeed
+ {\glet\font_typescripts_inherit_check\font_typescripts_inherit_check_indeed
\def\font_typescripts_inherit_check_step#style{\setevalue{\??typescriptinheritances#name:#style}{#parentclass}}%
\processcommalist[#styles]\font_typescripts_inherit_check_step}}}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/type-set.mkiv b/Master/texmf-dist/tex/context/base/mkiv/type-set.mkiv
index 1763de68790..c6b0c8841fc 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/type-set.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/type-set.mkiv
@@ -132,4 +132,6 @@
\definefilesynonym [type-imp-stixtwo.mkiv] [type-imp-stix.mkiv]
+\definefilesynonym [type-imp-ibmplex.mkiv] [type-imp-plex.mkiv]
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-bld.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-bld.lua
index 753748a2eee..55d74281f50 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-bld.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-bld.lua
@@ -54,10 +54,12 @@ storage.register("builders/paragraphs/constructors/names", names, "builders.
storage.register("builders/paragraphs/constructors/numbers", numbers, "builders.paragraphs.constructors.numbers")
local trace_page_builder = false trackers.register("builders.page", function(v) trace_page_builder = v end)
+local trace_vbox_builder = false trackers.register("builders.vbox", function(v) trace_vbox_builder = v end)
local trace_post_builder = false trackers.register("builders.post", function(v) trace_post_builder = v end)
-local report_par_builder = logs.reporter("builders","par")
local report_page_builder = logs.reporter("builders","page")
+local report_vbox_builder = logs.reporter("builders","vbox")
+local report_par_builder = logs.reporter("builders","par")
local mainconstructor = nil -- not stored in format
local nofconstructors = 0
@@ -137,7 +139,7 @@ end
-- also for testing (now also surrounding spacing done)
-function builders.paragraphs.constructors.methods.oneline(head,followed_by_display)
+function parbuilders.constructors.methods.oneline(head,followed_by_display)
-- when needed we will turn this into a helper
local t = texnest[texnest.ptr]
local h = hpack_node(head)
@@ -193,15 +195,11 @@ function builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction)
local done = false
if head then
starttiming(builders)
- if trace_vpacking then
+ if trace_vbox_builder then
local before = count_nodes(head)
head, done = vboxactions(head,groupcode,size,packtype,maxdepth,direction)
local after = count_nodes(head)
- if done then
- nodes.processors.tracer("vpack","changed",head,groupcode,before,after,true)
- else
- nodes.processors.tracer("vpack","unchanged",head,groupcode,before,after,true)
- end
+ nodes.processors.tracer("vpack",head,groupcode,before,after,done)
else
head, done = vboxactions(head,groupcode)
end
@@ -254,13 +252,13 @@ function builders.buildpage_filter(groupcode)
if trace_page_builder then
report(groupcode)
end
- return nil, false -- no return value needed
+-- return nil, false -- no return value needed
+ return nil
end
end
-registercallback('vpack_filter', builders.vpack_filter, "vertical spacing etc")
-registercallback('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)")
-----------------('contribute_filter', builders.contribute_filter, "adding content to lists")
+registercallback('vpack_filter', builders.vpack_filter, "vertical spacing etc")
+registercallback('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)")
statistics.register("v-node processing time", function()
return statistics.elapsedseconds(builders)
@@ -277,11 +275,21 @@ implement { name = "disableparbuilder", actions = constructors.disable }
-- Here are some tracers:
-local new_kern = nodes.pool.kern
-local new_rule = nodes.pool.rule
-local hpack = nodes.hpack
+local nuts = nodes.nuts
+local tonut = nodes.tonut
local setcolor = nodes.tracers.colors.set
local listtoutf = nodes.listtoutf
+local new_kern = nuts.pool.kern
+local new_rule = nuts.pool.rule
+local hpack = nuts.hpack
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
+local getdirection = nuts.getdirection
+local getlist = nuts.getlist
+local setwidth = nuts.setwidth
+local setdirection = nuts.setdirection
+local setlink = nuts.setlink
+local tonode = nuts.tonode
local report_hpack = logs.reporter("hpack routine")
local report_vpack = logs.reporter("vpack routine")
@@ -305,8 +313,9 @@ end)
local report, show = false, false
local function hpack_quality(how,detail,n,first,last)
+ n = tonut(n)
if report then
- local str = listtoutf(n.head,"",true,nil,true)
+ local str = listtoutf(getlist(n),"",true,nil,true)
if last <= 0 then
report_hpack("%s hbox: %s",how,str)
elseif first > 0 and first < last then
@@ -316,10 +325,10 @@ local function hpack_quality(how,detail,n,first,last)
end
end
if show then
- local width = 2*65536
- local height = n.height
- local depth = n.depth
- local dir = n.dir
+ local width = 2*65536
+ local height = getheight(n)
+ local depth = getdepth(n)
+ local direction = getdirection(n)
if height < 4*65526 then
height = 4*65526
end
@@ -327,12 +336,11 @@ local function hpack_quality(how,detail,n,first,last)
depth = 2*65526
end
local rule = new_rule(width,height,depth)
- rule.dir = dir
+ setdirection(rule,direction)
if how == "overfull" then
setcolor(rule,"red")
local kern = new_kern(-detail)
- kern.next = rule
- rule.prev = kern
+ setlink(kern,rule)
rule = kern
elseif how == "underfull" then
setcolor(rule,"blue")
@@ -342,9 +350,9 @@ local function hpack_quality(how,detail,n,first,last)
setcolor(rule,"cyan")
end
rule = hpack(rule)
- rule.width = 0
- rule.dir = dir
- return rule
+ setwidth(rule,0)
+ setdirection(rule,direction)
+ return tonode(rule) -- can be a nut
end
end
@@ -387,3 +395,4 @@ end)
-- end,
-- "experimental prevdepth checking"
-- )
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-brk.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-brk.lua
index 51760bbf48d..76e50ce1859 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-brk.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-brk.lua
@@ -23,7 +23,6 @@ local settings_to_array = utilities.parsers.settings_to_array
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -76,14 +75,14 @@ local new_wordboundary = nodepool.wordboundary
local nodecodes = nodes.nodecodes
local kerncodes = nodes.kerncodes
-local glyph_code = nodecodes.glyph
local kern_code = nodecodes.kern
local math_code = nodecodes.math
local fontkern_code = kerncodes.fontkern
------ userkern_code = kerncodes.userkern
local italickern_code = kerncodes.italiccorrection
+local is_letter = characters.is_letter
+
local typesetters = typesetters
typesetters.breakpoints = typesetters.breakpoints or {}
@@ -241,10 +240,9 @@ end
function breakpoints.handler(head)
local done = false
- local nead = tonut(head)
local attr = nil
local map = nil
- local current = nead
+ local current = head
while current do
local char, id = isglyph(current)
if char then
@@ -313,7 +311,7 @@ function breakpoints.handler(head)
end
end
if not done then
- return head, false
+ return head
end
-- we have hits
local numbers = languages.numbers
@@ -323,17 +321,21 @@ function breakpoints.handler(head)
local stop = data[2]
local cmap = data[3]
local smap = data[4]
--- local lang = getlang(start)
-- -- we do a sanity check for language
+-- local lang = getlang(start)
-- local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""])
-- if smap then
local nleft = smap.nleft
local cleft = 0
local prev = getprev(start)
- local kern = nil
+ local kern = nil
while prev and nleft ~= cleft do
- local id = getid(prev)
- if id == glyph_code then
+ local char, id = isglyph(prev)
+ if char then
+ if not is_letter[char] then
+ cleft = -1
+ break
+ end
cleft = cleft + 1
prev = getprev(prev)
elseif id == kern_code then
@@ -359,6 +361,10 @@ function breakpoints.handler(head)
while next and nright ~= cright do
local char, id = isglyph(next)
if char then
+ if not is_letter[char] then
+ cright = -1
+ break
+ end
if cright == 1 and cmap[char] then
-- let's not make it too messy
break
@@ -383,13 +389,13 @@ function breakpoints.handler(head)
if nright == cright then
local method = methods[smap.type]
if method then
- nead, start = method(nead,start,stop,smap,kern)
+ head, start = method(head,start,stop,smap,kern)
end
end
-- end
end
end
- return tonode(nead), true
+ return head
end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-cap.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-cap.lua
index 4dffd1c49a2..7e8003c620f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-cap.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-cap.lua
@@ -18,8 +18,6 @@ local report_casing = logs.reporter("typesetting","casing")
local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -29,6 +27,7 @@ local takeattr = nuts.takeattr
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
+local isglyph = nuts.isglyph
local getdisc = nuts.getdisc
local setattr = nuts.setattr
@@ -37,12 +36,12 @@ local setfont = nuts.setfont
local copy_node = nuts.copy
local end_of_math = nuts.end_of_math
-local traverse_id = nuts.traverse_id
local insert_after = nuts.insert_after
local find_attribute = nuts.find_attribute
+local nextglyph = nuts.traversers.glyph
+
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
local kerncodes = nodes.kerncodes
local glyph_code = nodecodes.glyph
@@ -98,19 +97,6 @@ local function get(a)
extract(a, 0, 8) -- run
end
--- local function get(a)
--- return
--- (a >> 8) & ~(-1 << 8), -- & 0x0FF -- tag
--- (a >> 16) & ~(-1 << 12), -- & 0xFFF -- font
--- (a >> 0) & ~(-1 << 8) -- & 0x0FF -- run
--- end
-
--- print(get(set( 1, 0)))
--- print(get(set( 1, 99)))
--- print(get(set( 2, 96)))
--- print(get(set( 30, 922)))
--- print(get(set(250,4000)))
-
-- a previous implementation used char(0) as placeholder for the larger font, so we needed
-- to remove it before it can do further harm ... that was too tricky as we use char 0 for
-- other cases too
@@ -128,10 +114,9 @@ local categories = characters.categories
-- true false true == mixed
local function replacer(start,codes)
- local char = getchar(start)
- local dc = codes[char]
+ local char, fnt = isglyph(start)
+ local dc = codes[char]
if dc then
- local fnt = getfont(start)
local ifc = fontchar[fnt]
if type(dc) == "table" then
for i=1,#dc do
@@ -149,13 +134,11 @@ local function replacer(start,codes)
insert_after(start,start,g)
end
end
- return start, true
elseif ifc[dc] then
setchar(start,dc)
- return start, true
end
end
- return start, false
+ return start
end
local registered, n = { }, 0
@@ -191,9 +174,9 @@ local function Words(start,attr,lastfont,n,count,where,first) -- looks quite com
end
if count == 1 and where ~= "post" then
replacer(first or start,uccodes)
- return start, true, true
+ return start, true
else
- return start, false, true
+ return start, true
end
end
@@ -203,9 +186,9 @@ local function Word(start,attr,lastfont,n,count,where,first)
end
local function camel(start,attr,lastfont,n,count,where,first)
- local _, done_1 = word(start,attr,lastfont,n,count,where,first)
- local _, done_2 = Words(start,attr,lastfont,n,count,where,first)
- return start, done_1 or done_2, true
+ word(start,attr,lastfont,n,count,where,first)
+ Words(start,attr,lastfont,n,count,where,first)
+ return start, true
end
-- local function mixed(start,attr,lastfont,n,count,where,first)
@@ -216,19 +199,16 @@ end
-- local char = getchar(first)
-- local dc = uccodes[char]
-- if not dc then
--- return start, false, true
+-- -- quit
-- elseif dc == char then
-- local lfa = lastfont[n]
-- if lfa then
-- setfont(first,lfa)
--- return start, true, true
--- else
--- return start, false, true
-- end
-- else
-- replacer(first or start,uccodes)
--- return start, true, true
-- end
+-- return start, true
-- end
local function mixed(start,attr,lastfont,n,count,where,first)
@@ -239,38 +219,33 @@ local function mixed(start,attr,lastfont,n,count,where,first)
local char = getchar(used)
local dc = uccodes[char]
if not dc then
- return start, false, true
+ -- quit
elseif dc == char then
local lfa = lastfont[n]
if lfa then
setfont(used,lfa)
- return start, true, true
- else
- return start, false, true
end
- else
- if check_kerns then
- local p = getprev(used)
- if p and getid(p) == glyph_code then
- local c = lccodes[char]
- local c = type(c) == "table" and c[1] or c
- replacer(used,uccodes)
- local fp = getfont(p)
- local fc = getfont(used)
- if fp ~= fc then
- local k = fonts.getkern(fontdata[fp],getchar(p),c)
- if k ~= 0 then
- insert_after(p,p,newkern(k))
- end
+ elseif check_kerns then
+ local p = getprev(used)
+ if p and getid(p) == glyph_code then
+ local c = lccodes[char]
+ local c = type(c) == "table" and c[1] or c
+ replacer(used,uccodes)
+ local fp = getfont(p)
+ local fc = getfont(used)
+ if fp ~= fc then
+ local k = fonts.getkern(fontdata[fp],getchar(p),c)
+ if k ~= 0 then
+ insert_after(p,p,newkern(k))
end
- else
- replacer(used,uccodes)
end
else
replacer(used,uccodes)
end
- return start, true, true
+ else
+ replacer(used,uccodes)
end
+ return start, true
end
local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
@@ -284,11 +259,11 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
end
end
end
- local s, d, c = replacer(first or start,uccodes)
+ local s, c = replacer(first or start,uccodes)
if once then
lastfont[n] = false -- here
end
- return start, d, c
+ return start, c
end
local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
@@ -296,7 +271,7 @@ local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
end
local function none(start,attr,lastfont,n,count,where,first)
- return start, false, true
+ return start, true
end
local function randomized(start,attr,lastfont,n,count,where,first)
@@ -311,7 +286,7 @@ local function randomized(start,attr,lastfont,n,count,where,first)
local n = getrandom("capital lu",0x41,0x5A)
if tfm[n] then -- this also intercepts tables
setchar(used,n)
- return start, true
+ return start
end
end
elseif kind == "ll" then
@@ -319,11 +294,11 @@ local function randomized(start,attr,lastfont,n,count,where,first)
local n = getrandom("capital ll",0x61,0x7A)
if tfm[n] then -- this also intercepts tables
setchar(used,n)
- return start, true
+ return start
end
end
end
- return start, false
+ return start
end
register(variables.WORD, WORD) -- 1
@@ -341,10 +316,9 @@ register(variables.cap, variables.capital) -- clone
register(variables.Cap, variables.Capital) -- clone
function cases.handler(head) -- not real fast but also not used on much data
- local start = tonut(head)
+ local start = head
local lastfont = { }
local lastattr = nil
- local done = false
local count = 0
local previd = nil
local prev = nil
@@ -367,10 +341,7 @@ function cases.handler(head) -- not real fast but also not used on much data
end
local action = actions[n] -- map back to low number
if action then
- start, ok = action(start,attr,lastfont,n,count)
- if ok then
- done = true
- end
+ start = action(start,attr,lastfont,n,count)
if trace_casing then
report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok)
end
@@ -396,32 +367,38 @@ function cases.handler(head) -- not real fast but also not used on much data
local pre, post, replace = getdisc(start)
if replace then
local cnt = count
- for g in traverse_id(glyph_code,replace) do
+ for g in nextglyph, replace do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+ if quit then
+ break
+ end
end
end
if pre then
local cnt = count
- for g in traverse_id(glyph_code,pre) do
+ for g in nextglyph, pre do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+ if quit then
+ break
+ end
end
end
if post then
local cnt = count
- for g in traverse_id(glyph_code,post) do
+ for g in nextglyph, post do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
+ if quit then
+ break
+ end
end
end
end
@@ -441,17 +418,16 @@ function cases.handler(head) -- not real fast but also not used on much data
start = getnext(start)
end
end
- return head, done
+ return head
end
-- function cases.handler(head) -- not real fast but also not used on much data
--- local attr, start = find_attribute(tonut(head),a_cases)
+-- local attr, start = find_attribute(head,a_cases)
-- if not start then
-- return head, false
-- end
-- local lastfont = { }
-- local lastattr = nil
--- local done = false
-- local count = 0
-- local previd = nil
-- local prev = nil
@@ -475,10 +451,7 @@ end
-- end
-- local action = actions[n] -- map back to low number
-- if action then
--- start, ok = action(start,attr,lastfont,n,count)
--- if ok then
--- done = true
--- end
+-- start = action(start,attr,lastfont,n,count)
-- if trace_casing then
-- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok)
-- end
@@ -504,32 +477,38 @@ end
-- local pre, post, replace = getdisc(start)
-- if replace then
-- local cnt = count
--- for g in traverse_id(glyph_code,replace) do
+-- for g in glyph_code, replace do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- if pre then
-- local cnt = count
--- for g in traverse_id(glyph_code,pre) do
+-- for g in nextglyph, pre do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- if post then
-- local cnt = count
--- for g in traverse_id(glyph_code,post) do
+-- for g in nextglyph, post do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- end
@@ -555,26 +534,22 @@ end
-- attr, start = find_attribute(start,a_cases)
-- end
-- end
--- return head, done
+-- return head
-- end
-- function cases.handler(head) -- let's assume head doesn't change ... no reason
--- local done = false
-- local lastfont = { }
--- for first, last, size, attr in nuts.words(tonut(head),a_cases) do
+-- for first, last, size, attr in nuts.words(head,a_cases) do
-- local n, id, m = get(attr)
-- if lastfont[n] == nil then
-- lastfont[n] = id
-- end
-- local action = actions[n]
-- if action then
--- local _, ok = action(first,attr,lastfont,n)
--- if ok then
--- done = true
--- end
+-- action(first,attr,lastfont,n)
-- end
-- end
--- return head, done
+-- return head
-- end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv
index 4d1272e103c..890b0818675 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv
@@ -81,20 +81,23 @@
% todo: names casings
-\unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\v!WORD ]}{}}
-\unexpanded\def\word {\groupedcommand{\setcharactercasing[\v!word ]}{}}
-\unexpanded\def\Word {\groupedcommand{\setcharactercasing[\v!Word ]}{}}
-\unexpanded\def\Words{\groupedcommand{\setcharactercasing[\v!Words]}{}}
-\unexpanded\def\camel{\groupedcommand{\setcharactercasing[\v!camel]}{}}
-
-% This might become:
-%
-% \unexpanded\def\WORD {\bgroup\def\g_word{\setcharactercasing[\v!WORD ]}\afterassignment\g_word\let\nexttoken}
-% \unexpanded\def\word {\bgroup\def\g_word{\setcharactercasing[\v!word ]}\afterassignment\g_word\let\nexttoken}
-% \unexpanded\def\Word {\bgroup\def\g_word{\setcharactercasing[\v!Word ]}\afterassignment\g_word\let\nexttoken}
-% \unexpanded\def\Words{\bgroup\def\g_word{\setcharactercasing[\v!Words]}\afterassignment\g_word\let\nexttoken}
-%
-% so no longer {\Word test} and { } mandate (also later \groupedcommands will go)
+% \unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\v!WORD ]}{}}
+% \unexpanded\def\word {\groupedcommand{\setcharactercasing[\v!word ]}{}}
+% \unexpanded\def\Word {\groupedcommand{\setcharactercasing[\v!Word ]}{}}
+% \unexpanded\def\Words{\groupedcommand{\setcharactercasing[\v!Words]}{}}
+% \unexpanded\def\camel{\groupedcommand{\setcharactercasing[\v!camel]}{}}
+
+\unexpanded\def\typo_capitale_WORD {\clf_setcharactercasing{\v!WORD }\fontid\font}
+\unexpanded\def\typo_capitale_word {\clf_setcharactercasing{\v!word }\fontid\font}
+\unexpanded\def\typo_capitale_Word {\clf_setcharactercasing{\v!Word }\fontid\font}
+\unexpanded\def\typo_capitale_Words{\clf_setcharactercasing{\v!Words}\fontid\font}
+\unexpanded\def\typo_capitale_camel{\clf_setcharactercasing{\v!camel}\fontid\font}
+
+\unexpanded\def\WORD {\triggergroupedcommandcs\typo_capitale_WORD }
+\unexpanded\def\word {\triggergroupedcommandcs\typo_capitale_word }
+\unexpanded\def\Word {\triggergroupedcommandcs\typo_capitale_Word }
+\unexpanded\def\Words{\triggergroupedcommandcs\typo_capitale_Words}
+\unexpanded\def\camel{\triggergroupedcommandcs\typo_capitale_camel}
\let\WORDS\WORD
\let\words\word
@@ -176,16 +179,27 @@
\sc
\clf_setcharactercasing{\currentcapitals}\fontid\font}
-\unexpanded\def\pseudosmallcapped{\groupedcommand{\typo_capitals_set_fake\v!WORD }\donothing} % all upper
-\unexpanded\def\pseudoSmallcapped{\groupedcommand{\typo_capitals_set_fake\v!capital}\donothing} % one upper + font
-\unexpanded\def\pseudoSmallCapped{\groupedcommand{\typo_capitals_set_fake\v!Capital}\donothing} % some upper + font
-\unexpanded\def\pseudoMixedCapped{\groupedcommand{\typo_capitals_set_fake\v!mixed }\donothing} % UpperCase
+% \unexpanded\def\pseudosmallcapped{\groupedcommand{\typo_capitals_set_fake\v!WORD }\donothing} % all upper
+% \unexpanded\def\pseudoSmallcapped{\groupedcommand{\typo_capitals_set_fake\v!capital}\donothing} % one upper + font
+% \unexpanded\def\pseudoSmallCapped{\groupedcommand{\typo_capitals_set_fake\v!Capital}\donothing} % some upper + font
+% \unexpanded\def\pseudoMixedCapped{\groupedcommand{\typo_capitals_set_fake\v!mixed }\donothing} % UpperCase
+%
+% \unexpanded\def\realsmallcapped {\groupedcommand{\typo_capitals_set_real\v!WORD }\donothing} % all lower
+% \unexpanded\def\realSmallcapped {\groupedcommand{\typo_capitals_set_real\v!Word }\donothing} % one upper + font
+% \unexpanded\def\realSmallCapped {\groupedcommand{\typo_capitals_set_real\v!Words }\donothing} % some upper
+%
+% \unexpanded\def\notsmallcapped {\groupedcommand{\typo_capitals_set_fake\v!word }\donothing}
+
+\unexpanded\def\pseudosmallcapped{\triggergroupedcommandcs\font_style_pseudosmallcapped}
+\unexpanded\def\pseudoSmallcapped{\triggergroupedcommandcs\font_style_pseudoSmallcapped}
+\unexpanded\def\pseudoSmallCapped{\triggergroupedcommandcs\font_style_pseudoSmallCapped}
+\unexpanded\def\pseudoMixedCapped{\triggergroupedcommandcs\font_style_pseudoMixedCapped}
-\unexpanded\def\realsmallcapped {\groupedcommand{\typo_capitals_set_real\v!WORD }\donothing} % all lower
-\unexpanded\def\realSmallcapped {\groupedcommand{\typo_capitals_set_real\v!Word }\donothing} % one upper + font
-\unexpanded\def\realSmallCapped {\groupedcommand{\typo_capitals_set_real\v!Words }\donothing} % some upper
+\unexpanded\def\realsmallcapped {\triggergroupedcommandcs\font_style_realsmallcapped}
+\unexpanded\def\realSmallcapped {\triggergroupedcommandcs\font_style_realSmallcapped}
+\unexpanded\def\realSmallCapped {\triggergroupedcommandcs\font_style_realSmallCapped}
-\unexpanded\def\notsmallcapped {\groupedcommand{\typo_capitals_set_fake\v!word }\donothing}
+\unexpanded\def\notsmallcapped {\triggergroupedcommandcs\font_style_notsmallcapped}
\unexpanded\def\font_style_pseudosmallcapped{\typo_capitals_set_fake\v!WORD } % all upper
\unexpanded\def\font_style_pseudoSmallcapped{\typo_capitals_set_fake\v!capital} % one upper + font
@@ -285,7 +299,9 @@
%
% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=]
-\unexpanded\def\randomizetext{\groupedcommand{\attribute\caseattribute\pluseight}{}}
+% \unexpanded\def\randomizetext{\groupedcommand{\attribute\caseattribute\pluseight}{}}
+
+\unexpanded\def\randomizetext{\triggergroupedcommand{\attribute\caseattribute\pluseight}}
\definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-chr.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-chr.lua
index 80497a49207..15d14c8601b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-chr.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-chr.lua
@@ -6,40 +6,40 @@ if not modules then modules = { } end modules ['typo-chr'] = {
license = "see context related readme files"
}
--- local nodecodes = nodes.nodecodes
--- local whatsitcodes = nodes.whatsitcodes
--- local glyph_code = nodecodes.glyph
--- local whatsit_code = nodecodes.whatsit
--- local user_code = whatsitcodes.userdefined
+-- This module can be optimized.
+
+-- local nodecodes = nodes.nodecodes
+-- local whatsitcodes = nodes.whatsitcodes
+--
+-- local glyph_code = nodecodes.glyph
+-- local whatsit_code = nodecodes.whatsit
--
--- local stringusernode = nodes.pool.userstring
+-- local userwhatsit_code = whatsitcodes.userdefined
--
--- local nuts = nodes.nuts
--- local pool = nuts.pool
+-- local stringusernode = nodes.pool.userstring
--
--- local tonut = nuts.tonut
--- local tonode = nuts.tonode
--- local getid = nuts.getid
--- local getprev = nuts.getprev
--- local getsubtype = nuts.getsubtype
--- local getchar = nuts.getchar
--- local getfield = nuts.getfield
+-- local nuts = nodes.nuts
+-- local pool = nuts.pool
--
--- local remove_node = nuts.remove
--- local traverse_by_id = nuts.traverse_id
+-- local getid = nuts.getid
+-- local getprev = nuts.getprev
+-- local getchar = nuts.getchar
+-- local getdata = nuts.getdata
+-- local getfield = nuts.getfield
--
--- local signal = pool.userids.signal
+-- local remove_node = nuts.remove
+-- local nextwhatsit = nuts.traversers.whatsit
--
--- local is_punctuation = characters.is_punctuation
+-- local signal = pool.userids.signal
+--
+-- local is_punctuation = characters.is_punctuation
--
-- local actions = {
-- removepunctuation = function(head,n)
-- local prev = getprev(n)
-- if prev then
--- if getid(prev) == glyph_code then
--- if is_punctuation[getchar(prev)] then
--- head = remove_node(head,prev,true)
--- end
+-- if getid(prev) == glyph_code and is_punctuation[getchar(prev)] then
+-- head = remove_node(head,prev,true)
-- end
-- end
-- return head
@@ -51,23 +51,18 @@ if not modules then modules = { } end modules ['typo-chr'] = {
-- typesetters.signals = { }
--
-- function typesetters.signals.handler(head)
--- local h = tonut(head)
-- local done = false
--- for n in traverse_by_id(whatsit_code,h) do
--- if getsubtype(n) == user_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then
--- local action = actions[getfield(n,"value")]
+-- for n, subtype in nextwhatsit, head do
+-- if subtype == userwhatsit_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then
+-- local action = actions[getdata(n)]
-- if action then
--- h = action(h,n)
+-- head = action(h,n)
-- end
--- h = remove_node(h,n,true)
+-- head = remove_node(head,n,true)
-- done = true
-- end
-- end
--- if done then
--- return tonode(h), true
--- else
--- return head
--- end
+-- return head, done
-- end
--
-- local enabled = false
@@ -88,35 +83,44 @@ if not modules then modules = { } end modules ['typo-chr'] = {
local insert, remove = table.insert, table.remove
-local context = context
+local context = context
+local ctx_doifelse = commands.doifelse
+
+local nodecodes = nodes.nodecodes
+local boundarycodes = nodes.boundarycodes
+local subtypes = nodes.subtypes
+
+local glyph_code = nodecodes.glyph
+local localpar_code = nodecodes.localpar
+local boundary_code = nodecodes.boundary
-local nodecodes = nodes.nodecodes
-local glyph_code = nodecodes.glyph
-local localpar_code = nodecodes.localpar
+local wordboundary_code = boundarycodes.word
-local texnest = tex.nest
-local flush_node = node.flush_node
-local flush_list = node.flush_list
+local texgetnest = tex.getnest -- to be used
+local texsetcount = tex.setcount
-local settexattribute = tex.setattribute
-local punctuation = characters.is_punctuation
+local flush_node = node.flush_node
+local flush_list = node.flush_list
-local variables = interfaces.variables
-local v_all = variables.all
-local v_reset = variables.reset
+local settexattribute = tex.setattribute
+local punctuation = characters.is_punctuation
-local a_marked = attributes.numbers['marked']
-local lastmarked = 0
-local marked = {
+local variables = interfaces.variables
+local v_all = variables.all
+local v_reset = variables.reset
+
+local stack = { }
+
+local a_marked = attributes.numbers['marked']
+local lastmarked = 0
+local marked = {
[v_all] = 1,
[""] = 1,
[v_reset] = attributes.unsetvalue,
}
-local stack = { }
-
local function pickup()
- local list = texnest[texnest.ptr]
+ local list = texgetnest()
if list then
local tail = list.tail
if tail and tail.id == glyph_code and punctuation[tail.char] then
@@ -171,8 +175,7 @@ local function pickup(head,tail,str)
while true do
local prev = first.prev
if prev and prev[a_marked] == attr then
- local id = prev.id
- if id == localpar_code then
+ if prev.id == localpar_code then -- and prev.subtype == 0
break
else
first = prev
@@ -187,7 +190,7 @@ end
local actions = {
remove = function(specification)
- local list = texnest[texnest.ptr]
+ local list = texgetnest()
if list then
local head = list.head
local tail = list.tail
@@ -250,3 +253,95 @@ interfaces.implement {
actions = markcontent,
arguments = "string",
}
+
+-- We just put these here.
+
+interfaces.implement {
+ name = "lastnodeidstring",
+ public = true,
+ actions = function()
+ local list = texgetnest() -- "top"
+ local okay = false
+ if list then
+ local tail = list.tail
+ if tail then
+ okay = nodecodes[tail.id]
+ end
+ end
+ context(okay or "")
+ end,
+}
+
+-- local t_lastnodeid = token.create("c_syst_last_node_id")
+--
+-- interfaces.implement {
+-- name = "lastnodeid",
+-- public = true,
+-- actions = function()
+-- ...
+-- tex.setcount("c_syst_last_node_id",okay)
+-- context.sprint(t_lastnodeid)
+-- end,
+-- }
+
+interfaces.implement {
+ name = "lastnodeid",
+ actions = function()
+ local list = texgetnest() -- "top"
+ local okay = -1
+ if list then
+ local tail = list.tail
+ if tail then
+ okay = tail.id
+ end
+ end
+ texsetcount("c_syst_last_node_id",okay)
+ end,
+}
+
+interfaces.implement {
+ name = "lastnodesubtypestring",
+ public = true,
+ actions = function()
+ local list = texgetnest() -- "top"
+ local okay = false
+ if list then
+ local tail = list.tail
+ if head then
+ okay = subtypes[tail.id][tail.subtype]
+ end
+ end
+ context(okay or "")
+ end,
+}
+
+local function lastnodeequals(id,subtype)
+ local list = texgetnest() -- "top"
+ local okay = false
+ if list then
+ local tail = list.tail
+ if tail then
+ local i = tail.id
+ okay = i == id or i == nodecodes[id]
+ if subtype then
+ local s = tail.subtype
+ okay = s == subtype or s == subtypes[i][subtype]
+ end
+ end
+ end
+ ctx_doifelse(okay)
+end
+
+interfaces.implement {
+ name = "lastnodeequals",
+ arguments = "2 strings",
+ actions = lastnodeequals,
+}
+
+interfaces.implement {
+ name = "atwordboundary",
+ actions = function()
+ lastnodeequals(boundary_code,wordboundary_code)
+ end,
+}
+
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-chr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-chr.mkiv
index c92c4562e0e..365c79e5154 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-chr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-chr.mkiv
@@ -79,4 +79,23 @@
\def\typo_marked_remove[#1]%
{\clf_pickupmarkedcontent action{remove}mark{#1}\relax}
+%D A few helpers (put here for convenience):
+%D
+%D \starttyping
+%D test test\doifelselastnode{boundary}{word}{YES}{NOP}test
+%D test test\wordboundary \doifelselastnode{boundary}{word}{YES}{NOP}test
+%D test test\wordboundary \doifelseatwordboundary{YES}{NOP}test
+%D test test \lastnodeidstring test
+%D test test\lastnodeidstring test
+%D test test\number\lastnodeid test
+%D \stoptyping
+
+\newcount\c_syst_last_node_id
+
+\unexpanded\def\doifelselastnode {\clf_lastnodeequals}
+\unexpanded\def\doifelseatwordboundary{\clf_atwordboundary}
+\unexpanded\def\lastnodeid {\clf_lastnodeid\c_syst_last_node_id}
+% \lastnodeidstring % public expandable
+% \lastnodesubstring % public expandable
+
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-cln.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-cln.lua
index b7187eaeb0b..b9b0e7d6cb7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-cln.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-cln.lua
@@ -31,15 +31,13 @@ local enableaction = nodes.tasks.enableaction
local texsetattribute = tex.setattribute
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local getchar = nuts.getchar
local getattr = nuts.getattr
local setattr = nuts.setattr
local setchar = nuts.setchar
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
local unsetvalue = attributes.unsetvalue
@@ -58,9 +56,8 @@ local resetter = { -- this will become an entry in char-def
-- cleaning comes first.
function cleaners.handler(head)
- local inline, done = false, false
- for n in traverse_id(glyph_code,tonut(head)) do
- local char = getchar(n)
+ local inline = false
+ for n, char, font in nextglyph, head do
if resetter[char] then
inline = false
elseif not inline then
@@ -71,7 +68,6 @@ function cleaners.handler(head)
-- some day, not much change that \SS ends up here
else
setchar(n,upper)
- done = true
if trace_autocase then
report_autocase("")
end
@@ -80,7 +76,7 @@ function cleaners.handler(head)
inline = true
end
end
- return head, done
+ return head
end
-- see typo-cap for a more advanced settings handler .. not needed now
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-del.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-del.mkiv
index d12be6bcfda..2ce98841e19 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-del.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-del.mkiv
@@ -71,35 +71,48 @@
\setnewconstant\boundarycharactermode\plusone
+% old: skip symbol skip
+% new: bound skip symbol skip bound
+
\unexpanded\def\midboundarycharacter#1#2%
{\ifcase\boundarycharactermode
\or
- %\nobreak
+ \removeunwantedspaces
+ \wordboundary
\hskip\hspaceamount\currentusedlanguage{#2}%
\usedlanguageparameter#1%
- %\nobreak
\hskip\hspaceamount\currentusedlanguage{#2}%
+ \wordboundary
+ \ignorespaces
\or
\usedlanguageparameter#1%
\fi
\boundarycharactermode\plusone}
+% old: symbol nobreak skip
+% new: symbol nobreak skip wordboundary
+
\unexpanded\def\leftboundarycharacter#1#2%
{\ifcase\boundarycharactermode
\or
\usedlanguageparameter#1%
\nobreak
- \hskip\hspaceamount\currentusedlanguage{#2}%
+ \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern
+ \wordboundary
\or
\usedlanguageparameter#1%
\fi
\boundarycharactermode\plusone}
+% old: preword skip symbol
+% new: bound nobreak skip symbol
+
\unexpanded\def\rightboundarycharacter#1#2%
{\ifcase\boundarycharactermode
\or
- \prewordbreak %\nobreak
- \hskip\hspaceamount\currentusedlanguage{#2}%
+ \wordboundary
+ \nobreak
+ \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern
\usedlanguageparameter#1%
\or
\usedlanguageparameter#1%
@@ -212,10 +225,15 @@
%D \typebuffer
%D \getbuffer
-\unexpanded\def\startsubsentence{\beginofsubsentence\prewordbreak\beginofsubsentencespacing\typo_subsentence_cleanup_start}
-\unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\endofsubsentencespacing\prewordbreak\endofsubsentence}
-\unexpanded\def\subsentence {\groupedcommand\startsubsentence\stopsubsentence}
-\unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\prewordbreak\midsentence\prewordbreak\typo_subsentence_cleanup_stop}
+%unexpanded\def\startsubsentence{\beginofsubsentence\prewordbreak\beginofsubsentencespacing\typo_subsentence_cleanup_start}
+%unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\endofsubsentencespacing\prewordbreak\endofsubsentence}
+%unexpanded\def\subsentence {\groupedcommandcs\startsubsentence\stopsubsentence}
+%unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\prewordbreak\midsentence\prewordbreak\typo_subsentence_cleanup_stop}
+
+\unexpanded\def\startsubsentence{\beginofsubsentence\wordboundary\beginofsubsentencespacing\wordboundary\typo_subsentence_cleanup_start}
+\unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\wordboundary\endofsubsentencespacing\wordboundary\endofsubsentence}
+\unexpanded\def\subsentence {\groupedcommandcs\startsubsentence\stopsubsentence}
+\unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\wordboundary\midsentence\wordboundary\typo_subsentence_cleanup_stop}
\definehspace [quotation] [\zeropoint]
\definehspace [interquotation] [.125em]
@@ -277,6 +295,8 @@
\let\currentdelimitedtext\s!unknown
+\installglobalmacrostack\currentdelimitedtext
+
\let\delimitedtextlevel\!!zerocount
\def\c_typo_delimited_nesting{\csname\??delimitedtextlevel\currentparentdelimitedtext\endcsname}
@@ -301,6 +321,8 @@
\let\currentdelimitedlanguage\empty
+\installglobalmacrostack\currentdelimitedlanguage
+
\def\typo_delimited_set_language_nop
{\setusedlanguage{\delimitedtextparameter\c!language}}
@@ -333,8 +355,8 @@
\let\m_delimited_argument\empty}
\def\typo_delimited_push#1#2%
- {\globalpushmacro\currentdelimitedtext % can we combine these two
- \globalpushmacro\currentdelimitedlanguage % the language used for hyphenation
+ {\push_macro_currentdelimitedtext % can we combine these two
+ \push_macro_currentdelimitedlanguage % the language used for hyphenation
\edef\currentdelimitedtext{#1}%
\edef\m_delimited_argument{#2}%
\ifx\m_delimited_argument\empty
@@ -350,8 +372,8 @@
\def\typo_delimited_pop
{\global\advance\c_typo_delimited_nesting\minusone
- \globalpopmacro\currentdelimitedlanguage
- \globalpopmacro\currentdelimitedtext}
+ \pop_macro_currentdelimitedlanguage
+ \pop_macro_currentdelimitedtext}
\installcorenamespace{delimitedtext}
\installcorenamespace{delimitedtextlevel}
@@ -414,6 +436,8 @@
\dostoptagged
\ignorespaces}
+\newconditional\c_typo_delimited_repeating
+
\def\typo_delimited_start_other
{\edef\p_delimited_repeat{\delimitedtextparameter\c!repeat}%
\ifx\p_delimited_repeat\v!yes
@@ -421,6 +445,7 @@
\else
\let\typo_delimited_repeat\relax
\fi
+ \setfalse\c_typo_delimited_repeating
\edef\p_delimited_location{\delimitedtextparameter\c!location}%
\ifx\p_delimited_location\v!paragraph
\singleexpandafter\typo_delimited_start_par
@@ -493,7 +518,7 @@
\let\typo_delimited_stop_par_indeed\stopnarrower
\fi
% so far
- \pushmacro\checkindentation
+ \push_macro_checkindentation
\useindentingparameter\delimitedtextparameter
%
\begingroup
@@ -515,7 +540,7 @@
{\typo_delimited_stop_content
\rightdelimitedtextmark
\carryoverpar\endgroup % new per 2013-01-21 ... please left floats
- \popmacro\checkindentation
+ \pop_macro_checkindentation
\typo_delimited_stop_par_indeed
\delimitedtextparameter\c!after
\edef\p_delimited_spaceafter{\delimitedtextparameter\c!spaceafter}%
@@ -680,30 +705,37 @@
% test test test
% \stoptext
-\def\typo_delimited_handle_middle#1%
- {\typo_delimited_stop_content
- \begingroup
- \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor
- \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
- \ifdim\wd\scratchbox>\zeropoint
- \ifdim\lastkern=\d_typo_delimited_signal
- \unkern
- \hskip\hspaceamount\currentusedlanguage{interquotation}%
+% We have no real test case for this and it's broken already for a while,
+% even in \MKII. Maybe we should to this in \LUA. Only Italian has the
+% middlespeech parameter set.
+
+\def\typo_delimited_handle_middle#1% special case
+ {\ifconditional\c_typo_delimited_repeating
+ \begingroup
+ \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor
+ \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
+ \ifdim\wd\scratchbox>\zeropoint
+ \ifdim\lastkern=\d_typo_delimited_signal
+ \unkern
+ \hskip\hspaceamount\currentusedlanguage{interquotation}%
+ \else % maybe an option:
+ %\edef\p_delimited_margin{\delimitedtextparameter\c!location}%
+ %\ifx\p_delimited_margin\v!margin
+ % \hskip-\wd\scratchbox
+ %\fi
+ \fi
+ \strut % new, needed below
+ \dostarttagged\t!delimitedsymbol\empty
+ \dotagsetdelimitedsymbol\s!middle
+ \delimitedtextparameter#1% unhbox\scratchbox
+ \dostoptagged
+ % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods
+ \kern\d_typo_delimited_signal % +- \prewordbreak
\fi
- \ifhmode % else funny pagebeaks
- \penalty\plustenthousand
- \hskip\zeropoint % == \prewordbreak
- \fi
- \strut % new, needed below
- \dostarttagged\t!delimitedsymbol\empty
- \dotagsetdelimitedsymbol\s!middle
- \delimitedtextparameter#1% unhbox\scratchbox
- \dostoptagged
- % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods
- \kern\d_typo_delimited_signal % +- \prewordbreak
- \fi
- \endgroup
- \typo_delimited_start_content}
+ \endgroup
+ \else
+ \settrue\c_typo_delimited_repeating
+ \fi}
\def\typo_delimited_handle_left#1%
{\begingroup
@@ -717,11 +749,11 @@
\unskip
\hskip\hspaceamount\currentusedlanguage{interquotation}%
\fi\fi
- \strut % new, needed below
- \ifhmode % else funny pagebeaks
- \penalty\plustenthousand
- \hskip\zeropoint % == \prewordbreak
- \fi
+ % \strut % new, needed below
+ % \ifhmode % else funny pagebeaks
+ % \penalty\plustenthousand
+ % \hskip\zeropoint % == \prewordbreak
+ % \fi
\strut % new, needed below
\dostarttagged\t!delimitedsymbol\empty
\dotagsetdelimitedsymbol\s!left
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua
index af01f0f0d0a..c0bbdc39668 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua
@@ -41,13 +41,11 @@ if not modules then modules = { } end modules ['typo-dha'] = {
local nodes, node = nodes, node
-local trace_directions = false trackers.register("typesetters.directions.default", function(v) trace_directions = v end)
+local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end)
local report_directions = logs.reporter("typesetting","text directions")
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -57,7 +55,7 @@ local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
local getattr = nuts.getattr
local getprop = nuts.getprop
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local isglyph = nuts.isglyph -- or ischar
local setprop = nuts.setprop
@@ -71,7 +69,7 @@ local end_of_math = nuts.end_of_math
local nodepool = nuts.pool
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
local math_code = nodecodes.math
@@ -80,9 +78,13 @@ local glue_code = nodecodes.glue
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local parfillskip_code = skipcodes.parfillskip
+local dirvalues = nodes.dirvalues
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
-local new_textdir = nodepool.textdir
+local parfillskip_code = gluecodes.parfillskip
+
+local new_direction = nodepool.direction
local insert = table.insert
@@ -104,14 +106,14 @@ local strip = false
local s_isol = fonts.analyzers.states.isol
-local function stopdir(finish)
- local n = new_textdir(finish == "TRT" and "-TRT" or "-TLT")
+local function stopdir(finish) -- we could use finish directly
+ local n = new_direction(finish == righttoleft_code and righttoleft_code or lefttoright_code,true)
setprop(n,"direction",true)
return n
end
-local function startdir(finish)
- local n = new_textdir(finish == "TRT" and "+TRT" or "+TLT")
+local function startdir(finish) -- we could use finish directly
+ local n = new_direction(finish == righttoleft_code and righttoleft_code or lefttoright_code)
setprop(n,"direction",true)
return n
end
@@ -136,7 +138,7 @@ end
local function process(start)
- local head = tonut(start) -- we have a global head
+ local head = start
local current = head
local autodir = 0
local embedded = 0
@@ -309,27 +311,31 @@ local function process(start)
elseif id == kern_code then
setprop(current,"direction",'k')
elseif id == dir_code then
- local dir = getdir(current)
- if dir == "+TRT" then
- autodir = -1
- elseif dir == "+TLT" then
- autodir = 1
- elseif dir == "-TRT" or dir == "-TLT" then
- if embedded and embedded~= 0 then
+ local direction, pop = getdirection(current)
+ if direction == righttoleft_code then
+ if not pop then
+ autodir = -1
+ elseif embedded and embedded~= 0 then
+ autodir = embedded
+ else
+ autodir = 0
+ end
+ elseif direction == lefttoright_code then
+ if not pop then
+ autodir = 1
+ elseif embedded and embedded~= 0 then
autodir = embedded
else
autodir = 0
end
- else
- -- message
end
textdir = autodir
setprop(current,"direction",true)
- elseif id == localpar_code then
- local dir = getdir(current)
- if dir == 'TRT' then
+ elseif id == localpar_code and getsubtype(current) == 0 then
+ local direction = getdirection(current)
+ if direction == righttoleft_code then
autodir = -1
- elseif dir == 'TLT' then
+ elseif direction == lefttoright_code then
autodir = 1
end
pardir = autodir
@@ -443,7 +449,7 @@ local function process(start)
end
end
- return tonode(head), done
+ return head
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dig.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-dig.lua
index 61e96c6b6a2..175fc0cc7ef 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dig.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dig.lua
@@ -20,15 +20,12 @@ local report_digits = logs.reporter("typesetting","digits")
local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
-local getfont = nuts.getfont
-local getchar = nuts.getchar
local getid = nuts.getid
local getwidth = nuts.getwidth
+local isglyph = nuts.isglyph
local takeattr = nuts.takeattr
local setlink = nuts.setlink
@@ -99,8 +96,7 @@ function nodes.aligned(head,start,stop,width,how)
end
actions[1] = function(head,start,attr)
- local font = getfont(start)
- local char = getchar(start)
+ local char, font = isglyph(start)
local unic = chardata[font][char].unicode or char
if charbase[unic].category == "nd" then -- ignore unic tables
local oldwidth = getwidth(start)
@@ -111,23 +107,21 @@ actions[1] = function(head,start,attr)
attr%100,div(attr,100),char,unic,newwidth-oldwidth)
end
head, start = nodes.aligned(head,start,start,newwidth,"middle")
- return head, start, true
+ return head, start
end
end
- return head, start, false
+ return head, start
end
function digits.handler(head)
- head = tonut(head)
- local done, current, ok = false, head, false
+ local current = head
while current do
if getid(current) == glyph_code then
local attr = takeattr(current,a_digits)
if attr and attr > 0 then
local action = actions[attr%100] -- map back to low number
if action then
- head, current, ok = action(head,current,attr)
- done = done and ok
+ head, current = action(head,current,attr)
elseif trace_digits then
report_digits("unknown digit trigger %a",attr)
end
@@ -137,7 +131,7 @@ function digits.handler(head)
current = getnext(current)
end
end
- return tonode(head), done
+ return head
end
local m, enabled = 0, false -- a trick to make neighbouring ranges work
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dir.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-dir.lua
index 7fbf5f6d3eb..88c84bd0244 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dir.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dir.lua
@@ -45,8 +45,9 @@ local band = bit32.band
local texsetattribute = tex.setattribute
local unsetvalue = attributes.unsetvalue
-local getnext = nodes.getnext
-local getattr = nodes.getattr
+local nuts = nodes.nuts
+local getnext = nuts.getnext
+local getattr = nuts.getattr
local enableaction = nodes.tasks.enableaction
local tracers = nodes.tracers
@@ -165,24 +166,24 @@ local stoptiming = statistics.stoptiming
--
-- \enabledirectives[typesetters.directions.onetoo]
-function directions.handler(head,_,_,_,direction)
+function directions.handler(head,where,_,_,direction)
local only_one = not getnext(head)
if only_one and not one_too then
- return head, false
+ return head
end
local attr = getattr(head,a_directions)
if not attr or attr == 0 then
- return head, false
+ return head
end
local method = getmethod(attr)
local handler = handlers[method]
if not handler then
- return head, false
+ return head
end
starttiming(directions)
- local head, done = handler(head,direction,only_one)
+ head = handler(head,direction,only_one,where)
stoptiming(directions)
- return head, done
+ return head
end
statistics.register("text directions", function()
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dir.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-dir.mkiv
index d92c9379351..7449a705323 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dir.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dir.mkiv
@@ -18,17 +18,13 @@
\unprotect
-\registerctxluafile{typo-dir}{}
+\registerctxluafile{typo-dir}{optimize}
\registerctxluafile{typo-dha}{}
-\registerctxluafile{typo-dua}{}
-\registerctxluafile{typo-dub}{}
-\doifelsefileexists{typo-duc-new.lua} {
- \registerctxluafile{typo-duc-new}{}
-} {
- \registerctxluafile{typo-duc}{}
-}
+%registerctxluafile{typo-dua}{}
+%registerctxluafile{typo-dub}{}
+\registerctxluafile{typo-duc}{}
-\definesystemattribute[directions][public]
+\definesystemattribute[directions][public,pickup]
\installcorenamespace{directions}
\installcorenamespace{directionsbidimode}
@@ -69,8 +65,9 @@
\expandafter\glet\csname\??directionsbidimode\currentbidistamp\endcsname\currentbidimode}
\appendtoks
+ \edef\p_bidi{\directionsparameter\c!bidi}%
\edef\currentbidistamp
- {\directionsparameter\c!bidi
+ {\p_bidi
:\directionsparameter\c!method
:\directionsparameter\c!fences}%
\expandafter\let\expandafter\currentbidimode\csname\??directionsbidimode\currentbidistamp\endcsname
@@ -83,6 +80,11 @@
\else
\setdirection[\number\directionsbidimode]%
\fi
+ \ifx\p_bidi\v!global
+ \pickupdirectionsattribute
+ \else
+ \forgetdirectionsattribute
+ \fi
\to \everysetupdirections
\appendtoks
@@ -104,8 +106,8 @@
\unexpanded\edef\bidilro{\normalUchar"202D}
\unexpanded\edef\bidirlo{\normalUchar"202E}
-\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi}
-\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi}
+\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdirection\directionlefttoright\fi}
+\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdirection\directionrighttoleft\fi}
\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setdirection[3]\fi}
\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setdirection[4]\fi}
@@ -121,85 +123,85 @@
% bidi test
-\definefontfeature
- [arab]
- [mode=node,language=dflt,script=arab,
- init=yes,medi=yes,fina=yes,isol=yes,
- liga=yes,dlig=yes,rlig=yes,clig=yes,
- mark=yes,mkmk=yes,kern=yes,curs=yes]
-
-\font\Arabic=arabtype*arab at 20pt
-
-\def\LATIN{LATIN} {\setdirection[1]} % enable this
-\def\ARAB {محمد}
-
-\startluacode
- function documentdata.split_tokens(str)
- for s in str:bytes() do
- context.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s))
- end
- end
-\stopluacode
-
-\unexpanded\def\biditest#1#2#3% font text raw
- {\dontleavehmode\hbox
- {\framed[offset=overlay]{\tttf#2}\quad
- \enabletrackers[typesetters.directions]%
- \framed[offset=overlay]{#1#3}\quad
- \disabletrackers[typesetters.directions]%
- \tttf\ctxlua{documentdata.split_tokens([[\detokenize{#3}]])}}}
-
-\startbuffer[bidi-sample]
-\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left
-\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left
-\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
-\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
-\stopbuffer
-
-\startbuffer[bidi-sample]
-\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left
-\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left
-\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right
-\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right
-\stopbuffer
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=off]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=global]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=local]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\startbuffer[bidi-sample]
-\setupdirections[bidi=global]
-
- \hbox{\righttoleft\arabicfont (0001)}\par
- \dontleavehmode\hbox{\righttoleft\arabicfont (0002)}\par
- {\righttoleft\arabicfont (0003)\par}
- {\righttoleft\arabicfont (0004)}\par
- \dontleavehmode{\righttoleft\arabicfont (0005)\par}
- \dontleavehmode{\righttoleft\arabicfont (0006)}\par
- \rtlhbox{\arabicfont (0007)}\par
- \ltrhbox{\arabicfont (0008)}\par
-\dontleavehmode\rtlhbox{\arabicfont (0009)}\par
-\dontleavehmode\ltrhbox{\arabicfont (0010)}\par
-\stopsetups
-
-{\typebuffer[bidi-sample] \getbuffer[bidi-sample]}
-
-\stoptext
+% \definefontfeature
+% [arab]
+% [mode=node,language=dflt,script=arab,
+% init=yes,medi=yes,fina=yes,isol=yes,
+% liga=yes,dlig=yes,rlig=yes,clig=yes,
+% mark=yes,mkmk=yes,kern=yes,curs=yes]
+%
+% \font\Arabic=arabtype*arab at 20pt
+%
+% \def\LATIN{LATIN} {\setdirection[1]} % enable this
+% \def\ARAB {عربي}
+%
+% \startluacode
+% function documentdata.split_tokens(str)
+% for s in str:bytes() do
+% context.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s))
+% end
+% end
+% \stopluacode
+%
+% \unexpanded\def\biditest#1#2#3% font text raw
+% {\dontleavehmode\hbox
+% {\framed[offset=overlay]{\tttf#2}\quad
+% \enabletrackers[typesetters.directions]%
+% \framed[offset=overlay]{#1#3}\quad
+% \disabletrackers[typesetters.directions]%
+% \tttf\ctxlua{documentdata.split_tokens([[\detokenize{#3}]])}}}
+%
+% \startbuffer[bidi-sample]
+% \biditest\Arabic{LATIN BARA}{\lefttoright\relax \LATIN\ \ARAB}\par
+% \biditest\Arabic{BARA LATIN}{\righttoleft\relax \LATIN\ \ARAB}\par
+% \biditest\Arabic{LATIN ARAB}{\lefttoright{\bidilro \LATIN\ \ARAB}}\par % right -> left
+% \biditest\Arabic{LATIN ARAB}{\righttoleft{\bidilro \LATIN\ \ARAB}}\par % right -> left
+% \biditest\Arabic{BARA NITAL}{\lefttoright{\bidirlo \LATIN\ \ARAB}}\par % left -> right
+% \biditest\Arabic{BARA NITAL}{\righttoleft{\bidirlo \LATIN\ \ARAB}}\par % left -> right
+% \stopbuffer
+%
+% \startbuffer[bidi-sample]
+% \biditest\Arabic{LATIN BARA}{\lefttoright\relax \LATIN\ \ARAB}\par
+% \biditest\Arabic{BARA LATIN}{\righttoleft\relax \LATIN\ \ARAB}\par
+% \biditest\Arabic{LATIN ARAB}{\lefttoright\bidilro \LATIN\ \ARAB}\par % right -> left
+% \biditest\Arabic{LATIN ARAB}{\righttoleft\bidilro \LATIN\ \ARAB}\par % right -> left
+% \biditest\Arabic{BARA NITAL}{\lefttoright\bidirlo \LATIN\ \ARAB}\par % left -> right
+% \biditest\Arabic{BARA NITAL}{\righttoleft\bidirlo \LATIN\ \ARAB}\par % left -> right
+% \stopbuffer
+%
+% \startbuffer[bidi-setup]
+% \setupdirections[bidi=off]
+% \stopbuffer
+%
+% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+%
+% \startbuffer[bidi-setup]
+% \setupdirections[bidi=global]
+% \stopbuffer
+%
+% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+%
+% \startbuffer[bidi-setup]
+% \setupdirections[bidi=local]
+% \stopbuffer
+%
+% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+%
+% \startbuffer[bidi-sample]
+% \setupdirections[bidi=global]
+%
+% \hbox{\righttoleft\arabicfont (0001)}\par
+% \dontleavehmode\hbox{\righttoleft\arabicfont (0002)}\par
+% {\righttoleft\arabicfont (0003)\par}
+% {\righttoleft\arabicfont (0004)}\par
+% \dontleavehmode{\righttoleft\arabicfont (0005)\par}
+% \dontleavehmode{\righttoleft\arabicfont (0006)}\par
+% \rtlhbox{\arabicfont (0007)}\par
+% \ltrhbox{\arabicfont (0008)}\par
+% \dontleavehmode\rtlhbox{\arabicfont (0009)}\par
+% \dontleavehmode\ltrhbox{\arabicfont (0010)}\par
+% \stopsetups
+%
+% {\typebuffer[bidi-sample] \getbuffer[bidi-sample]}
+%
+% \stoptext
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-drp.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-drp.lua
index 1e142280fed..9a59891e103 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-drp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-drp.lua
@@ -28,14 +28,11 @@ local enableaction = tasks.enableaction
local disableaction = tasks.disableaction
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
local getchar = nuts.getchar
local getid = nuts.getid
-local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
local getwhd = nuts.getwhd
@@ -59,8 +56,9 @@ local new_kern = nodepool.kern
local insert_before = nuts.insert_before
local insert_after = nuts.insert_after
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
+
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
local variables = interfaces.variables
local v_default = variables.default
@@ -139,9 +137,8 @@ interfaces.implement {
-- a page so this has a low priority
actions[v_default] = function(head,setting)
- local done = false
local id = getid(head)
- if id == localpar_code then
+ if id == localpar_code then -- and getsubtype(head) == 0
-- begin of par
local first = getnext(head)
local indent = false
@@ -173,7 +170,7 @@ actions[v_default] = function(head,setting)
-- 1 char | n chars | skip first quote | ignore punct | keep punct
--
if getattr(first,a_initial) then
- for current in traverse(getnext(first)) do
+ for current in nextnode, getnext(first) do
if getattr(current,a_initial) then
last = current
else
@@ -189,10 +186,10 @@ actions[v_default] = function(head,setting)
local next = getnext(first)
if not next then
-- don't start with a quote or so
- return head, false
+ return head
end
last = nil
- for current in traverse_id(glyph_code,next) do
+ for current in nextglyph, next do
head, first = remove_node(head,first,true)
first = current
last = first
@@ -200,21 +197,21 @@ actions[v_default] = function(head,setting)
end
if not last then
-- no following glyph or so
- return head, false
+ return head
end
else
-- keep quote etc with initial
local next = getnext(first)
if not next then
-- don't start with a quote or so
- return head, false
+ return head
end
- for current in traverse_id(glyph_code,next) do
+ for current in nextglyph, next do
last = current
break
end
if last == first then
- return head, false
+ return head
end
end
elseif kind == "pf" then
@@ -225,8 +222,7 @@ actions[v_default] = function(head,setting)
-- maybe also: get all A. B. etc
local next = getnext(first)
if next then
- for current in traverse_id(glyph_code,next) do
- local char = getchar(current)
+ for current, char in nextglyph, next do
local kind = category(char)
if kind == "po" then
if method[v_last] then
@@ -241,7 +237,7 @@ actions[v_default] = function(head,setting)
end
end
else
- for current in traverse_id(glyph_code,first) do
+ for current in nextglyph, first do
last = current
if length <= 1 then
break
@@ -265,12 +261,12 @@ actions[v_default] = function(head,setting)
end
-- apply font
--- local g = nodes.copy(tonode(current))
+-- local g = nuts.copy(current)
-- g.subtype = 0
-- nodes.handlers.characters(g)
-- nodes.handlers.protectglyphs(g)
-- setchar(current,g.char)
--- nodes.flush_node(g)
+-- nuts.flush_node(g)
-- can be a helper
if ca and ca > 0 then
@@ -319,7 +315,7 @@ actions[v_default] = function(head,setting)
end
--
local hoffset = width + hoffset + distance + (indent and parindent or 0)
- for current in traverse_id(glyph_code,first) do
+ for current in nextglyph, first do
setoffsets(current,-hoffset,-voffset) -- no longer - height here
if current == last then
break
@@ -347,14 +343,12 @@ actions[v_default] = function(head,setting)
if indent then
insert_after(first,first,new_kern(-parindent))
end
- done = true
end
end
- return head, done
+ return head
end
function initials.handler(head)
- head = tonut(head)
local start = head
local attr = nil
while start do
@@ -377,9 +371,8 @@ function initials.handler(head)
if trace_initials then
report_initials("processing initials, alternative %a",alternative)
end
- local head, done = action(head,settings)
- return tonode(head), done
+ return action(head,settings)
end
end
- return tonode(head), false
+ return head
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-drp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-drp.mkiv
index 371ea38d60e..18392510803 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-drp.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-drp.mkiv
@@ -118,7 +118,7 @@
\kern\zeropoint % we need a node
\p_text
\endgroup
- \globallet\typo_initial_handle\relax}
+ \glet\typo_initial_handle\relax}
\let\typo_initial_handle\relax
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dua.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-dua.lua
index 1e48dfb9178..3db5f510ac1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dua.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dua.lua
@@ -68,8 +68,6 @@ local directiondata = characters.directions
local mirrordata = characters.mirrors
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -77,11 +75,11 @@ local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
local getchar = nuts.getchar
local getprop = nuts.getprop
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local setprop = nuts.setprop
local setchar = nuts.setchar
-local setdir = nuts.setdir
+local setdirection = nuts.setdirection
----- setattrlist = nuts.setattrlist
local remove_node = nuts.remove
@@ -89,10 +87,10 @@ local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local nodepool = nuts.pool
-local new_textdir = nodepool.textdir
+local new_direction = nodepool.direction
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
@@ -101,23 +99,28 @@ local vlist_code = nodecodes.vlist
local math_code = nodecodes.math
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local parfillskip_code = skipcodes.parfillskip
------ object_replacement = 0xFFFC -- object replacement character
-local maximum_stack = 60 -- probably spec but not needed
+local parfillskip_code = gluecodes.parfillskip
+
+local dirvalues = nodes.dirvalues
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
+
+local maximum_stack = 60
local directions = typesetters.directions
local setcolor = directions.setcolor
------ a_directions = attributes.private('directions')
-
local remove_controls = true directives.register("typesetters.directions.one.removecontrols",function(v) remove_controls = v end)
-local trace_directions = false trackers .register("typesetters.directions.one", function(v) trace_directions = v end)
-local trace_details = false trackers .register("typesetters.directions.one.details", function(v) trace_details = v end)
-
local report_directions = logs.reporter("typesetting","directions one")
+local trace_directions = false trackers .register("typesetters.directions", function(v) trace_directions = v end)
+local trace_details = false trackers .register("typesetters.directions.details", function(v) trace_details = v end)
+
+
+
+
local whitespace = {
lre = true,
rle = true,
@@ -234,13 +237,19 @@ local function build_list(head) -- todo: store node pointer ... saves loop
list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 }
current = getnext(current)
elseif id == dir_code then
- local dir = getdir(current)
- if dir == "+TLT" then
- list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 }
- elseif dir == "+TRT" then
- list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 }
- elseif dir == "-TLT" or dir == "-TRT" then
- list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ local direction, pop = getdirection(current)
+ if direction == lefttoright_code then
+ if pop then
+ list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ else
+ list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 }
+ end
+ elseif direction == righttoleft_code then
+ if pop then
+ list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ else
+ list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 }
+ end
else
list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, id = id } -- object replacement character
end
@@ -323,27 +332,33 @@ local function find_run_limit_b_s_ws_on(list,start,limit)
return start
end
-local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar)
- local id = getid(head)
- if id == localpar_code then
- if getdir(head) == "TRT" then
- return 1, "TRT", true
- else
- return 0, "TLT", true
+local function get_baselevel(head,list,size,direction)
+ -- This is an adapted version:
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
+ elseif getid(head) == localpar_code and getsubtype(head) == 0 then
+ direction = getdirection(head)
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
end
- else
- -- P2, P3
- for i=1,size do
- local entry = list[i]
- local direction = entry.direction
- if direction == "r" or direction == "al" then
- return 1, "TRT", true
- elseif direction == "l" then
- return 0, "TLT", true
- end
+ end
+ -- for old times sake we we handle strings too
+ if direction == "TLT" then
+ return lefttoright_code, true
+ elseif direction == "TRT" then
+ return righttoleft_code, true
+ end
+ -- P2, P3
+ for i=1,size do
+ local entry = list[i]
+ local direction = entry.direction
+ if direction == "r" or direction == "al" then
+ return righttoleft_code, true
+ elseif direction == "l" then
+ return lefttoright_code, true
end
- return 0, "TLT", false
end
+ return lefttoright_code, false
end
local function resolve_explicit(list,size,baselevel)
@@ -409,7 +424,7 @@ local function resolve_explicit(list,size,baselevel)
end
-- X7
elseif direction == "pdf" then
- if nofstack < maximum_stack then
+ if noifstack > 0 then
local stacktop = stack[nofstack]
nofstack = nofstack - 1
level = stacktop[1]
@@ -418,7 +433,7 @@ local function resolve_explicit(list,size,baselevel)
entry.direction = "bn"
entry.remove = true
elseif trace_directions then
- report_directions("stack overflow at position %a with direction %a",i,direction)
+ report_directions("stack underflow at position %a with direction %a",i,direction)
end
-- X6
else
@@ -679,8 +694,6 @@ local function resolve_levels(list,size,baselevel)
end
end
--- This is not ok but we keep it as-is:
-
local function insert_dir_points(list,size)
-- L2, but no actual reversion is done, we simply annotate where
-- begindir/endddir node will be inserted.
@@ -697,11 +710,11 @@ local function insert_dir_points(list,size)
local begindir = nil
local enddir = nil
if level % 2 == 1 then
- begindir = "+TRT"
- enddir = "-TRT"
+ begindir = righttoleft_code
+ enddir = righttoleft_code
else
- begindir = "+TLT"
- enddir = "-TLT"
+ begindir = lefttoright_code
+ enddir = lefttoright_code
end
for i=1,size do
local entry = list[i]
@@ -730,7 +743,6 @@ end
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
while current do
if index > size then
report_directions("fatal error, size mismatch")
@@ -751,34 +763,31 @@ local function apply_to_list(list,size,head,pardir)
setcolor(current,direction,false,mirror)
end
elseif id == hlist_code or id == vlist_code then
- setdir(current,pardir) -- is this really needed?
+ setdirection(current,pardir) -- is this really needed?
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- local d = new_textdir(enddir)
- setprop(d,"directions",true)
+ local d = new_direction(enddir,true)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
enddir = false
- done = true
end
elseif begindir then
- if id == localpar_code then
+ if id == localpar_code and getsubtype(current) == 0 then
-- localpar should always be the 1st node
- local d = new_textdir(begindir)
- setprop(d,"directions",true)
+ local d = new_direction(begindir)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
begindir = nil
- done = true
end
end
if begindir then
- local d = new_textdir(begindir)
- setprop(d,"directions",true)
+ local d = new_direction(begindir)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
- done = true
end
local skip = entry.skip
if skip and skip > 0 then
@@ -788,30 +797,28 @@ local function apply_to_list(list,size,head,pardir)
end
end
if enddir then
- local d = new_textdir(enddir)
- setprop(d,"directions",true)
+ local d = new_direction(enddir,true)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
- done = true
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
index = index + 1
end
- return head, done
+ return head
end
-local function process(head)
- head = tonut(head)
+local function process(head,direction,only_one,where)
+ -- This is an adapted version:
local list, size = build_list(head)
- local baselevel, pardir, dirfound = get_baselevel(head,list,size) -- we always have an inline dir node in context
+ local baselevel, dirfound = get_baselevel(head,list,size,direction)
if not dirfound and trace_details then
report_directions("no initial direction found, gambling")
end
@@ -825,8 +832,7 @@ local function process(head)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,baselevel)
end
directions.installhandler(interfaces.variables.one,process)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-dub.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-dub.lua
index d0747ae6ccd..f27e4047660 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-dub.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-dub.lua
@@ -55,8 +55,6 @@ local mirrordata = characters.mirrors
local textclassdata = characters.textclasses
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -65,11 +63,11 @@ local getlist = nuts.getlist
local getchar = nuts.getchar
local getattr = nuts.getattr
local getprop = nuts.getprop
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local setprop = nuts.setprop
local setchar = nuts.setchar
-local setdir = nuts.setdir
+local setdirection = nuts.setdirection
local setattrlist = nuts.setattrlist
local remove_node = nuts.remove
@@ -77,10 +75,10 @@ local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local nodepool = nuts.pool
-local new_textdir = nodepool.textdir
+local new_direction = nodepool.direction
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
@@ -89,24 +87,29 @@ local vlist_code = nodecodes.vlist
local math_code = nodecodes.math
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local parfillskip_code = skipcodes.parfillskip
-local maximum_stack = 0xFF -- unicode: 60, will be jumped to 125, we don't care too much
+local parfillskip_code = gluecodes.parfillskip
+
+local dirvalues = nodes.dirvalues
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
+
+local maximum_stack = 0xFF
+
+local a_directions = attributes.private('directions')
local directions = typesetters.directions
local setcolor = directions.setcolor
local getfences = directions.getfences
-local a_directions = attributes.private('directions')
-
local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end)
----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end)
-local trace_directions = false trackers .register("typesetters.directions.two", function(v) trace_directions = v end)
-local trace_details = false trackers .register("typesetters.directions.two.details", function(v) trace_details = v end)
-local trace_list = false trackers .register("typesetters.directions.two.list", function(v) trace_list = v end)
+local report_directions = logs.reporter("typesetting","directions three")
-local report_directions = logs.reporter("typesetting","directions two")
+local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end)
+local trace_details = false trackers.register("typesetters.directions.details", function(v) trace_details = v end)
+local trace_list = false trackers.register("typesetters.directions.list", function(v) trace_list = v end)
-- strong (old):
--
@@ -117,7 +120,7 @@ local report_directions = logs.reporter("typesetting","directions two")
-- lre : left to right embedding
-- rle : left to left embedding
-- al : right to legt arabic (esp punctuation issues)
-
+--
-- weak:
--
-- en : english number
@@ -127,23 +130,23 @@ local report_directions = logs.reporter("typesetting","directions two")
-- cs : common number separator
-- nsm : nonspacing mark
-- bn : boundary neutral
-
+--
-- neutral:
--
-- b : paragraph separator
-- s : segment separator
-- ws : whitespace
-- on : other neutrals
-
+--
-- interesting: this is indeed better (and more what we expect i.e. we already use this split
-- in the old original (also these isolates)
-
+--
-- strong (new):
--
-- l : left to right
-- r : right to left
-- al : right to left arabic (esp punctuation issues)
-
+--
-- explicit: (new)
--
-- lro : left to right override
@@ -206,27 +209,28 @@ end
local function show_done(list,size)
local joiner = utfchar(0x200C)
local result = { }
+ local format = formatters["<%s>"]
for i=1,size do
local entry = list[i]
local character = entry.char
local begindir = entry.begindir
local enddir = entry.enddir
if begindir then
- result[#result+1] = formatters["<%s>"](begindir)
+ result[#result+1] = format(begindir)
end
if entry.remove then
-- continue
elseif character == 0xFFFC then
- result[#result+1] = formatters["<%s>"]("?")
+ result[#result+1] = format("?")
elseif character == 0x0020 then
- result[#result+1] = formatters["<%s>"](" ")
+ result[#result+1] = format(" ")
elseif character >= 0x202A and character <= 0x202C then
- result[#result+1] = formatters["<%s>"](entry.original)
+ result[#result+1] = format(entry.original)
else
result[#result+1] = utfchar(character)
end
if enddir then
- result[#result+1] = formatters["<%s>"](enddir)
+ result[#result+1] = format(enddir)
end
end
return concat(result,joiner)
@@ -236,17 +240,7 @@ end
-- char is only used for mirror, so in fact we can as well only store it for
-- glyphs only
--- using metatable is slightly faster so maybe some day ...
-
--- local space = { char = 0x0020, direction = "ws", original = "ws" }
--- local lre = { char = 0x202A, direction = "lre", original = "lre" }
--- local rle = { char = 0x202B, direction = "rle", original = "rle" }
--- local pdf = { char = 0x202C, direction = "pdf", original = "pdf" }
--- local object = { char = 0xFFFC, direction = "on", original = "on" }
---
--- local t = { level = 0 } setmetatable(t,space) list[size] = t
-
-local function build_list(head) -- todo: store node pointer ... saves loop
+local function build_list(head)
-- P1
local current = head
local list = { }
@@ -282,13 +276,19 @@ local function build_list(head) -- todo: store node pointer ... saves loop
list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 }
current = getnext(current)
elseif id == dir_code then
- local dir = getdir(current)
- if dir == "+TLT" then
- list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 }
- elseif dir == "+TRT" then
- list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 }
- elseif dir == "-TLT" or dir == "-TRT" then
- list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ local direction, pop = getdirection(current)
+ if direction == lefttoright_code then
+ if pop then
+ list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ else
+ list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 }
+ end
+ elseif direction == righttoleft_code then
+ if pop then
+ list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 }
+ else
+ list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 }
+ end
else
list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, id = id } -- object replacement character
end
@@ -343,8 +343,8 @@ end
local function resolve_fences(list,size,start,limit)
-- N0: funny effects, not always better, so it's an option
- local stack = { }
- local top = 0
+ local stack = { }
+ local nofstack = 0
for i=start,limit do
local entry = list[i]
if entry.direction == "on" then
@@ -355,15 +355,15 @@ local function resolve_fences(list,size,start,limit)
entry.mirror = mirror
entry.class = class
if class == "open" then
- top = top + 1
- stack[top] = { mirror, i, false }
- elseif top == 0 then
+ nofstack = nofstack + 1
+ stack[nofstack] = { mirror, i, false }
+ elseif nofstack == 0 then
-- skip
elseif class == "close" then
- while top > 0 do
- local s = stack[top]
- if s[1] == char then
- local open = s[2]
+ while nofstack > 0 do
+ local stacktop = stack[nofstack]
+ if stacktop[1] == char then
+ local open = stacktop[2]
local close = i
list[open ].paired = close
list[close].paired = open
@@ -371,7 +371,7 @@ local function resolve_fences(list,size,start,limit)
else
-- do we mirror or not
end
- top = top - 1
+ nofstack = nofstack - 1
end
end
end
@@ -394,27 +394,32 @@ end
-- the action
-local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar)
- local id = getid(head)
- if id == localpar_code then
- if getdir(head) == "TRT" then
- return 1, "TRT", true
- else
- return 0, "TLT", true
+local function get_baselevel(head,list,size,direction)
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
+ elseif getid(head) == localpar_code and getsubtype(head) == 0 then
+ direction = getdirection(head)
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
end
- else
- -- P2, P3
- for i=1,size do
- local entry = list[i]
- local direction = entry.direction
- if direction == "r" or direction == "al" then -- and an ?
- return 1, "TRT", true
- elseif direction == "l" then
- return 0, "TLT", true
- end
+ end
+ -- for old times sake we we handle strings too
+ if direction == "TLT" then
+ return lefttoright_code, true
+ elseif direction == "TRT" then
+ return righttoleft_code, true
+ end
+ -- P2, P3
+ for i=1,size do
+ local entry = list[i]
+ local direction = entry.direction
+ if direction == "r" or direction == "al" then -- and an ?
+ return righttoleft_code, true
+ elseif direction == "l" then
+ return lefttoright_code, true
end
- return 0, "TLT", false
end
+ return lefttoright_code, false
end
local function resolve_explicit(list,size,baselevel)
@@ -480,16 +485,17 @@ local function resolve_explicit(list,size,baselevel)
end
-- X7
elseif direction == "pdf" then
- if nofstack < maximum_stack then
+ if nofstack > 0 then
local stacktop = stack[nofstack]
- nofstack = nofstack - 1
level = stacktop[1]
override = stacktop[2]
+ nofstack = nofstack - 1
entry.level = level
entry.direction = "bn"
entry.remove = true
elseif trace_directions then
- report_directions("stack overflow at position %a with direction %a",i,direction)
+ report_directions("stack underflow at position %a with direction %a",
+ i, direction)
end
-- X6
else
@@ -688,33 +694,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter)
end
end
--- local function resolve_implicit(list,size,start,limit,orderbefore,orderafter)
--- -- I1
--- for i=start,limit do
--- local entry = list[i]
--- local level = entry.level
--- if level % 2 ~= 1 then -- not odd(level)
--- local direction = entry.direction
--- if direction == "r" then
--- entry.level = level + 1
--- elseif direction == "an" or direction == "en" then
--- entry.level = level + 2
--- end
--- end
--- end
--- -- I2
--- for i=start,limit do
--- local entry = list[i]
--- local level = entry.level
--- if level % 2 == 1 then -- odd(level)
--- local direction = entry.direction
--- if direction == "l" or direction == "en" or direction == "an" then
--- entry.level = level + 1
--- end
--- end
--- end
--- end
-
local function resolve_implicit(list,size,start,limit,orderbefore,orderafter,baselevel)
for i=start,limit do
local entry = list[i]
@@ -814,52 +793,6 @@ local function resolve_levels(list,size,baselevel,analyze_fences)
end
end
--- local function insert_dir_points(list,size)
--- -- L2, but no actual reversion is done, we simply annotate where
--- -- begindir/endddir node will be inserted.
--- local maxlevel = 0
--- local finaldir = false
--- for i=1,size do
--- local level = list[i].level
--- if level > maxlevel then
--- maxlevel = level
--- end
--- end
--- for level=0,maxlevel do
--- local started = false
--- local begindir = nil
--- local enddir = nil
--- if level % 2 == 1 then
--- begindir = "+TRT"
--- enddir = "-TRT"
--- else
--- begindir = "+TLT"
--- enddir = "-TLT"
--- end
--- for i=1,size do
--- local entry = list[i]
--- if entry.level >= level then
--- if not started then
--- entry.begindir = begindir
--- started = true
--- end
--- else
--- if started then
--- list[i-1].enddir = enddir
--- started = false
--- end
--- end
--- end
--- -- make sure to close the run at end of line
--- if started then
--- finaldir = enddir
--- end
--- end
--- if finaldir then
--- list[size].enddir = finaldir
--- end
--- end
-
local function insert_dir_points(list,size)
-- L2, but no actual reversion is done, we simply annotate where
-- begindir/endddir node will be inserted.
@@ -877,12 +810,12 @@ local function insert_dir_points(list,size)
local enddir -- = nil
local prev -- = nil
if toggle then
- begindir = "+TLT"
- enddir = "-TLT"
+ begindir = lefttoright_code
+ enddir = lefttoright_code
toggle = false
else
- begindir = "+TRT"
- enddir = "-TRT"
+ begindir = righttoleft_code
+ enddir = righttoleft_code
toggle = true
end
for i=1,size do
@@ -922,7 +855,7 @@ local function insert_dir_points(list,size)
if trace_list and n > 1 then
report_directions("unbalanced list")
end
- last.enddir = s[n] == "+TRT" and "-TRT" or "-TLT"
+ last.enddir = s[n] == righttoleft_code and righttoleft_code or lefttoright_code
end
end
end
@@ -930,7 +863,6 @@ end
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
if trace_list then
report_directions("start run")
end
@@ -964,34 +896,31 @@ local function apply_to_list(list,size,head,pardir)
setcolor(current,direction,false,mirror)
end
elseif id == hlist_code or id == vlist_code then
- setdir(current,pardir) -- is this really needed?
+ setdirection(current,pardir) -- is this really needed?
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- local d = new_textdir(enddir)
- setprop(d,"directions",true)
+ local d = new_direction(enddir,true)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
enddir = false
- done = true
end
elseif begindir then
- if id == localpar_code then
+ if id == localpar_code and getsubtype(current) == 0 then
-- localpar should always be the 1st node
- local d = new_textdir(begindir)
- setprop(d,"directions",true)
+ local d = new_direction(begindir)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
begindir = nil
- done = true
end
end
if begindir then
- local d = new_textdir(begindir)
- setprop(d,"directions",true)
+ local d = new_direction(begindir)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
- done = true
end
local skip = entry.skip
if skip and skip > 0 then
@@ -1001,18 +930,16 @@ local function apply_to_list(list,size,head,pardir)
end
end
if enddir then
- local d = new_textdir(enddir)
- setprop(d,"directions",true)
+ local d = new_direction(enddir,true)
+ -- setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
- done = true
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
@@ -1021,17 +948,16 @@ local function apply_to_list(list,size,head,pardir)
if trace_list then
report_directions("stop run")
end
- return head, done
+ return head
end
-local function process(head)
- head = tonut(head)
+local function process(head,direction,only_one,where)
-- for the moment a whole paragraph property
local attr = getattr(head,a_directions)
local analyze_fences = getfences(attr)
--
local list, size = build_list(head)
- local baselevel, pardir, dirfound = get_baselevel(head,list,size) -- we always have an inline dir node in context
+ local baselevel, dirfound = get_baselevel(head,list,size,direction)
if not dirfound and trace_details then
report_directions("no initial direction found, gambling")
end
@@ -1045,8 +971,7 @@ local function process(head)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,baselevel)
end
directions.installhandler(interfaces.variables.two,process)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-duc.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-duc.lua
index 52074019047..f91fc4d647d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-duc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-duc.lua
@@ -7,8 +7,6 @@ if not modules then modules = { } end modules ['typo-duc'] = {
comment = "Unicode bidi (sort of) variant c",
}
--- Will be replaced by typo-duc-new.lua!
-
-- This is a follow up on typo-uda which itself is a follow up on t-bidi by Khaled Hosny which
-- in turn is based on minibidi.c from Arabeyes. This is a further optimizations, as well as
-- an update on some recent unicode bidi developments. There is (and will) also be more control
@@ -58,8 +56,6 @@ local mirrordata = characters.mirrors
local textclassdata = characters.textclasses
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -68,11 +64,12 @@ local getlist = nuts.getlist
local getchar = nuts.getchar
local getattr = nuts.getattr
local getprop = nuts.getprop
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
+local isglyph = nuts.isglyph
local setprop = nuts.setprop
local setchar = nuts.setchar
-local setdir = nuts.setdir
+local setdirection = nuts.setdirection
local setattrlist = nuts.setattrlist
local properties = nodes.properties.data
@@ -82,10 +79,10 @@ local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local nodepool = nuts.pool
-local new_textdir = nodepool.textdir
+local new_direction = nodepool.direction
local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
@@ -94,25 +91,30 @@ local vlist_code = nodecodes.vlist
local math_code = nodecodes.math
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local parfillskip_code = skipcodes.parfillskip
-local maximum_stack = 0xFF -- unicode: 60, will be jumped to 125, we don't care too much
+local parfillskip_code = gluecodes.parfillskip
+
+local dirvalues = nodes.dirvalues
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
+
+local maximum_stack = 0xFF
+
+local a_directions = attributes.private('directions')
local directions = typesetters.directions
local setcolor = directions.setcolor
local getfences = directions.getfences
-local a_directions = attributes.private('directions')
-
local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end)
----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end)
-local trace_directions = false trackers.register("typesetters.directions.three", function(v) trace_directions = v end)
-local trace_details = false trackers.register("typesetters.directions.three.details", function(v) trace_details = v end)
-local trace_list = false trackers.register("typesetters.directions.three.list", function(v) trace_list = v end)
-
local report_directions = logs.reporter("typesetting","directions three")
+local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end)
+local trace_details = false trackers.register("typesetters.directions.details", function(v) trace_details = v end)
+local trace_list = false trackers.register("typesetters.directions.list", function(v) trace_list = v end)
+
-- strong (old):
--
-- l : left to right
@@ -122,7 +124,7 @@ local report_directions = logs.reporter("typesetting","directions three")
-- lre : left to right embedding
-- rle : left to left embedding
-- al : right to legt arabic (esp punctuation issues)
-
+--
-- weak:
--
-- en : english number
@@ -132,23 +134,23 @@ local report_directions = logs.reporter("typesetting","directions three")
-- cs : common number separator
-- nsm : nonspacing mark
-- bn : boundary neutral
-
+--
-- neutral:
--
-- b : paragraph separator
-- s : segment separator
-- ws : whitespace
-- on : other neutrals
-
+--
-- interesting: this is indeed better (and more what we expect i.e. we already use this split
-- in the old original (also these isolates)
-
+--
-- strong (new):
--
-- l : left to right
-- r : right to left
-- al : right to left arabic (esp punctuation issues)
-
+--
-- explicit: (new)
--
-- lro : left to right override
@@ -241,20 +243,20 @@ end
-- keeping the list and overwriting doesn't save much runtime, only a few percent
-- char is only used for mirror, so in fact we can as well only store it for
-- glyphs only
-
+--
-- tracking what direction is used and skipping tests is not faster (extra kind of
-- compensates gain)
-local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0 } }
-local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0 } }
-local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0 } }
-local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } }
-local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0 } }
+local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0, skip = 0 } }
+local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0, skip = 0 } }
+local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0, skip = 0 } }
+local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0, skip = 0 } }
+local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0, skip = 0 } }
local stack = table.setmetatableindex("table") -- shared
local list = { } -- shared
-local function build_list(head) -- todo: store node pointer ... saves loop
+local function build_list(head,where)
-- P1
local current = head
local size = 0
@@ -263,6 +265,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop
local id = getid(current)
local p = properties[current]
if p and p.directions then
+ -- tricky as dirs can be injected in between
local skip = 0
local last = id
current = getnext(current)
@@ -285,6 +288,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop
elseif id == glyph_code then
local chr = getchar(current)
local dir = directiondata[chr]
+ -- could also be a metatable
list[size] = { char = chr, direction = dir, original = dir, level = 0 }
current = getnext(current)
-- if not list[dir] then list[dir] = true end -- not faster when we check for usage
@@ -292,13 +296,11 @@ local function build_list(head) -- todo: store node pointer ... saves loop
list[size] = setmetatable({ },mt_space)
current = getnext(current)
elseif id == dir_code then
- local dir = getdir(current)
- if dir == "+TLT" then
- list[size] = setmetatable({ },mt_lre)
- elseif dir == "+TRT" then
- list[size] = setmetatable({ },mt_rle)
- elseif dir == "-TLT" or dir == "-TRT" then
- list[size] = setmetatable({ },mt_pdf)
+ local dir, pop = getdirection(current)
+ if dir == lefttoright_code then
+ list[size] = setmetatable({ },pop and mt_pdf or mt_lre)
+ elseif dir == righttoleft_code then
+ list[size] = setmetatable({ },pop and mt_pdf or mt_rle)
else
list[size] = setmetatable({ id = id },mt_object)
end
@@ -351,6 +353,8 @@ end
-- ש ( ל ( א ) כ ) 2-8,4-6
-- ש ( ל [ א ] כ ) 2-8,4-6
+local fencestack = table.setmetatableindex("table")
+
local function resolve_fences(list,size,start,limit)
-- N0: funny effects, not always better, so it's an option
local nofstack = 0
@@ -365,15 +369,14 @@ local function resolve_fences(list,size,start,limit)
entry.class = class
if class == "open" then
nofstack = nofstack + 1
- local stacktop = stack[nofstack]
+ local stacktop = fencestack[nofstack]
stacktop[1] = mirror
stacktop[2] = i
- stacktop[3] = false -- not used
elseif nofstack == 0 then
-- skip
elseif class == "close" then
while nofstack > 0 do
- local stacktop = stack[nofstack]
+ local stacktop = fencestack[nofstack]
if stacktop[1] == char then
local open = stacktop[2]
local close = i
@@ -407,25 +410,31 @@ end
-- the action
local function get_baselevel(head,list,size,direction)
- if not direction and getid(head) == localpar_code then
- direction = getdir(head)
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
+ elseif getid(head) == localpar_code and getsubtype(head) == 0 then
+ direction = getdirection(head)
+ if direction == lefttoright_code or direction == righttoleft_code then
+ return direction, true
+ end
end
- if direction == "TRT" then
- return 1, "TRT", true
- elseif direction == "TLT" then
- return 0, "TLT", true
+ -- for old times sake we we handle strings too
+ if direction == "TLT" then
+ return lefttoright_code, true
+ elseif direction == "TRT" then
+ return righttoleft_code, true
end
- -- P2, P3:
+ -- P2, P3
for i=1,size do
local entry = list[i]
local direction = entry.direction
if direction == "r" or direction == "al" then -- and an ?
- return 1, "TRT", true
+ return righttoleft_code, true
elseif direction == "l" then
- return 0, "TLT", true
+ return lefttoright_code, true
end
end
- return 0, "TLT", false
+ return lefttoright_code, false
end
local function resolve_explicit(list,size,baselevel)
@@ -499,7 +508,7 @@ local function resolve_explicit(list,size,baselevel)
end
-- X7
elseif direction == "pdf" then
- if nofstack < maximum_stack then
+ if nofstack > 0 then
local stacktop = stack[nofstack]
level = stacktop[1]
override = stacktop[2]
@@ -508,7 +517,11 @@ local function resolve_explicit(list,size,baselevel)
entry.direction = "bn"
entry.remove = true
elseif trace_directions then
- report_directions("stack overflow at position %a with direction %a",i,direction)
+ report_directions("stack underflow at position %a with direction %a",
+ i, direction)
+ else
+ report_directions("stack underflow at position %a with direction %a: %s",
+ i, direction, show_list(list,size))
end
-- X6
else
@@ -518,11 +531,6 @@ local function resolve_explicit(list,size,baselevel)
end
end
end
--- else
--- for i=1,size do
--- list[i].level = baselevel
--- end
--- end
-- X8 (reset states and overrides after paragraph)
end
@@ -726,33 +734,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter)
end
end
--- local function resolve_implicit(list,size,start,limit,orderbefore,orderafter)
--- -- I1
--- for i=start,limit do
--- local entry = list[i]
--- local level = entry.level
--- if level % 2 ~= 1 then -- not odd(level)
--- local direction = entry.direction
--- if direction == "r" then
--- entry.level = level + 1
--- elseif direction == "an" or direction == "en" then
--- entry.level = level + 2
--- end
--- end
--- end
--- -- I2
--- for i=start,limit do
--- local entry = list[i]
--- local level = entry.level
--- if level % 2 == 1 then -- odd(level)
--- local direction = entry.direction
--- if direction == "l" or direction == "en" or direction == "an" then
--- entry.level = level + 1
--- end
--- end
--- end
--- end
-
local function resolve_implicit(list,size,start,limit,orderbefore,orderafter,baselevel)
for i=start,limit do
local entry = list[i]
@@ -852,60 +833,6 @@ local function resolve_levels(list,size,baselevel,analyze_fences)
end
end
--- local function insert_dir_points(list,size)
--- -- L2, but no actual reversion is done, we simply annotate where
--- -- begindir/endddir node will be inserted.
--- local maxlevel = 0
--- local finaldir = false
--- local toggle = true
--- for i=1,size do
--- local level = list[i].level
--- if level > maxlevel then
--- maxlevel = level
--- end
--- end
--- for level=0,maxlevel do
--- local started -- = false
--- local begindir -- = nil
--- local enddir -- = nil
--- local prev -- = nil
--- if toggle then
--- begindir = "+TLT"
--- enddir = "-TLT"
--- toggle = false
--- else
--- begindir = "+TRT"
--- enddir = "-TRT"
--- toggle = true
--- end
--- for i=1,size do
--- local entry = list[i]
--- if entry.level >= level then
--- if not started then
--- entry.begindir = begindir
--- started = true
--- end
--- else
--- if started then
--- prev.enddir = enddir
--- started = false
--- end
--- end
--- prev = entry
--- end
--- -- make sure to close the run at end of line
--- if started then
--- finaldir = enddir
--- end
--- end
--- if finaldir then
--- list[size].enddir = finaldir
--- end
--- for i=1,size do
--- print("<",i,list[i].level,list[i].begindir,list[i].enddir)
--- end
--- end
-
local stack = { }
local function insert_dir_points(list,size)
@@ -925,12 +852,12 @@ local function insert_dir_points(list,size)
local enddir -- = nil
local prev -- = nil
if toggle then
- begindir = "+TLT"
- enddir = "-TLT"
+ begindir = lefttoright_code
+ enddir = lefttoright_code
toggle = false
else
- begindir = "+TRT"
- enddir = "-TRT"
+ begindir = righttoleft_code
+ enddir = righttoleft_code
toggle = true
end
for i=1,size do
@@ -969,15 +896,18 @@ local function insert_dir_points(list,size)
if trace_list and n > 1 then
report_directions("unbalanced list")
end
- last.enddir = stack[n] == "+TRT" and "-TRT" or "-TLT"
+ last.enddir = stack[n]
end
end
end
+-- We flag nodes that can be skipped when we see them again but because whatever
+-- mechanism can injetc dir nodes that then are not flagged, we don't flag dir
+-- nodes that we inject here.
+
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
if trace_list then
report_directions("start run")
end
@@ -990,7 +920,12 @@ local function apply_to_list(list,size,head,pardir)
local entry = list[index]
local begindir = entry.begindir
local enddir = entry.enddir
- local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end
+ local p = properties[current]
+ if p then
+ p.directions = true
+ else
+ properties[current] = { directions = true }
+ end
if id == glyph_code then
local mirror = entry.mirror
if mirror then
@@ -1011,55 +946,43 @@ local function apply_to_list(list,size,head,pardir)
setcolor(current,direction,false,mirror)
end
elseif id == hlist_code or id == vlist_code then
- setdir(current,pardir) -- is this really needed?
+ setdirection(current,pardir) -- is this really needed?
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- local d = new_textdir(enddir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head = insert_node_before(head,current,d)
+ head = insert_node_before(head,current,new_direction(enddir,true))
enddir = false
- done = true
end
elseif begindir then
- if id == localpar_code then
+ if id == localpar_code and getsubtype(current) == 0 then
-- localpar should always be the 1st node
- local d = new_textdir(begindir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head, current = insert_node_after(head,current,d)
+ head, current = insert_node_after(head,current,new_direction(begindir))
begindir = nil
- done = true
end
end
if begindir then
- local d = new_textdir(begindir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head = insert_node_before(head,current,d)
- done = true
+ head = insert_node_before(head,current,new_direction(begindir))
end
local skip = entry.skip
if skip and skip > 0 then
for i=1,skip do
current = getnext(current)
- local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end
+ local p = properties[current]
+ if p then
+ p.directions = true
+ else
+ properties[current] = { directions = true }
+ end
end
end
if enddir then
- local d = new_textdir(enddir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head, current = insert_node_after(head,current,d)
- done = true
+ head, current = insert_node_after(head,current,new_direction(enddir,true))
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
@@ -1068,7 +991,7 @@ local function apply_to_list(list,size,head,pardir)
if trace_list then
report_directions("stop run")
end
- return head, done
+ return head
end
-- If needed we can optimize for only_one. There is no need to do anything
@@ -1077,16 +1000,15 @@ end
-- have more than one node. Actually, we only enter this function when we
-- do have a glyph!
-local function process(head,direction,only_one)
- head = tonut(head)
+local function process(head,direction,only_one,where)
-- for the moment a whole paragraph property
local attr = getattr(head,a_directions)
local analyze_fences = getfences(attr)
--
- local list, size = build_list(head)
- local baselevel, pardir, dirfound = get_baselevel(head,list,size,direction) -- we always have an inline dir node in context
+ local list, size = build_list(head,where)
+ local baselevel, dirfound = get_baselevel(head,list,size,direction)
if trace_details then
- report_directions("analyze: direction %a, baselevel %a",dirfound and pardir or "unknown",baselevel or 1)
+ report_directions("analyze: baselevel %a",baselevel == righttoleft_code and "r2l" or "l2r")
report_directions("before : %s",show_list(list,size,"original"))
end
resolve_explicit(list,size,baselevel)
@@ -1096,8 +1018,12 @@ local function process(head,direction,only_one)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,baselevel)
end
-directions.installhandler(interfaces.variables.three,process)
+local variables = interfaces.variables
+
+directions.installhandler(variables.one, process) -- for old times sake
+directions.installhandler(variables.two, process) -- for old times sake
+directions.installhandler(variables.three, process) -- for old times sake
+directions.installhandler(variables.unicode,process)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-fkr.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-fkr.lua
index a1135d0f321..1fd08526c3a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-fkr.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-fkr.lua
@@ -7,12 +7,10 @@ if not modules then modules = { } end modules ['typo-fkr'] = {
}
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getid = nuts.getid
local getnext = nuts.getnext
-local getchar = nuts.getchar
-local getfont = nuts.getfont
local getattr = nuts.getattr
+local isglyph = nuts.isglyph
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
@@ -32,20 +30,15 @@ local a_extrakern = attributes.private("extrafontkern")
typesetters.fontkerns = { }
function typesetters.fontkerns.handler(head)
- local kepthead = head
- local head = tonut(head)
local current = head
local lastfont = nil
local lastchar = nil
local lastdata = nil
- local done = false
while current do
- local id = getid(current)
- if id == glyph_code then
+ local char, font = isglyph(current)
+ if char then
local a = getattr(current,a_extrakern)
if a then
- local char = getchar(current)
- local font = getfont(current)
if font ~= lastfont then
if a > 0 and lastchar then
if not lastdata then
@@ -64,7 +57,6 @@ function typesetters.fontkerns.handler(head)
end
if kern ~= 0 then
head, current = insert_before(head,current,new_kern(kern))
- done = true
end
lastdata = data
else
@@ -77,7 +69,6 @@ function typesetters.fontkerns.handler(head)
local kern = getkernpair(lastdata,lastchar,char)
if kern ~= 0 then
head, current = insert_before(head,current,new_kern(kern))
- done = true
end
end
lastchar = char
@@ -94,7 +85,7 @@ function typesetters.fontkerns.handler(head)
end
current = getnext(current)
end
- return kepthead, done
+ return head
end
if context then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua
index 4fb82ce4499..0489807327c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua
@@ -30,7 +30,6 @@ local context = context
local implement = interfaces.implement
local nuts = nodes.nuts
-local tonut = nuts.tonut
local tonode = nuts.tonode
local getnext = nuts.getnext
@@ -38,7 +37,6 @@ local getprev = nuts.getprev
local getboth = nuts.getboth
local setboth = nuts.setboth
local getid = nuts.getid
-local getsubtype = nuts.getsubtype
local getwidth = nuts.getwidth
local getlist = nuts.getlist
local setlist = nuts.setlist
@@ -58,14 +56,16 @@ local glue_code = nodecodes.glue
local spaceskip_code = nodes.gluecodes.spaceskip
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
+local nextdisc = nuts.traversers.disc
+
local flush_node_list = nuts.flush_list
local flush_node = nuts.flush_node
local copy_node_list = nuts.copy_list
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local remove_node = nuts.remove
-local list_dimensions = nuts.dimensions
+local getdimensions = nuts.dimensions
local hpack_node_list = nuts.hpack
local nodepool = nuts.pool
@@ -136,7 +136,7 @@ actions[v_line] = function(head,setting)
local linebreaks = { }
local function set(head)
- for g in traverse_id(glyph_code,head) do
+ for g in nextglyph, head do
if dynamic > 0 then
setattr(g,0,dynamic)
end
@@ -146,7 +146,7 @@ actions[v_line] = function(head,setting)
set(temp)
- for g in traverse_id(disc_code,temp) do
+ for g in nextdisc, temp do
local pre, post, replace = getdisc(g)
if pre then
set(pre)
@@ -173,17 +173,13 @@ actions[v_line] = function(head,setting)
local function list_dimensions(list,start)
local temp = copy_node_list(list,start)
- temp = tonode(temp)
temp = nodes.handlers.characters(temp)
temp = nodes.injections.handler(temp)
-- temp = typesetters.fontkerns.handler(temp) -- maybe when enabled
- -- nodes.handlers.protectglyphs(temp) -- not needed as we discard
+ -- nodes.handlers.protectglyphs(temp) -- not needed as we discard
-- temp = typesetters.spacings.handler(temp) -- maybe when enabled
-- temp = typesetters.kerns.handler(temp) -- maybe when enabled
- temp = tonut(temp)
- temp = hpack_node_list(temp)
- local width = getwidth(temp)
- flush_node_list(temp)
+ local width = getdimensions(temp)
return width
end
@@ -206,7 +202,7 @@ actions[v_line] = function(head,setting)
while start do
local id = getid(start)
if id == glyph_code then
- n = n + 1
+ -- go on
elseif id == disc_code then
-- this could be an option
n = n + 1
@@ -218,7 +214,8 @@ actions[v_line] = function(head,setting)
end
elseif id == kern_code then -- todo: fontkern
-- this could be an option
- elseif n > 0 then
+ elseif id == glue_code then
+ n = n + 1
if try() then
break
end
@@ -255,7 +252,6 @@ actions[v_line] = function(head,setting)
local id = getid(start)
local ok = false
if id == glyph_code then
- n = n + 1
update(start)
elseif id == disc_code then
n = n + 1
@@ -264,7 +260,7 @@ actions[v_line] = function(head,setting)
if linebreak == n then
local p, n = getboth(start)
if pre then
- for current in traverse_id(glyph_code,pre) do
+ for current in nextglyph, pre do
update(current)
end
setlink(pretail,n)
@@ -284,7 +280,7 @@ actions[v_line] = function(head,setting)
else
local p, n = getboth(start)
if replace then
- for current in traverse_id(glyph_code,replace) do
+ for current in nextglyph, replace do
update(current)
end
setlink(replacetail,n)
@@ -299,22 +295,30 @@ actions[v_line] = function(head,setting)
setdisc(disc,pre,post,replace)
flush_node(disc)
elseif id == glue_code then
- head = insert_node_before(head,start,newpenalty(10000)) -- nobreak
+ n = n + 1
+ if linebreak ~= n then
+ head = insert_node_before(head,start,newpenalty(10000)) -- nobreak
+ end
end
+ local next = getnext(start)
if linebreak == n then
- if trace_firstlines then
- head, start = insert_node_after(head,start,newpenalty(10000)) -- nobreak
- head, start = insert_node_after(head,start,newkern(-65536))
- head, start = insert_node_after(head,start,tracerrule(65536,4*65536,2*65536,"darkblue"))
+ if start ~= head then
+ local where = id == glue_code and getprev(start) or start
+ if trace_firstlines then
+ head, where = insert_node_after(head,where,newpenalty(10000)) -- nobreak
+ head, where = insert_node_after(head,where,newkern(-65536))
+ head, where = insert_node_after(head,where,tracerrule(65536,4*65536,2*65536,"darkblue"))
+ end
+ head, where = insert_node_after(head,where,newpenalty(-10000)) -- break
end
- head, start = insert_node_after(head,start,newpenalty(-10000)) -- break
+ start = next
break
end
- start = getnext(start)
+ start = next
end
end
- return head, true
+ return head
end
actions[v_word] = function(head,setting)
@@ -359,13 +363,12 @@ actions[v_word] = function(head,setting)
end
start = getnext(start)
end
- return head, true
+ return head
end
actions[v_default] = actions[v_line]
function firstlines.handler(head)
- head = tonut(head)
local start = head
local attr = nil
while start do
@@ -388,11 +391,10 @@ function firstlines.handler(head)
if trace_firstlines then
report_firstlines("processing firstlines, alternative %a",alternative)
end
- local head, done = action(head,settings)
- return tonode(head), done
+ return action(head,settings)
end
end
- return tonode(head), false
+ return head
end
-- goodie
@@ -401,7 +403,7 @@ local function applytofirstcharacter(box,what)
local tbox = getbox(box) -- assumes hlist
local list = getlist(tbox)
local done = nil
- for n in traverse_id(glyph_code,list) do
+ for n in nextglyph, list do
list = remove_node(list,n)
done = n
break
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.mkiv
index 37348be2940..533c197cd10 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.mkiv
@@ -91,7 +91,7 @@
\kern\zeropoint % we need a node
% \hskip\zeropoint\s!plus\emwidth\relax % can be an option
\endgroup
- \globallet\typo_firstline_handle\relax}
+ \glet\typo_firstline_handle\relax}
\let\typo_firstline_handle\relax
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua
index 328bf14067e..2683eecc3e1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua
@@ -29,13 +29,9 @@ local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local getprev = nuts.getprev
local getnext = nuts.getnext
local getid = nuts.getid
-local getfont = nuts.getfont
local getchar = nuts.getchar
local getdisc = nuts.getdisc
local getattr = nuts.getattr
@@ -128,14 +124,22 @@ local function okay(data,current,font,prevchar,previtalic,char,what)
return false
end
if threshold then
- local ht = getheight(current)
- local ex = exheights[font]
- local th = threshold * ex
- if ht <= th then
- if trace_italics then
- report_italics("ignoring correction between %s italic %C and regular %C, height %p less than threshold %p",prevchar,what,char,ht,th)
+ -- if getid(current) == glyph_code then
+ while current and getid(current) ~= glyph_code do
+ current = getprev(current)
+ end
+ if current then
+ local ht = getheight(current)
+ local ex = exheights[font]
+ local th = threshold * ex
+ if ht <= th then
+ if trace_italics then
+ report_italics("ignoring correction between %s italic %C and regular %C, height %p less than threshold %p",prevchar,what,char,ht,th)
+ end
+ return false
end
- return false
+ else
+ -- maybe backtrack to glyph
end
end
if trace_italics then
@@ -177,7 +181,7 @@ local textokay = false
local enablemath = false
local enabletext = false
-local function domath(head,current, done)
+local function domath(head,current)
current = end_of_math(current)
local next = getnext(current)
if next then
@@ -200,8 +204,7 @@ local function domath(head,current, done)
a = a + 100
end
local i = getkern(kern)
- local f = getfont(glyph)
- local c = getchar(glyph)
+ local c, f = isglyph(glyph)
if getheight(next) < 1.25*exheights[f] then
if i == 0 then
if trace_italics then
@@ -212,7 +215,6 @@ local function domath(head,current, done)
report_italics("%s italic between math %C and punctuation %C","removing",i,c,char)
end
setkern(kern,0) -- or maybe a small value or half the ic
- done = true
end
elseif i == 0 then
local d = chardata[f][c]
@@ -226,7 +228,6 @@ local function domath(head,current, done)
if trace_italics then
report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char)
end
- done = true
end
elseif trace_italics then
report_italics("%s italic %p between math %C and punctuation %C","keeping",k,c,char)
@@ -251,34 +252,31 @@ local function domath(head,current, done)
report_italics("%s italic %p between math %C and non punctuation %C","adding",a,getchar(glyph),char)
end
insert_node_after(head,glyph,correction_kern(a,glyph))
- done = true
end
end
end
end
end
end
- return current, done
+ return current
end
local function mathhandler(head)
- local nuthead = tonut(head)
- local current = nuthead
- local done = false
+ local current = head
while current do
if getid(current) == math_code then
- current, done = domath(nuthead,current,done)
+ current = domath(head,current)
end
current = getnext(current)
end
- return head, done
+ return head
end
local function texthandler(head)
local prev = nil
local prevchar = nil
- local prevhead = tonut(head)
+ local prevhead = head
local previtalic = 0
local previnserted = nil
@@ -300,20 +298,18 @@ local function texthandler(head)
local replaceinserted = nil
local current = prevhead
- local done = false
local lastfont = nil
local lastattr = nil
while current do
local char, id = isglyph(current)
if char then
- local font = getfont(current)
+ local font = id
local data = italicsdata[font]
if font ~= lastfont then
if previtalic ~= 0 then
if okay(data,current,font,prevchar,previtalic,char,"glyph") then
insert_node_after(prevhead,prev,correction_kern(previtalic,current))
- done = true
end
elseif previnserted and data then
if trace_italics then
@@ -325,7 +321,6 @@ local function texthandler(head)
if replaceitalic ~= 0 then
if okay(data,replace,font,replacechar,replaceitalic,char,"replace") then
insert_node_after(replacehead,replace,correction_kern(replaceitalic,current))
- done = true
end
replaceitalic = 0
elseif replaceinserted and data then
@@ -338,7 +333,6 @@ local function texthandler(head)
if postitalic ~= 0 then
if okay(data,post,font,postchar,postitalic,char,"post") then
insert_node_after(posthead,post,correction_kern(postitalic,current))
- done = true
end
postitalic = 0
elseif postinserted and data then
@@ -395,7 +389,7 @@ local function texthandler(head)
while current do
local char, id = isglyph(current)
if char then
- local font = getfont(current)
+ local font = id
local data = italicsdata[font]
if data then
local attr = forcedvariant or getattr(current,a_italics)
@@ -431,7 +425,7 @@ local function texthandler(head)
while current do
local char, id = isglyph(current)
if char then
- local font = getfont(current)
+ local font = id
local data = italicsdata[font]
if data then
local attr = forcedvariant or getattr(current,a_italics)
@@ -479,7 +473,6 @@ local function texthandler(head)
end
previnserted = correction_glue(previtalic,current) -- maybe just add ? else problem with penalties
previtalic = 0
- done = true
insert_node_after(prevhead,prev,previnserted)
else
if replaceitalic ~= 0 then
@@ -488,7 +481,6 @@ local function texthandler(head)
end
replaceinserted = correction_kern(replaceitalic,current) -- needs to be a kern
replaceitalic = 0
- done = true
insert_node_after(replacehead,replace,replaceinserted)
end
if postitalic ~= 0 then
@@ -497,7 +489,6 @@ local function texthandler(head)
end
postinserted = correction_kern(postitalic,current) -- needs to be a kern
postitalic = 0
- done = true
insert_node_after(posthead,post,postinserted)
end
end
@@ -510,7 +501,7 @@ local function texthandler(head)
postinserted = nil
postitalic = 0
if mathokay then
- current, done = domath(head,current,done)
+ current = domath(head,current)
else
current = end_of_math(current)
end
@@ -526,7 +517,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
else
if replaceitalic ~= 0 then
if trace_italics then
@@ -539,7 +529,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
end
if postitalic ~= 0 then
if trace_italics then
@@ -552,7 +541,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
end
end
end
@@ -564,25 +552,22 @@ local function texthandler(head)
report_italics("inserting %p between %s italic %C and end of list",previtalic,"glyph",prevchar)
end
insert_node_after(prevhead,prev,correction_kern(previtalic,current))
- done = true
else
if replaceitalic ~= 0 then
if trace_italics then
report_italics("inserting %p between %s italic %C and end of list",replaceitalic,"replace",replacechar)
end
insert_node_after(replacehead,replace,correction_kern(replaceitalic,current))
- done = true
end
if postitalic ~= 0 then
if trace_italics then
report_italics("inserting %p between %s italic %C and end of list",postitalic,"post",postchar)
end
insert_node_after(posthead,post,correction_kern(postitalic,current))
- done = true
end
end
end
- return head, done
+ return head
end
function italics.handler(head)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
index 71d9736a44b..c26004a49df 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
@@ -21,9 +21,6 @@ local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
-- check what is used
local find_node_tail = nuts.tail
@@ -32,6 +29,7 @@ local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local end_of_math = nuts.end_of_math
local use_components = nuts.use_components
+local copy_node = nuts.copy
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -43,10 +41,12 @@ local getdisc = nuts.getdisc
local getglue = nuts.getglue
local getkern = nuts.getkern
local isglyph = nuts.isglyph
+local setchar = nuts.setchar
local setfield = nuts.setfield
local getattr = nuts.getattr
local takeattr = nuts.takeattr
+local setattr = nuts.setattr
local setlink = nuts.setlink
local setdisc = nuts.setdisc
local setglue = nuts.setglue
@@ -62,7 +62,7 @@ local new_glue = nodepool.glue
local nodecodes = nodes.nodecodes
local kerncodes = nodes.kerncodes
-local skipcodes = nodes.skipcodes
+local gluecodes = nodes.gluecodes
local disccodes = nodes.disccodes
local listcodes = nodes.listcodes
@@ -74,17 +74,18 @@ local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local math_code = nodecodes.math
-local box_list_code = listcodes.box
-local user_list_code = listcodes.unknown
+local boxlist_code = listcodes.box
+local unknownlist_code = listcodes.unknown
-local discretionary_code = disccodes.discretionary
-local automatic_code = disccodes.automatic
+local discretionarydisc_code = disccodes.discretionary
+local automaticdisc_code = disccodes.automatic
local fontkern_code = kerncodes.fontkern
local userkern_code = kerncodes.userkern
-local userskip_code = skipcodes.userskip
-local spaceskip_code = skipcodes.spaceskip
-local xspaceskip_code = skipcodes.xspaceskip
+
+local userskip_code = gluecodes.userskip
+local spaceskip_code = gluecodes.spaceskip
+local xspaceskip_code = gluecodes.xspaceskip
local fonthashes = fonts.hashes
local chardata = fonthashes.characters
@@ -132,9 +133,6 @@ local factors = kerns.factors
local gluefactor = 4 -- assumes quad = .5 enspace
-kerns.keepligature = false -- just for fun (todo: control setting with key/value)
-kerns.keeptogether = false -- just for fun (todo: control setting with key/value)
-
-- red : kept by dynamic feature
-- green : kept by static feature
-- blue : keep by goodie
@@ -257,7 +255,7 @@ end
local function inject_end(boundary,next,keeptogether,krn,ok)
local tail = find_node_tail(boundary)
- local char, id = getid(tail)
+ local char, id = isglyph(tail)
if id == kern_code then
if getsubtype(tail) == fontkern_code then
local inject = true
@@ -301,7 +299,7 @@ local function process_list(head,keeptogether,krn,font,okay)
local char, id = isglyph(start)
if char then
if not font then
- font = getfont(start)
+ font = id -- getfont(start)
mark = markdata[font]
kern = quaddata[font]*krn
end
@@ -354,19 +352,223 @@ local function closest_bound(b,get)
while b do
if not getattr(b,a_kerns) then
break
- elseif getid(b) == glyph_code then
- return b, getfont(b)
else
- b = get(b)
+ local c, f = isglyph(b)
+ if c then
+ return b, f
+ else
+ b = get(b)
+ end
end
end
end
end
+-- function kerns.handler(head)
+-- local start = head
+-- local lastfont = nil
+-- local keepligature = kerns.keepligature
+-- local keeptogether = kerns.keeptogether
+-- local fillup = false
+-- local bound = false
+-- local prev = nil
+-- local previd = nil
+-- local prevchar = nil
+-- local prevfont = nil
+-- local prevmark = nil
+-- while start do
+-- -- fontkerns don't get the attribute but they always sit between glyphs so
+-- -- are always valid bound .. disc nodes also somtimes don't get them
+-- local id = getid(start)
+-- local attr = takeattr(start,a_kerns)
+-- if attr and attr > 0 then
+-- local krn = mapping[attr]
+-- if krn == v_max then
+-- krn = .25
+-- fillup = true
+-- else
+-- fillup = false
+-- end
+-- if not krn or krn == 0 then
+-- bound = false
+-- elseif id == glyph_code then
+-- if keepligature and keepligature(start) then
+-- -- keep 'm
+-- else
+-- -- we could use the subtype ligature but that's also a call
+-- -- todo: check tounicode and use that information to split
+-- head, start = use_components(head,start)
+-- end
+-- local char, font = isglyph(start)
+-- local mark = markdata[font]
+-- if not bound then
+-- -- yet
+-- elseif mark[char] then
+-- -- skip
+-- elseif previd == kern_code then
+-- if getsubtype(prev) == fontkern_code then
+-- local inject = true
+-- if keeptogether then
+-- if previd == glyph_code and keeptogether(prev,start) then
+-- inject = false
+-- end
+-- end
+-- if inject then
+-- -- not yet ok, as injected kerns can be overlays (from node-inj.lua)
+-- setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
+-- end
+-- end
+-- elseif previd == glyph_code then
+-- if prevfont == font then
+-- if keeptogether and keeptogether(prev,start) then
+-- -- keep 'm
+-- else
+-- local data = chardata[font][prevchar]
+-- local kerns = data and data.kerns
+-- local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
+-- insert_node_before(head,start,kern_injector(fillup,kern))
+-- end
+-- else
+-- insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
+-- end
+-- end
+-- prev = start
+-- prevchar = char
+-- prevfont = font
+-- prevmark = mark
+-- previd = id
+-- bound = true
+-- elseif id == disc_code then
+-- local prev, next, pglyph, nglyph -- delayed till needed
+-- local subtype = getsubtype(start)
+-- -- if subtype == automaticdisc_code then
+-- -- -- this is kind of special, as we have already injected the
+-- -- -- previous kern
+-- -- local prev = getprev(start)
+-- -- local pglyph = prev and getid(prev) == glyph_code
+-- -- languages.expand(start,pglyph and prev)
+-- -- -- we can have a different start now
+-- -- elseif subtype ~= discretionarydisc_code then
+-- -- prev = getprev(start)
+-- -- pglyph = prev and getid(prev) == glyph_code
+-- -- languages.expand(start,pglyph and prev)
+-- -- end
+-- local pre, post, replace = getdisc(start)
+-- local indeed = false
+-- if pre then
+-- local okay = false
+-- if not prev then
+-- prev = getprev(start)
+-- pglyph = prev and getid(prev) == glyph_code
+-- end
+-- if pglyph then
+-- pre, okay = inject_begin(pre,prev,keeptogether,krn,okay)
+-- end
+-- pre, okay = process_list(pre,keeptogether,krn,false,okay)
+-- if okay then
+-- indeed = true
+-- end
+-- end
+-- if post then
+-- local okay = false
+-- if not next then
+-- next = getnext(start)
+-- nglyph = next and getid(next) == glyph_code
+-- end
+-- if nglyph then
+-- post, okay = inject_end(post,next,keeptogether,krn,okay)
+-- end
+-- post, okay = process_list(post,keeptogether,krn,false,okay)
+-- if okay then
+-- indeed = true
+-- end
+-- end
+-- if replace then
+-- local okay = false
+-- if not prev then
+-- prev = getprev(start)
+-- pglyph = prev and getid(prev) == glyph_code
+-- end
+-- if pglyph then
+-- replace, okay = inject_begin(replace,prev,keeptogether,krn,okay)
+-- end
+-- if not next then
+-- next = getnext(start)
+-- nglyph = next and getid(next) == glyph_code
+-- end
+-- if nglyph then
+-- replace, okay = inject_end(replace,next,keeptogether,krn,okay)
+-- end
+-- replace, okay = process_list(replace,keeptogether,krn,false,okay)
+-- if okay then
+-- indeed = true
+-- end
+-- elseif prevfont then
+-- replace = new_kern(quaddata[prevfont]*krn)
+-- indeed = true
+-- end
+-- if indeed then
+-- setdisc(start,pre,post,replace)
+-- end
+-- bound = false
+-- elseif id == kern_code then
+-- bound = getsubtype(start) == fontkern_code
+-- prev = start
+-- previd = id
+-- elseif id == glue_code then
+-- local subtype = getsubtype(start)
+-- if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then
+-- local width, stretch, shrink, stretch_order, shrink_order = getglue(start)
+-- if width > 0 then
+-- local w = width + gluefactor * width * krn
+-- stretch = stretch * w / width
+-- shrink = shrink * w / width
+-- if fillup then
+-- stretch = 2 * stretch
+-- shrink = 2 * shrink
+-- stretch_order = 1
+-- -- shrink_order = 1 ?
+-- end
+-- setglue(start,w,stretch,shrink,stretch_order,shrink_order)
+-- end
+-- end
+-- bound = false
+-- elseif id == hlist_code or id == vlist_code then
+-- local subtype = getsubtype(start)
+-- if subtype == unknownlist_code or subtype == boxlist_code then
+-- -- special case
+-- local b, f = closest_bound(start,getprev)
+-- if b then
+-- insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
+-- end
+-- local b, f = closest_bound(start,getnext)
+-- if b then
+-- insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
+-- end
+-- end
+-- bound = false
+-- elseif id == math_code then
+-- start = end_of_math(start)
+-- bound = false
+-- end
+-- if start then
+-- start = getnext(start)
+-- end
+-- elseif id == kern_code then
+-- bound = getsubtype(start) == fontkern_code
+-- prev = start
+-- previd = id
+-- start = getnext(start)
+-- else
+-- bound = false
+-- start = getnext(start)
+-- end
+-- end
+-- return head
+-- end
+
function kerns.handler(head)
- local head = tonut(head)
local start = head
- local done = false
local lastfont = nil
local keepligature = kerns.keepligature
local keeptogether = kerns.keeptogether
@@ -379,10 +581,10 @@ function kerns.handler(head)
local prevmark = nil
while start do
-- fontkerns don't get the attribute but they always sit between glyphs so
- -- are always valid bound .. disc nodes also somtimes don't get them
- local id = getid(start)
+ -- are always valid bound .. disc nodes also sometimes don't get them
local attr = takeattr(start,a_kerns)
if attr and attr > 0 then
+ local char, id = isglyph(start)
local krn = mapping[attr]
if krn == v_max then
krn = .25
@@ -392,17 +594,34 @@ function kerns.handler(head)
end
if not krn or krn == 0 then
bound = false
- elseif id == glyph_code then
+ elseif char then -- id == glyph_code
+ local font = id -- more readable
+ local mark = markdata[font]
if keepligature and keepligature(start) then
-- keep 'm
else
- -- we could use the subtype ligature but that's also a call
- -- todo: check tounicode and use that information to split
- head, start = use_components(head,start)
+ -- head, start = use_components(head,start)
+ -- beware, these are not kerned so we mighty need a kern only pass
+ -- maybe some day .. anyway, one should disable ligaturing
+ local data = chardata[font][char]
+ if data then
+ local unicode = data.unicode -- can be cached
+ if type(unicode) == "table" then
+ char = unicode[1]
+ local s = start
+ setchar(s,char)
+ for i=2,#unicode do
+ local n = copy_node(s)
+ if i == 2 then
+ setattr(n,a_kerns,attr) -- we took away the attr
+ end
+ setchar(n,unicode[i])
+ insert_node_after(head,s,n)
+ s = n
+ end
+ end
+ end
end
- local char = getchar(start)
- local font = getfont(start)
- local mark = markdata[font]
if not bound then
-- yet
elseif mark[char] then
@@ -418,7 +637,6 @@ function kerns.handler(head)
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
- done = true
end
end
elseif previd == glyph_code then
@@ -426,34 +644,33 @@ function kerns.handler(head)
if keeptogether and keeptogether(prev,start) then
-- keep 'm
else
+ -- hm, only basemode ... will go away ...
local data = chardata[font][prevchar]
local kerns = data and data.kerns
local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
insert_node_before(head,start,kern_injector(fillup,kern))
- done = true
end
else
insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
- done = true
end
end
prev = start
prevchar = char
prevfont = font
prevmark = mark
- previd = id
+ previd = glyph_code -- id
bound = true
elseif id == disc_code then
local prev, next, pglyph, nglyph -- delayed till needed
local subtype = getsubtype(start)
- -- if subtype == automatic_code then
+ -- if subtype == automaticdisc_code then
-- -- this is kind of special, as we have already injected the
-- -- previous kern
-- local prev = getprev(start)
-- local pglyph = prev and getid(prev) == glyph_code
-- languages.expand(start,pglyph and prev)
-- -- we can have a different start now
- -- elseif subtype ~= discretionary_code then
+ -- elseif subtype ~= discretionarydisc_code then
-- prev = getprev(start)
-- pglyph = prev and getid(prev) == glyph_code
-- languages.expand(start,pglyph and prev)
@@ -514,7 +731,6 @@ function kerns.handler(head)
end
if indeed then
setdisc(start,pre,post,replace)
- done = true
end
bound = false
elseif id == kern_code then
@@ -536,23 +752,20 @@ function kerns.handler(head)
-- shrink_order = 1 ?
end
setglue(start,w,stretch,shrink,stretch_order,shrink_order)
- done = true
end
end
bound = false
elseif id == hlist_code or id == vlist_code then
local subtype = getsubtype(start)
- if subtype == user_list_code or subtype == box_list_code then
+ if subtype == unknownlist_code or subtype == boxlist_code then
-- special case
local b, f = closest_bound(start,getprev)
if b then
insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
- done = true
end
local b, f = closest_bound(start,getnext)
if b then
insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
- done = true
end
end
bound = false
@@ -563,17 +776,20 @@ function kerns.handler(head)
if start then
start = getnext(start)
end
- elseif id == kern_code then
- bound = getsubtype(start) == fontkern_code
- prev = start
- previd = id
- start = getnext(start)
else
- bound = false
- start = getnext(start)
+ local id = getid(start)
+ if id == kern_code then
+ bound = getsubtype(start) == fontkern_code
+ prev = start
+ previd = id
+ start = getnext(start)
+ else
+ bound = false
+ start = getnext(start)
+ end
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-lin.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-lin.lua
index ebf748a8294..8393ea65b34 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-lin.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-lin.lua
@@ -64,7 +64,7 @@ local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local glue_code = nodecodes.glue
local kern_code = nodecodes.kern
-local line_code = listcodes.line
+local linelist_code = listcodes.line
----- localpar_code = nodecodes.localpar
local leftskip_code = gluecodes.leftskip
local rightskip_code = gluecodes.rightskip
@@ -73,7 +73,7 @@ local parfillskip_code = gluecodes.parfillskip
local tonut = nodes.tonut
local tonode = nodes.tonode
-local traverse_id = nuts.traverse_id
+local nexthlist = nuts.traversers.hlist
local insert_before = nuts.insert_before
local insert_after = nuts.insert_after
local find_tail = nuts.tail
@@ -90,7 +90,7 @@ local getboth = nuts.getboth
local setlink = nuts.setlink
local setkern = nuts.setkern
local getkern = nuts.getkern
-local getdir = nuts.getdir
+local getdirection = nuts.getdirection
local getshift = nuts.getshift
local setshift = nuts.setshift
local getwidth = nuts.getwidth
@@ -109,6 +109,8 @@ local new_hlist = nodepool.hlist
local new_rule = nodepool.rule
local new_glue = nodepool.glue
+local righttoleft_code = nodes.dirvalues.righttoleft
+
local texgetcount = tex.getcount
local texgetglue = tex.getglue
local setmetatableindex = table.setmetatableindex
@@ -127,22 +129,12 @@ local noflines = 0
-- This is the third version, a mix between immediate (prestice lines) and delayed
-- as we don't want anchors that are not used.
--- if reverse then delta = - delta end
--- head = insert_before(head,head,nodepool.textdir("-TLT"))
--- ....
--- head = insert_before(head,head,nodepool.textdir("TLT"))
-
--- todo: figure out metatable mess ... when we copy we also need to copy
--- anchors ... use rawgets
-
--- problem: what if a box is copied ... we could check an attribute
-
local function finalize(prop,key) -- delayed calculations
local line = prop.line
local hsize = prop.hsize
local width = prop.width
local shift = getshift(line) -- dangerous as it can be vertical as well
- local reverse = getdir(line) == "TRT" or false
+ local reverse = getdirection(line) == righttoleft_code or false
local pack = new_hlist()
local head = getlist(line)
local delta = 0
@@ -248,49 +240,47 @@ function paragraphs.normalize(head,islocal)
return head, false
end
-- this can become a separate handler but it makes sense to integrate it here
- local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip")
- if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then
- local last = nil -- a nut
- local done = false
- for line in traverse_id(hlist_code,tonut(head)) do
- if getsubtype(line) == line_code and not getprop(line,"line") then
- if done then
- last = line
- else
- done = true
+ local mode = texgetcount("parfillleftmode")
+ if mode > 0 then
+ local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip")
+ if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then
+ local last = nil -- a nut
+ local done = mode == 2 -- false
+ for line, subtype in nexthlist, head do
+ if subtype == linelist_code and not getprop(line,"line") then
+ if done then
+ last = line
+ else
+ done = true
+ end
end
end
- end
- if last then -- only if we have more than one line
- local head = getlist(last)
- local current = head
- if current then
- if getid(current) == glue_code and getsubtype(current,leftskip_code) then
- current = getnext(current)
- end
+ if last then -- only if we have more than one line
+ local head = getlist(last)
+ local current = head
if current then
- head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink))
- if head == current then
- setlist(last,head)
+ if getid(current) == glue_code and getsubtype(current,leftskip_code) then
+ current = getnext(current)
+ end
+ if current then
+ head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink))
+ if head == current then
+ setlist(last,head)
+ end
+ -- can be a 'rehpack(h )'
+ rehpack(last)
end
- -- can be a 'rehpack(h )'
- rehpack(last)
end
end
end
end
-- normalizer
- for line in traverse_id(hlist_code,tonut(head)) do
- if getsubtype(line) == line_code and not getprop(line,"line") then
+ for line, subtype in nexthlist, head do
+ if subtype == linelist_code and not getprop(line,"line") then
normalize(line)
- if done then
- last = line
- else
- done = true
- end
end
end
- return head, true
+ return head, true -- true is obsolete
end
-- print(nodes.idstostring(head))
@@ -418,12 +408,17 @@ function paragraphs.moveinline(n,blob,dx,dy)
end
end
-local lateluafunction = nodepool.lateluafunction
-local setposition = job.positions.set
-local t_anchor = { x = true, c = true }
+local latelua = nodepool.latelua
+local setposition = jobpositions.setspec
+local t_anchor = { x = true, c = true } -- needs checking
local function setanchor(h_anchor)
- return lateluafunction(function() setposition("md:h",h_anchor,t_anchor) end)
+ return latelua {
+ action = setposition,
+ name = "md:h",
+ index = h_anchor,
+ value = t_anchor, -- really shared ?
+ }
end
function paragraphs.calculatedelta(n,width,delta,atleft,islocal,followshape,area)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-mar.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-mar.lua
index bc9c408c19f..f8665e0b061 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-mar.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-mar.lua
@@ -62,13 +62,11 @@ local nuts = nodes.nuts
local nodepool = nuts.pool
local tonode = nuts.tonode
-local tonut = nuts.tonut
local hpack_nodes = nuts.hpack
local traverse_id = nuts.traverse_id
local flush_node_list = nuts.flush_list
-local getfield = nuts.getfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
@@ -84,6 +82,9 @@ local setshift = nuts.setshift
local getwidth = nuts.getwidth
local setwidth = nuts.setwidth
local getheight = nuts.getheight
+local getprop = nuts.getprop
+
+local setattrlist = nuts.setattrlist
local getbox = nuts.getbox
local takebox = nuts.takebox
@@ -93,7 +94,6 @@ local getprop = nuts.getprop
local nodecodes = nodes.nodecodes
local listcodes = nodes.listcodes
-local gluecodes = nodes.gluecodes
local whatsitcodes = nodes.whatsitcodes
local hlist_code = nodecodes.hlist
@@ -103,17 +103,17 @@ local userdefined_code = whatsitcodes.userdefined
local nodepool = nuts.pool
-local new_usernumber = nodepool.usernumber
+local new_usernode = nodepool.usernode
local new_hlist = nodepool.hlist
-local lateluafunction = nodepool.lateluafunction
+local latelua = nodepool.latelua
local texgetdimen = tex.getdimen
local texgetcount = tex.getcount
local texget = tex.get
local isleftpage = layouts.status.isleftpage
-local registertogether = builders.paragraphs.registertogether -- tonode
+local registertogether = builders.paragraphs.registertogether
local paragraphs = typesetters.paragraphs
local addtoline = paragraphs.addtoline
@@ -299,7 +299,9 @@ function margins.save(t)
--
-- t.realpageno = texgetcount("realpageno")
if inline then
- context(tonode(new_usernumber(inline_mark,nofsaved))) -- or use a normal node
+ local n = new_usernode(inline_mark,nofsaved)
+ setattrlist(n,true)
+ context(tonode(n)) -- or use a normal node
store[nofsaved] = t -- no insert
nofinlined = nofinlined + 1
else
@@ -448,8 +450,9 @@ end
-- anchors are only set for lines that have a note
-local function sa(tag) -- maybe l/r keys ipv left/right keys
- local p = cache[tag]
+local function sa(specification) -- maybe l/r keys ipv left/right keys
+ local tag = specification.tag
+ local p = cache[tag]
if p then
if trace_marginstack then
report_margindata("updating anchor %a",tag)
@@ -462,11 +465,13 @@ local function sa(tag) -- maybe l/r keys ipv left/right keys
end
local function setanchor(v_anchor) -- freezes the global here
- return lateluafunction(function() sa(v_anchor) end)
+ return latelua { action = sa, tag = v_anchor }
end
-local function aa(tag,n) -- maybe l/r keys ipv left/right keys
- local p = jobpositions.gettobesaved('md:v',tag)
+local function aa(specification) -- maybe l/r keys ipv left/right keys
+ local tag = specification.tag
+ local n = specification.n
+ local p = jobpositions.gettobesaved('md:v',tag)
if p then
if trace_marginstack then
report_margindata("updating injected %a",tag)
@@ -483,7 +488,7 @@ local function aa(tag,n) -- maybe l/r keys ipv left/right keys
end
local function addtoanchor(v_anchor,n) -- freezes the global here
- return lateluafunction(function() aa(v_anchor,n) end)
+ return latelua { action = aa, tag = v_anchor, n = n }
end
local function markovershoot(current) -- todo: alleen als offset > line
@@ -717,8 +722,8 @@ local function flushinline(parent,head)
while current and nofinlined > 0 do
local id = getid(current)
if id == whatsit_code then
- if getsubtype(current) == userdefined_code and getfield(current,"user_id") == inline_mark then
- local n = getfield(current,"value")
+ if getsubtype(current) == userdefined_code and getprop(current,"id") == inline_mark then
+ local n = getprop(current,"data")
local candidate = inlinestore[n]
if candidate then -- no vpack, as we want to realign
inlinestore[n] = nil
@@ -812,9 +817,8 @@ local function handler(scope,head,group)
if trace_margindata then
report_margindata("flushing stage one, stored %s, scope %s, delayed %s, group %a",nofstored,scope,nofdelayed,group)
end
- head = tonut(head)
local current = head
- local done = false
+ local done = false -- for tracing only
while current do
local id = getid(current)
if (id == vlist_code or id == hlist_code) and getprop(current,"margindata") == nil then
@@ -839,11 +843,9 @@ local function handler(scope,head,group)
report_margindata("flushing stage one, nothing done, %s left",nofstored)
end
end
-resetstacked()
- return tonode(head), done
- else
- return head, false
+ resetstacked()
end
+ return head
end
local trialtypesetting = context.trialtypesetting
@@ -854,7 +856,7 @@ local trialtypesetting = context.trialtypesetting
function margins.localhandler(head,group) -- sometimes group is "" which is weird
if trialtypesetting() then
- return head, false
+ return head
end
local inhibit = conditionals.inhibitmargindata
@@ -862,15 +864,15 @@ function margins.localhandler(head,group) -- sometimes group is "" which is weir
if trace_margingroup then
report_margindata("ignored 3, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
- elseif nofstored > 0 then
+ return head
+ end
+ if nofstored > 0 then
return handler(v_local,head,group)
- else
- if trace_margingroup then
- report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
- end
- return head, false
end
+ if trace_margingroup then
+ report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
+ end
+ return head
end
function margins.globalhandler(head,group) -- check group
@@ -884,7 +886,7 @@ function margins.globalhandler(head,group) -- check group
if trace_margingroup then
report_margindata("ignored 1, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
+ return head
elseif group == "hmode_par" then
return handler(v_global,head,group)
elseif group == "vmode_par" then -- experiment (for alignments)
@@ -899,22 +901,20 @@ function margins.globalhandler(head,group) -- check group
if trace_margingroup then
report_margindata("ignored 2, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
+ return head
end
end
local function finalhandler(head)
if nofdelayed > 0 then
local current = head
- local done = false
- while current and nofdelayed > 0 do
+ while current and nofdelayed > 0 do -- traverse_list
local id = getid(current)
if id == hlist_code then -- only lines?
local a = getprop(current,"margindata")
if not a then
finalhandler(getlist(current))
elseif realigned(current,a) then
- done = true
if nofdelayed == 0 then
return head, true
end
@@ -924,10 +924,8 @@ local function finalhandler(head)
end
current = getnext(current)
end
- return head, done
- else
- return head, false
end
+ return head
end
function margins.finalhandler(head)
@@ -935,16 +933,12 @@ function margins.finalhandler(head)
if trace_margindata then
report_margindata("flushing stage two, instore: %s, delayed: %s",nofstored,nofdelayed)
end
- head = tonut(head)
- local head, done = finalhandler(head)
--- resetstacked(true)
-resetstacked(nofdelayed==0)
- head = tonode(head)
- return head, done
+ head = finalhandler(head)
+ resetstacked(nofdelayed==0)
else
resetstacked()
- return head, false
end
+ return head
end
-- Somehow the vbox builder (in combinations) gets pretty confused and decides to
@@ -996,6 +990,7 @@ interfaces.implement {
{ "align" },
{ "option" },
{ "line", "integer" },
+ { "index", "integer" },
{ "stackname" },
{ "stack" },
}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-mar.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-mar.mkiv
index f265f173c9b..921f1f230c3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-mar.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-mar.mkiv
@@ -155,6 +155,7 @@
\forgetall
\tf
\resetallattributes % \deactivatecolor % needed, but maybe we should switch to maintextcolor: \onlyinheritmaintextcolor
+ \pickupattributes
\to \everymargindatacontent
% trialtypesetting: no need for margin stuff while trialing as
@@ -200,11 +201,17 @@
\let\margindatahbox\naturalhbox % \hbox
+\newcount\c_typo_margins_n
+
+\ifdefined\dotagmarginanchor \else \let\dotagmarginanchor\gobbleoneargument \fi
+\ifdefined\dotagmargintext \else \let\dotagmargintext \gobbleoneargument \fi
+
\unexpanded\def\typo_margins_data_yes_indeed[#dataparameters][#textparameters]#content%
{\iffirstargument
\setupcurrentmargindata[#dataparameters]%
\fi
\doifelsenothing{#content}\donefalse\donetrue
+ \global\advance\c_typo_margins_n\plusone
\ifdone
\edef\currentmarginreference{\margindataparameter\c!reference}%
\ifx\currentmarginreference\empty \else
@@ -212,6 +219,7 @@
\fi
\edef\currentmargindatastrut{\margindataparameter\c!strut}%
\dostarttaggedchained\t!margintext\currentmargindata\??margindata
+ \dotagmargintext\c_typo_margins_n
\ifcsname\currentmarginframedhash\s!parent\endcsname
\setbox\nextbox\margindatahbox \currentmarginreference \bgroup
\the\everymargindatacontent
@@ -271,6 +279,8 @@
\ifdone
\edef\p_anchor{\margindataparameter\c!anchor}%
\anch_positions_initialize % we use positions at the lua end
+ \dostarttagged\t!marginanchor\empty
+ \dotagmarginanchor\c_typo_margins_n
\clf_savemargindata
location {\margindataparameter\c!location}%
method {\margindataparameter\c!method}%
@@ -306,7 +316,9 @@
line \numexpr\margindataparameter\c!line\relax
stackname {\margindataparameter\c!stackname}%
stack {\margindataparameter\c!stack}%
+ index \c_typo_margins_n
\relax
+ \dostoptagged
\else
\clf_savemargindata
location {\margindataparameter\c!location}%
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-pag.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-pag.lua
index b5759a097f7..05513e20c39 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-pag.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-pag.lua
@@ -26,7 +26,6 @@ local unsetvalue = attributes.unsetvalue
local a_keeptogether = attributes.private("keeptogether")
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -187,8 +186,8 @@ end
-- also look at first non glue/kern node e.g for a dropped caps
function parbuilders.keeptogether(head)
- local done = false
- local current = tonut(head)
+ local done = false
+ local current = head
while current do
if getid(current) == hlist_code then
local a = takeattr(current,a_keeptogether)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-par.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-par.mkiv
index 3db0ffa45a7..066dc6a6973 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-par.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-par.mkiv
@@ -23,7 +23,7 @@
\unprotect
-\registerctxluafile{node-ltp}{}
+\registerctxluafile{node-ltp}{optimize}
\registerctxluafile{trac-par}{}
\protect \endinput
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-pnc.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-pnc.lua
index 1ed8d9940af..732970884f2 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-pnc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-pnc.lua
@@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['typo-pnc'] = {
local nodes = nodes
local fonts = fonts
-local prependaction = nodes.tasks.prependaction
local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
@@ -23,7 +22,8 @@ local spaceskip_code = gluecodes.spaceskip
local new_kern = nuts.pool.kern
local insert_after = nuts.insert_after
-local traverse_id = nuts.traverse_id
+
+local nextglyph = nuts.traversers.glyph
local getchar = nuts.getchar
local getfont = nuts.getfont
@@ -68,10 +68,8 @@ local mapping = periodkerns.mapping
local factors = periodkerns.factors
function periodkerns.handler(head)
- local done = false
- local hnut = tonut(head)
- for current in traverse_id(glyph_code,tonut(hnut)) do
- if getchar(current) == period then
+ for current, char, font in nextglyph, head do
+ if char == period then
local a = getattr(current,a_periodkern)
if a then
local factor = mapping[a]
@@ -79,10 +77,10 @@ function periodkerns.handler(head)
local prev, next = getboth(current)
if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
local pchar = getchar(prev)
- local pcode = categories[getchar(prev)]
+ local pcode = categories[pchar]
if pcode == "lu" or pcode == "ll" then
local nchar = getchar(next)
- local ncode = categories[getchar(next)]
+ local ncode = categories[nchar]
if ncode == "lu" or ncode == "ll" then
local next2 = getnext(next)
if next2 and getid(next2) == glyph_code and getchar(next2) == period then
@@ -91,11 +89,10 @@ function periodkerns.handler(head)
if factor ~= 0 then
fontspace = parameters[getfont(current)].space -- can be sped up
inserted = factor * fontspace
- insert_after(hnut,current,new_kern(inserted))
+ insert_after(head,current,new_kern(inserted))
if trace then
report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
end
- done = true
end
local next3 = getnext(next2)
if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
@@ -115,7 +112,6 @@ function periodkerns.handler(head)
end
end
setwidth(next3,space)
- done = true
else
if trace then
if inserted then
@@ -136,7 +132,7 @@ function periodkerns.handler(head)
end
end
end
- return head, done
+ return head
end
local enabled = false
@@ -144,7 +140,6 @@ local enabled = false
function periodkerns.set(factor)
factor = tonumber(factor) or 0
if not enabled then
- prependaction("processors","normalizers","typesetters.periodkerns.handler")
enableaction("processors","typesetters.periodkerns.handler")
enabled = true
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua
index b6aae0cae37..d29eb17b8f3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua
@@ -21,8 +21,6 @@ local nodes = nodes
local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getchar = nuts.getchar
@@ -81,9 +79,8 @@ local function process(what,head,current,char)
return head, current
end
-function nodes.handlers.stripping(head)
- head = tonut(head)
- local current, done = head, false
+function nodes.handlers.stripping(head) -- use loop
+ local current = head
while current do
local char, id = isglyph(current)
if char then
@@ -93,7 +90,6 @@ function nodes.handlers.stripping(head)
local what = glyphs[char]
if what then
head, current = process(what,head,current,char)
- done = true
else -- handling of spacing etc has to be done elsewhere
current = getnext(current)
end
@@ -104,7 +100,7 @@ function nodes.handlers.stripping(head)
current = getnext(current)
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-rub.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-rub.lua
index 8c41a561176..da63d7b64e9 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-rub.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-rub.lua
@@ -33,8 +33,6 @@ local v_auto = variables.auto
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
@@ -53,7 +51,9 @@ local setwidth = nuts.setwidth
local hpack = nuts.hpack
local insert_after = nuts.insert_after
local takebox = nuts.takebox
-local traverse_id = nuts.traverse_id
+
+local nexthlist = nuts.traversers.hlist
+local nextvlist = nuts.traversers.vlist
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
@@ -63,14 +63,11 @@ local glue_code = nodecodes.glue
local penalty_code = nodecodes.penalty
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-local whatsit_code = nodecodes.whatsit
local localpar_code = nodecodes.localpar
-
-local whatsitcodes = nodes.whatsitcodes
------ late_luacode = whatsitcodes.latelua
+local dir_code = nodecodes.dir
local kerncodes = nodes.kerncodes
-local font_code = kerncodes.font
+local fontkern_code = kerncodes.font
local nodepool = nuts.pool
local new_kern = nodepool.kern
@@ -194,7 +191,6 @@ do
end
function rubies.check(head)
- local head = tonut(head)
local current = head
local start = nil
local stop = nil
@@ -208,7 +204,7 @@ function rubies.check(head)
setprev(start)
setnext(stop)
local h = hpack(start)
- if prev == head then
+ if start == head then
head = h
else
setlink(prev,h)
@@ -247,20 +243,21 @@ function rubies.check(head)
start = current
stop = current
end
- elseif id == kern_code and getsubtype(current,font_code) then
+ -- go on
+ elseif id == kern_code and getsubtype(current,fontkern_code) then
-- go on
elseif found and id == disc_code then
-- go on (todo: look into disc)
elseif found then
- flush("flush 4")
+ flush("flush 3")
found = nil
end
current = nx
end
if found then
- flush("flush 5")
+ flush("flush 4")
end
- return tonode(head), true
+ return head, true -- no need for true
end
local attach
@@ -309,11 +306,11 @@ local function whatever(current)
local c = getprev(current)
while c do
local id = getid(c)
- if id == glue_code or id == penalty_code or id == kern_code or (id == whatsit_code and getsubtype(current,localpar_code)) then
+ if id == glue_code or id == penalty_code or id == kern_code then
-- go on
elseif id == hlist_code and getwidth(c) == 0 then
-- go on
- elseif id == whatsit_code or id == localpar_code then
+ elseif id == whatsit_code or id == localpar_code or id == dir_code then
-- go on
else
l = false
@@ -371,20 +368,17 @@ local function whatever(current)
end
end
-attach = function(head)
- for current in traverse_id(hlist_code,head) do
+attach = function(head) -- traverse_list
+ for current in nexthlist, head do
whatever(current)
end
- for current in traverse_id(vlist_code,head) do
+ for current in nextvlist, head do
whatever(current)
end
- return head, true
+ return head
end
-function rubies.attach(head)
- local h, d = attach(tonut(head))
- return tonode(h), d
-end
+rubies.attach = attach
-- for now there is no need to be compact
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-rub.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-rub.mkiv
index d51c53aa414..cc1571ad776 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-rub.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-rub.mkiv
@@ -26,6 +26,7 @@
\installcorenamespace {ruby}
\installcorenamespace {rubyanalyze}
\installcorenamespace {rubyplacement}
+\installcorenamespace {rubynumber}
\installcommandhandler \??ruby {ruby} \??ruby
@@ -135,6 +136,14 @@
\c!hoffset=\zeropoint,
\c!voffset=-2\exheight]
+%D Experiment too:
+
+\unexpanded\def\numberedruby[#1]#2%
+ {\doifnotcounter{\??rubynumber#1}{\definecounter[\??rubynumber#1]\setcounter[\??rubynumber#1][1]}%
+ \ruby[#1]{#2}{\convertedcounter[\??rubynumber#1]}%
+ \incrementcounter[\??rubynumber#1]%
+ \relax}
+
\protect \endinput
% \usemodule[art-01]\setupbodyfont[dejavu,12pt]
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-scr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-scr.mkiv
index d4881b80a5d..0dfd111ae33 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-scr.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-scr.mkiv
@@ -142,8 +142,8 @@
\unexpanded\def\typo_scripts_lowhigh_indeed[#1]#2#3% todo: align .. [#1] is compatible hack
{\dostarttagged\t!subsup\currentlowhigh
- \setbox\plusfour\hbox{\typo_scripts_lowhigh_low_high\lower\c!down\t!sub{#2}}%
- \setbox\plussix \hbox{\typo_scripts_lowhigh_low_high\raise\c!up \t!sup{#3}}%
+ \setbox\plusfour\hpack{\typo_scripts_lowhigh_low_high\lower\c!down\t!sub{#2}}%
+ \setbox\plussix \hpack{\typo_scripts_lowhigh_low_high\raise\c!up \t!sup{#3}}%
\doif{#1}{\v!left}
{\ifdim\wd\plusfour<\wd\plussix
\setbox\plusfour\hpack to \wd\plussix {\hss\box\plusfour}%
@@ -166,7 +166,7 @@
{\dontleavehmode
\begingroup
\kern\lowhighparameter\c!distance\relax
- \setbox\scratchbox\hbox\bgroup
+ \setbox\scratchbox\hpack\bgroup
#1\lowhighparameter#2\hbox\bgroup
\ifx\fontsize\empty
\ifmmode
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-spa.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-spa.lua
index bda1397197e..78fc2296443 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-spa.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-spa.lua
@@ -23,12 +23,9 @@ local unsetvalue = attributes.unsetvalue
local v_reset = interfaces.variables.reset
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
-local getfont = nuts.getfont
local takeattr = nuts.takeattr
local isglyph = nuts.isglyph
@@ -73,8 +70,6 @@ end
-- todo cache lastattr
function spacings.handler(head)
- head = tonut(head)
- local done = false
local start = head
-- head is always begin of par (whatsit), so we have at least two prev nodes
-- penalty followed by glue
@@ -87,10 +82,11 @@ function spacings.handler(head)
if data then
local map = data.characters[char]
if map then
+ local font = id
local left = map.left
local right = map.right
local alternative = map.alternative
- local quad = quaddata[getfont(start)]
+ local quad = quaddata[font]
local prev = getprev(start)
if left and left ~= 0 and prev then
local ok = false
@@ -122,7 +118,6 @@ function spacings.handler(head)
end
insert_node_before(head,start,new_penalty(10000))
insert_node_before(head,start,new_glue(left*quad))
- done = true
end
end
local next = getnext(start)
@@ -159,7 +154,6 @@ function spacings.handler(head)
end
insert_node_after(head,start,new_glue(right*quad))
insert_node_after(head,start,new_penalty(10000))
- done = true
end
end
end
@@ -172,7 +166,7 @@ function spacings.handler(head)
start = getnext(start)
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-sus.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-sus.lua
index 2d3037bdc91..6c02b929167 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-sus.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-sus.lua
@@ -40,8 +40,6 @@ local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local getid = nuts.getid
local getprev = nuts.getprev
@@ -164,7 +162,6 @@ local colors = {
local found = 0
function typesetters.marksuspects(head)
- local head = tonut(head)
local current = head
local lastdone = nil
while current do
@@ -254,7 +251,7 @@ function typesetters.marksuspects(head)
current = getnext(current)
end
end
- return tonode(head), found > 0
+ return head
end
local function showsuspects(head)
@@ -289,9 +286,9 @@ end
function typesetters.showsuspects(head)
if found > 0 then
- return tonode(showsuspects(tonut(head))), true
+ return showsuspects(head)
else
- return head, false
+ return head
end
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua
index 870d006ccf8..8cf29832971 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua
@@ -34,7 +34,6 @@ local v_number = variables.number
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -50,8 +49,8 @@ local setchar = nuts.setchar
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local traverse_list_by_id = nuts.traverse_id
-local list_dimensions = nuts.dimensions
+local nextglyph = nuts.traversers.glyph
+local getdimensions = nuts.dimensions
local first_glyph = nuts.first_glyph
local setglue = nuts.setglue
@@ -171,23 +170,22 @@ local function traced_kern(w)
return tracedrule(w,nil,nil,"darkgray")
end
-function characteralign.handler(originalhead,where)
+function characteralign.handler(head,where)
if not datasets then
- return originalhead, false
+ return head
end
- local head = tonut(originalhead)
-- local first = first_glyph(head) -- we could do that once
local first
- for n in traverse_list_by_id(glyph_code,head) do
+ for n in nextglyph, head do
first = n
break
end
if not first then
- return originalhead, false
+ return head
end
local a = getattr(first,a_characteralign)
if not a or a == 0 then
- return originalhead, false
+ return head
end
local column = div(a,0xFFFF)
local row = a % 0xFFFF
@@ -210,7 +208,7 @@ function characteralign.handler(originalhead,where)
while current do
local char, id = isglyph(current)
if char then
- local font = getfont(current)
+ local font = id --- nicer
local data = fontcharacters[font][char]
local unicode = data and data.unicode or char -- ignore tables
if not unicode then -- type(unicode) ~= "number"
@@ -234,8 +232,9 @@ function characteralign.handler(originalhead,where)
if not b_start then
if sign then
b_start = sign
- local new = validsigns[getchar(sign)]
- if char == new or not fontcharacters[getfont(sign)][new] then
+ local c, f = isglyph(sign)
+ local new = validsigns[c]
+ if char == new or not fontcharacters[f][new] then
if trace_split then
setcolor(sign,"darkyellow")
end
@@ -285,7 +284,7 @@ function characteralign.handler(originalhead,where)
while current do
local char, id = isglyph(current)
if char then
- local font = getfont(current)
+ local font = id -- nicer
-- local unicode = unicodes[font][char]
local unicode = fontcharacters[font][char].unicode or char -- ignore tables
if not unicode then
@@ -322,21 +321,21 @@ function characteralign.handler(originalhead,where)
local predefined = dataset.predefined
local before, after
if predefined then
- before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0
- after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0
+ before = b_start and getdimensions(b_start,getnext(b_stop)) or 0
+ after = a_start and getdimensions(a_start,getnext(a_stop)) or 0
else
local entry = list[row]
if entry then
before = entry.before or 0
after = entry.after or 0
else
- before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0
- after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0
+ before = b_start and getdimensions(b_start,getnext(b_stop)) or 0
+ after = a_start and getdimensions(a_start,getnext(a_stop)) or 0
list[row] = {
before = before,
after = after,
}
- return tonode(head), true
+ return head, true
end
if not dataset.collected then
-- print("[maxbefore] [maxafter]")
@@ -404,5 +403,5 @@ function characteralign.handler(originalhead,where)
insert_node_after(head,c,new_kern(maxafter))
end
end
- return tonode(head), true
+ return head
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.lua
index 07e34cd6c8f..9fb5441526c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.lua
@@ -8,65 +8,80 @@ if not modules then modules = { } end modules ['typo-wrp'] = {
-- begin/end par wrapping stuff ... more to come
-local nodecodes = nodes.nodecodes
+local nodecodes = nodes.nodecodes
+local gluecodes = nodes.gluecodes
+local penaltycodes = nodes.penaltycodes
+local boundarycodes = nodes.boundarycodes
-local glue_code = nodecodes.glue
-local penalty_code = nodecodes.penalty
-local parfill_skip_code = nodes.gluecodes.parfillskip
-local user_penalty_code = nodes.penaltycodes.userpenalty
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local boundary_code = nodecodes.boundary
-local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
+local parfillskip_code = gluecodes.parfillskip
-local find_node_tail = nuts.tail
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getpenalty = nuts.getpenalty
-local remove = nuts.remove
+local userpenalty_code = penaltycodes.userpenalty
+local linepenalty_code = penaltycodes.linepenalty
+local linebreakpenalty_code = penaltycodes.linebreakpenalty
-local enableaction = nodes.tasks.enableaction
+local wordboundary_code = boundarycodes.word
-local wrappers = { }
-typesetters.wrappers = wrappers
+local nuts = nodes.nuts
-local trace_wrappers = trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end)
+local find_node_tail = nuts.tail
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getpenalty = nuts.getpenalty
+local remove = nuts.remove
-local report = logs.reporter("paragraphs","wrappers")
+local enableaction = nodes.tasks.enableaction
+
+local wrappers = { }
+typesetters.wrappers = wrappers
+
+local trace_wrappers = trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end)
+
+local report = logs.reporter("paragraphs","wrappers")
-- we really need to pass tail too ... but then we need to check all the plugins
-- bah ... slowdown
+-- This check is very tight to the crlf definition. We check for:
+--
+-- [break -10000] [wordboundary] [line(break)penalty] [parfillskip]
+--
+-- If needed we can extend this checker for other cases but then we will also
+-- use attributes.
+
local function remove_dangling_crlf(head,tail)
- if tail and getid(tail) == glue_code and getsubtype(tail) == parfill_skip_code then
+ if head and tail and getid(tail) == glue_code and getsubtype(tail) == parfillskip_code then
tail = getprev(tail)
- if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == 10000 then
- tail = getprev(tail)
- if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == -10000 then
- if tail == head then
- -- can't happen
- else
- if trace_wrappers then
- report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
+ if tail and getid(tail) == penalty_code then
+ local subtype = getsubtype(tail)
+ if subtype == linepenalty_code or subtype == linebreakpenalty_code then
+ tail = getprev(tail)
+ if tail and getid(tail) == boundary_code and getsubtype(tail) == wordboundary_code then
+ tail = getprev(tail)
+ if tail ~= head and getid(tail) == penalty_code and getsubtype(tail) == userpenalty_code and getpenalty(tail) == -10000 then
+ if trace_wrappers then
+ report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
+ end
+ remove(head,tail,true)
+ return head, tail
end
- remove(head,tail,true)
- return head, tail, true
end
end
end
end
- return head, tail, false
+ return head, tail
end
function wrappers.handler(head)
- local head = tonut(head)
if head then
local tail = find_node_tail(head)
- local done = false
- head, tail, done = remove_dangling_crlf(head,tail) -- will be action chain
+ head, tail = remove_dangling_crlf(head,tail) -- will be action chain
end
- return head, true
+ return head
end
interfaces.implement {
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.mkiv b/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.mkiv
index 0e010515b05..4e9ecf2e128 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.mkiv
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-wrp.mkiv
@@ -40,18 +40,21 @@
\unexpanded\def\spac_crlf
{\clf_enablecrlf % once
\unskip
- \prewordbreak % here or in \spac_crlf_placeholder
\spac_crlf_placeholder
\ifcase\raggedstatus\hfil\or\or\or\hfil\fi
+ % in bad usage this can lead to: [break -10000] [wordboundary] [line(break)penalty] [parfillskip]
\break
- \hskip\zeropoint % new so that the next word also hyphenates
+ \wordboundary
+ % which we then remove (maybe we should flag the wordboundary with an attribute but not now
\ignorespaces}
\unexpanded\def\spac_crlf_placeholder
{\strut}
\unexpanded\def\spac_crlf_placeholder_show
- {\hbox to \zeropoint{\strut{\infofont\kern.25\emwidth}\lohi{\infofont CR}{\infofont LF}\hss}}
+ {\wordboundary
+ %\nobreak
+ \hpack to \zeropoint{\strut{\infofont\kern.25\emwidth}\lohi{\infofont CR}{\infofont LF}\hss}}
\unexpanded\def\settestcrlf
{\let\spac_crlf_placeholder\spac_crlf_placeholder_show}
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-deb.lua b/Master/texmf-dist/tex/context/base/mkiv/util-deb.lua
index b8db0c58345..6932e8804d3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-deb.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-deb.lua
@@ -10,9 +10,6 @@ if not modules then modules = { } end modules ['util-deb'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
-local debug = require "debug"
-
-local getinfo, sethook = debug.getinfo, debug.sethook
local type, next, tostring, tonumber = type, next, tostring, tonumber
local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub
local insert, remove, sort = table.insert, table.remove, table.sort
@@ -98,7 +95,7 @@ end
setmetatableindex(names,function(t,name)
local v = setmetatableindex(function(t,source)
local v = setmetatableindex(function(t,line)
- local v = { total = 0, count = 0 }
+ local v = { total = 0, count = 0, nesting = 0 }
t[line] = v
return v
end)
@@ -109,6 +106,9 @@ setmetatableindex(names,function(t,name)
return v
end)
+local getinfo = nil
+local sethook = nil
+
local function hook(where)
local f = getinfo(2,"nSl")
if f then
@@ -128,12 +128,24 @@ local function hook(where)
end
local data = names[name][source][line]
if where == "call" then
- data.count = data.count + 1
- insert(data,ticks())
+ local nesting = data.nesting
+ if nesting == 0 then
+ data.count = data.count + 1
+ insert(data,ticks())
+ data.nesting = 1
+ else
+ data.nesting = nesting + 1
+ end
elseif where == "return" then
- local t = remove(data)
- if t then
- data.total = data.total + ticks() - t
+ local nesting = data.nesting
+ if nesting == 1 then
+ local t = remove(data)
+ if t then
+ data.total = data.total + ticks() - t
+ end
+ data.nesting = 0
+ else
+ data.nesting = nesting - 1
end
end
end
@@ -228,6 +240,27 @@ function debugger.showstats(printer,threshold)
-- table.save("luatex-profile.lua",names)
end
+local function getdebug()
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay, debug = pcall(require,"debug")
+ end
+ if type(debug) ~= "table" then
+ return
+ end
+ getinfo = debug.getinfo
+ sethook = debug.sethook
+ if type(getinfo) ~= "function" then
+ getinfo = nil
+ end
+ if type(sethook) ~= "function" then
+ sethook = nil
+ end
+end
+
function debugger.savestats(filename,threshold)
local f = io.open(filename,'w')
if f then
@@ -237,7 +270,8 @@ function debugger.savestats(filename,threshold)
end
function debugger.enable()
- if nesting == 0 then
+ getdebug()
+ if sethook and getinfo and nesting == 0 then
running = true
if initialize then
initialize()
@@ -259,7 +293,7 @@ function debugger.disable()
if nesting > 0 then
nesting = nesting - 1
end
- if nesting == 0 then
+ if sethook and getinfo and nesting == 0 then
sethook()
end
end
@@ -282,20 +316,25 @@ end
-- from the lua book:
local function showtraceback(rep) -- from lua site / adapted
- local level = 2 -- we don't want this function to be reported
- local reporter = rep or report
- while true do
- local info = getinfo(level, "Sl")
- if not info then
- break
- elseif info.what == "C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ getdebug()
+ if getinfo then
+ local level = 2 -- we don't want this function to be reported
+ local reporter = rep or report
+ while true do
+ local info = getinfo(level, "Sl")
+ if not info then
+ break
+ elseif info.what == "C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level = level + 1
end
- level = level + 1
end
end
debugger.showtraceback = showtraceback
-- debug.showtraceback = showtraceback
+
+-- showtraceback()
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-env.lua b/Master/texmf-dist/tex/context/base/mkiv/util-env.lua
index 064bd513ad5..dde76587486 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-env.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-env.lua
@@ -72,20 +72,16 @@ end
-- dirty tricks (we will replace the texlua call by luatex --luaonly)
local validengines = allocate {
- ["luatex"] = true,
- ["luajittex"] = true,
- -- ["luatex.exe"] = true,
- -- ["luajittex.exe"] = true,
+ ["luatex"] = true,
+ ["luajittex"] = true,
}
local basicengines = allocate {
- ["luatex"] = "luatex",
- ["texlua"] = "luatex",
- ["texluac"] = "luatex",
- ["luajittex"] = "luajittex",
- ["texluajit"] = "luajittex",
- -- ["texlua.exe"] = "luatex",
- -- ["texluajit.exe"] = "luajittex",
+ ["luatex"] = "luatex",
+ ["texlua"] = "luatex", -- obsolete
+ ["texluac"] = "luatex", -- obsolete
+ ["luajittex"] = "luajittex",
+ ["texluajit"] = "luajittex", -- obsolete
}
local luaengines = allocate {
@@ -154,8 +150,11 @@ environment.sortedflags = nil
-- context specific arguments (in order not to confuse the engine)
function environment.initializearguments(arg)
- local arguments, files = { }, { }
- environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
+ local arguments = { }
+ local files = { }
+ environment.arguments = arguments
+ environment.files = files
+ environment.sortedflags = nil
for index=1,#arg do
local argument = arg[index]
if index > 0 then
@@ -174,6 +173,11 @@ function environment.initializearguments(arg)
end
end
end
+ if not environment.ownname then
+ if os.selfpath and os.selfname then
+ environment.ownname = file.addsuffix(file.join(os.selfpath,os.selfname),"lua")
+ end
+ end
environment.ownname = file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
@@ -281,13 +285,20 @@ if arg then
for index=1,#arg do
local argument = arg[index]
if find(argument,"^\"") then
- newarg[#newarg+1] = gsub(argument,"^\"","")
- if not find(argument,"\"$") then
+ if find(argument,"\"$") then
+ newarg[#newarg+1] = gsub(argument,"^\"(.-)\"$","%1")
+ instring = false
+ else
+ newarg[#newarg+1] = gsub(argument,"^\"","")
instring = true
end
elseif find(argument,"\"$") then
- newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","")
- instring = false
+ if instring then
+ newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","")
+ instring = false
+ else
+ newarg[#newarg+1] = argument
+ end
elseif instring then
newarg[#newarg] = newarg[#newarg] .. " " .. argument
else
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-evo.lua b/Master/texmf-dist/tex/context/base/mkiv/util-evo.lua
index 7f0b59ac452..dfb395e082b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-evo.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-evo.lua
@@ -161,15 +161,22 @@ local function loadedtable(filename)
for i=1,10 do
local t = loadtable(filename)
if t then
+ report("file %a loaded",filename)
return t
else
ossleep(1/4)
end
end
end
+ report("file %a not loaded",filename)
return { }
end
+local function savedtable(filename,data)
+ savetable(filename,data)
+ report("file %a saved",filename)
+end
+
local function loadpresets(filename)
local presets = loadtable(filename)
if presets then
@@ -194,6 +201,13 @@ local function loadeverything(filename)
return loadedtable(filename)
end
+local function loadlatest(filename)
+ if type(filename) == "table" and validpresets(filename) then
+ filename = filename.files and filename.files.latest
+ end
+ return loadedtable(filename)
+end
+
local function result(t,fmt,a,b,c)
if t then
report(fmt,a or "done",b or "done",c or "done","done")
@@ -365,6 +379,21 @@ local function findzone(presets,name)
return usedzones and usedzones[name]
end
+local function getzonenames(presets)
+ if not presets then
+ return { }
+ end
+ local data = presets.data
+ if not data then
+ return { }
+ end
+ local t = sortedkeys(data.zones or { })
+ for i=1,#t do
+ t[i] = lower(t[i])
+ end
+ return t
+end
+
local function gettargets(zone) -- maybe also for a day
local schedule = zone.schedule
local min = false
@@ -503,7 +532,7 @@ local function geteverything(presets,noschedules)
end
end
end
- savetable(presets.files.everything,data)
+ savedtable(presets.files.everything,data)
return result(data,"getting everything, %s")
end
end
@@ -521,26 +550,29 @@ local function gettemperatures(presets)
for i=1,#data do
local gateways = data[i].gateways
local locationinfo = data[i].locationInfo
- local locationid = locationinfo.locationId
- if gateways then
- local status = getstatus(presets,locationid,locationinfo.name)
- if status then
- for i=1,#gateways do
- local g = status.gateways[i]
- local gateway = gateways[i]
- local systems = gateway.temperatureControlSystems
- if systems then
- local s = g.temperatureControlSystems
- for i=1,#systems do
- local zones = systems[i].zones
- if zones then
- local z = s[i].zones
- for i=1,#zones do
- if validzonetypes[zone.zoneType] then
- local z = z[i]
- if z.name == zone.name then
- zone.temperatureStatus = z.temperatureStatus
- updated = true
+ if locationinfo then
+ local locationid = locationinfo.locationId
+ if gateways then
+ local status = getstatus(presets,locationid,locationinfo.name)
+ if status then
+ for i=1,#gateways do
+ local g = status.gateways[i]
+ local gateway = gateways[i]
+ local systems = gateway.temperatureControlSystems
+ if systems then
+ local s = g.temperatureControlSystems
+ for i=1,#systems do
+ local zones = systems[i].zones
+ if zones then
+ local z = s[i].zones
+ for i=1,#zones do
+ local zone = zones[i]
+ if validzonetypes[zone.zoneType] then
+ local z = z[i]
+ if z.name == zone.name then
+ zone.temperatureStatus = z.temperatureStatus
+ updated = true
+ end
end
end
end
@@ -548,12 +580,16 @@ local function gettemperatures(presets)
end
end
end
+ else
+ report("no gateways")
end
+ else
+ report("no location info")
end
end
if updated then
data.time = ostime()
- savetable(presets.files.latest,data)
+ savedtable(presets.files.latest,data)
end
return result(data,"getting temperatures, %s")
end
@@ -601,7 +637,10 @@ end
local function loadtemperatures(presets)
if validpresets(presets) then
- local status = loadeverything(presets)
+ local status = loadlatest(presets)
+ if not status or not next(status) then
+ status = loadeverything(presets)
+ end
if status then
local usedgateways = presets.data.gateways
for i=1,#status do
@@ -637,9 +676,10 @@ end
local function updatetemperatures(presets)
if validpresets(presets) then
local everythingname = presets.files.everything
+ local latestname = presets.files.latest
local historyname = presets.files.history
- if everythingname and historyname then
- gettemperatures(presets,everythingname)
+ if (everythingname or latestname) and historyname then
+ gettemperatures(presets)
local t = loadtemperatures(presets)
if t then
local data = { }
@@ -649,7 +689,7 @@ local function updatetemperatures(presets)
end
local history = loadhistory(historyname) or { }
setmoment(history,ostime(),data)
- savetable(historyname,history)
+ savedtable(historyname,history)
return result(t,"updating temperatures, %s")
end
end
@@ -747,10 +787,10 @@ local function off(presets,name)
end
end
-local function on(presets,name)
+local function on(presets,name,temperature)
local zone = presets and getzonestate(presets,name)
if zone then
- setzonestate(presets,name,zone.highest)
+ setzonestate(presets,name,temperature or zone.highest)
end
end
@@ -787,7 +827,7 @@ local function settask(presets,when,tag,action)
else
list[tag] = nil
end
- savetable(presets.files.schedules,list)
+ savedtable(presets.files.schedules,list)
end
end
@@ -832,7 +872,7 @@ local function checktasks(presets)
for k, v in next, q do
list[q] = nil
end
- savetable(presets.files.schedules,list)
+ savedtable(presets.files.schedules,list)
end
return list
end
@@ -954,10 +994,10 @@ end
evohome = {
helpers = {
- getaccesstoken = getaccesstoken, -- presets
- getuserinfo = getuserinfo, -- presets
- getlocationinfo = getlocationinfo, -- presets
- getschedule = getschedule, -- presets, name
+ getaccesstoken = getaccesstoken, -- presets
+ getuserinfo = getuserinfo, -- presets
+ getlocationinfo = getlocationinfo, -- presets
+ getschedule = getschedule, -- presets, name
--
geteverything = geteverything, -- presets, noschedules
gettemperatures = gettemperatures, -- presets
@@ -965,6 +1005,7 @@ evohome = {
setzonestate = setzonestate, -- presets, name, temperature
resetzonestate = resetzonestate, -- presets, name
getzonedata = findzone, -- presets, name
+ getzonenames = getzonenames, -- presets
--
loadpresets = loadpresets, -- filename
loadhistory = loadhistory, -- presets | filename
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-fil.lua b/Master/texmf-dist/tex/context/base/mkiv/util-fil.lua
index 0e8ed4e5751..9f96a01b911 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-fil.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-fil.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['util-fil'] = {
license = "see context related readme files"
}
+local tonumber = tonumber
local byte = string.byte
local char = string.char
@@ -196,41 +197,23 @@ function files.readinteger4le(f)
end
end
--- function files.readfixed2(f)
--- local a, b = byte(f:read(2),1,2)
--- if a >= 0x80 then
--- return (0x100 * a + b - 0x10000)/256.0
--- else
--- return (0x100 * a + b)/256.0
--- end
--- end
-
function files.readfixed2(f)
local a, b = byte(f:read(2),1,2)
if a >= 0x80 then
- return (a - 0x100) + b/0x100
+ tonumber((a - 0x100) .. "." .. b)
else
- return (a ) + b/0x100
+ tonumber(( a ) .. "." .. b)
end
end
--- (real) (n>>16) + ((n&0xffff)/65536.0))
-
--- function files.readfixed4(f)
--- local a, b, c, d = byte(f:read(4),1,4)
--- if a >= 0x80 then
--- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0
--- else
--- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0
--- end
--- end
+-- (real) (n>>16) + ((n&0xffff)/65536.0)) but no cast in lua (we could use unpack)
function files.readfixed4(f)
local a, b, c, d = byte(f:read(4),1,4)
if a >= 0x80 then
- return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000
+ tonumber((0x100 * a + b - 0x10000) .. "." .. (0x100 * c + d))
else
- return (0x100 * a + b ) + (0x100 * c + d)/0x10000
+ tonumber((0x100 * a + b ) .. "." .. (0x100 * c + d))
end
end
@@ -343,3 +326,40 @@ if fio and fio.readcardinal1 then
end
end
+
+if fio and fio.readcardinaltable then
+
+ files.readcardinaltable = fio.readcardinaltable
+ files.readintegertable = fio.readintegertable
+
+else
+
+ local readcardinal1 = files.readcardinal1
+ local readcardinal2 = files.readcardinal2
+ local readcardinal3 = files.readcardinal3
+ local readcardinal4 = files.readcardinal4
+
+ function files.readcardinaltable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readcardinal1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end
+ return t
+ end
+
+ local readinteger1 = files.readinteger1
+ local readinteger2 = files.readinteger2
+ local readinteger3 = files.readinteger3
+ local readinteger4 = files.readinteger4
+
+ function files.readintegertable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readinteger1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end
+ return t
+ end
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-fmt.lua b/Master/texmf-dist/tex/context/base/mkiv/util-fmt.lua
index 371a5dfcece..fe80c64201e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-fmt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-fmt.lua
@@ -35,10 +35,17 @@ function formatters.formatcolumns(result,between)
for j=1,n do
local rj = r[j]
local tj = type(rj)
+-- if tj == "number" then
+-- numbers[j] = true
+-- end
+-- if tj ~= "string" then
+-- rj = tostring(rj)
+-- r[j] = rj
+-- end
if tj == "number" then
numbers[j] = true
- end
- if tj ~= "string" then
+ rj = tostring(rj)
+ elseif tj ~= "string" then
rj = tostring(rj)
r[j] = rj
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-jsn.lua b/Master/texmf-dist/tex/context/base/mkiv/util-jsn.lua
index e5f83e06c47..acbf160904d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-jsn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-jsn.lua
@@ -14,10 +14,12 @@ if not modules then modules = { } end modules ['util-jsn'] = {
--
-- Reminder for me: check usage in framework and extend when needed. Also document
-- it in the cld lib documentation.
+--
+-- Upgraded for handling the somewhat more fax server templates.
local P, V, R, S, C, Cc, Cs, Ct, Cf, Cg = lpeg.P, lpeg.V, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cf, lpeg.Cg
local lpegmatch = lpeg.match
-local format = string.format
+local format, gsub = string.format, string.gsub
local utfchar = utf.char
local concat = table.concat
@@ -26,9 +28,6 @@ local tonumber, tostring, rawset, type, next = tonumber, tostring, rawset, type,
local json = utilities.json or { }
utilities.json = json
--- moduledata = moduledata or { }
--- moduledata.json = json
-
-- \\ \/ \b \f \n \r \t \uHHHH
local lbrace = P("{")
@@ -43,16 +42,19 @@ local whitespace = lpeg.patterns.whitespace
local optionalws = whitespace^0
local escapes = {
- -- ["\\"] = "\\", -- lua will escape these
- -- ["/"] = "/", -- no need to escape this one
- ["b"] = "\010",
- ["f"] = "\014",
- ["n"] = "\n",
- ["r"] = "\r",
- ["t"] = "\t",
+ ["b"] = "\010",
+ ["f"] = "\014",
+ ["n"] = "\n",
+ ["r"] = "\r",
+ ["t"] = "\t",
}
-local escape_un = C(P("\\u") / "0x" * S("09","AF","af")) / function(s) return utfchar(tonumber(s)) end
+-- todo: also handle larger utf16
+
+local escape_un = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s)
+ return utfchar(tonumber(s,16))
+end)
+
local escape_bs = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char
local jstring = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote
@@ -85,7 +87,9 @@ function json.tolua(str)
return lpegmatch(jsonconverter,str)
end
-local function tojson(value,t) -- we could optimize #t
+local escaper
+
+local function tojson(value,t,n) -- we could optimize #t
local kind = type(value)
if kind == "table" then
local done = false
@@ -93,60 +97,75 @@ local function tojson(value,t) -- we could optimize #t
if size == 0 then
for k, v in next, value do
if done then
- t[#t+1] = ","
+ n = n + 1 ; t[n] = ","
else
- t[#t+1] = "{"
+ n = n + 1 ; t[n] = "{"
done = true
end
- t[#t+1] = format("%q:",k)
- tojson(v,t)
+ n = n + 1 ; t[n] = format("%q:",k)
+ t, n = tojson(v,t,n)
end
if done then
- t[#t+1] = "}"
+ n = n + 1 ; t[n] = "}"
else
- t[#t+1] = "{}"
+ n = n + 1 ; t[n] = "{}"
end
elseif size == 1 then
-- we can optimize for non tables
- t[#t+1] = "["
- tojson(value[1],t)
- t[#t+1] = "]"
+ n = n + 1 ; t[n] = "["
+ t, n = tojson(value[1],t,n)
+ n = n + 1 ; t[n] = "]"
else
for i=1,size do
if done then
- t[#t+1] = ","
+ n = n + 1 ; t[n] = ","
else
- t[#t+1] = "["
+ n = n + 1 ; t[n] = "["
done = true
end
- tojson(value[i],t)
+ t, n = tojson(value[i],t,n)
end
- t[#t+1] = "]"
+ n = n + 1 ; t[n] = "]"
end
elseif kind == "string" then
- t[#t+1] = format("%q",value)
+ n = n + 1 ; t[n] = '"'
+ n = n + 1 ; t[n] = lpegmatch(escaper,value) or value
+ n = n + 1 ; t[n] = '"'
elseif kind == "number" then
- t[#t+1] = value
+ n = n + 1 ; t[n] = value
elseif kind == "boolean" then
- t[#t+1] = tostring(value)
+ n = n + 1 ; t[n] = tostring(value)
end
- return t
+ return t, n
end
function json.tostring(value)
-- todo optimize for non table
local kind = type(value)
if kind == "table" then
- return concat(tojson(value,{}),"")
+ if not escaper then
+ local escapes = {
+ ["\\"] = "\\u005C",
+ ["\""] = "\\u0022",
+ }
+ for i=0,0x20 do
+ escapes[utfchar(i)] = format("\\u%04X",i)
+ end
+ escaper = Cs( (
+ (R('\0\x20') + S('\"\\')) / escapes
+ + P(1)
+ )^1 )
+
+ end
+ return concat((tojson(value,{},0)))
elseif kind == "string" or kind == "number" then
- return value
+ return lpegmatch(escaper,value) or value
else
return tostring(value)
end
end
--- local tmp = [[ { "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
-
+-- local tmp = [[ { "t" : "foobar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
-- tmp = json.tolua(tmp)
-- inspect(tmp)
-- tmp = json.tostring(tmp)
@@ -155,7 +174,6 @@ end
-- inspect(tmp)
-- tmp = json.tostring(tmp)
-- inspect(tmp)
-
-- inspect(json.tostring(true))
function json.load(filename)
@@ -165,4 +183,11 @@ function json.load(filename)
end
end
+-- local s = [[\foo"bar"]]
+-- local j = json.tostring { s = s }
+-- local l = json.tolua(j)
+-- inspect(j)
+-- inspect(l)
+-- print(s==l.s)
+
return json
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-lib.lua b/Master/texmf-dist/tex/context/base/mkiv/util-lib.lua
index 714cfd4c77c..fb65a566e24 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-lib.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-lib.lua
@@ -237,7 +237,7 @@ local function locate(required,version,trace,report,action)
report("stored library: %a",required)
end
end
- return library
+ return library or nil
end
do
@@ -352,7 +352,7 @@ We use the same lookup logic for ffi loading.
trackers.register("resolvers.ffilib", function(v) trace_ffilib = v end)
-- pushlibpath(pathpart(name))
- -- local message, library = pcall(savedffiload,nameonly(name))
+ -- local state, library = pcall(savedffiload,nameonly(name))
-- poplibpath()
local loaded = { }
@@ -361,11 +361,11 @@ We use the same lookup logic for ffi loading.
name = removesuffix(name)
local l = loaded[name]
if l == nil then
- local message, library = pcall(savedffiload,name)
- if type(message) == "userdata" then
- l = message
- elseif type(library) == "userdata" then
+ local state, library = pcall(savedffiload,name)
+ if type(library) == "userdata" then
l = library
+ elseif type(state) == "userdata" then
+ l = state
else
l = false
end
@@ -376,6 +376,20 @@ We use the same lookup logic for ffi loading.
return l
end
+ local function getlist(required)
+ local list = directives.value("system.librarynames" )
+ if type(list) == "table" then
+ list = list[required]
+ if type(list) == "table" then
+ if trace then
+ report("using lookup list for library %a: % | t",required,list)
+ end
+ return list
+ end
+ end
+ return { required }
+ end
+
function ffilib(name,version)
name = removesuffix(name)
local l = loaded[name]
@@ -384,23 +398,45 @@ We use the same lookup logic for ffi loading.
report_ffilib("reusing already loaded %a",name)
end
return l
- elseif version == "system" then
- return locateindeed(name)
+ end
+ local list = getlist(name)
+ if version == "system" then
+ for i=1,#list do
+ local library = locateindeed(list[i])
+ if type(library) == "userdata" then
+ return library
+ end
+ end
else
- return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
+ for i=1,#list do
+ local library = locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library) == "userdata" then
+ return library
+ end
+ end
end
end
function ffi.load(name)
- local library = ffilib(name)
- if type(library) == "userdata" then
- return library
+ local list = getlist(name)
+ for i=1,#list do
+ local library = ffilib(list[i])
+ if type(library) == "userdata" then
+ return library
+ end
end
if trace_ffilib then
report_ffilib("trying to load %a using normal loader",name)
end
-- so here we don't store
- return savedffiload(name)
+ for i=1,#list do
+ local state, library = pcall(savedffiload,list[i])
+ if type(library) == "userdata" then
+ return library
+ elseif type(state) == "userdata" then
+ return library
+ end
+ end
end
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-lua.lua b/Master/texmf-dist/tex/context/base/mkiv/util-lua.lua
index b7de119360c..1199301f42f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-lua.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-lua.lua
@@ -88,6 +88,7 @@ function luautilities.loadedluacode(fullname,forcestrip,name,macros)
code()
else
report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code, message = loadfile(fullname)
end
if forcestrip and luautilities.stripcode then
if type(forcestrip) == "function" then
@@ -114,7 +115,7 @@ function luautilities.strippedloadstring(code,name,forcestrip) -- not executed
end
if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
register(name)
- return load(dump(code,true)), 0 -- not yet executes
+ return load(dump(code,true)), 0 -- not yet executed
else
return code, 0
end
@@ -198,12 +199,12 @@ function luautilities.checkmemory(previous,threshold,trace) -- threshold in MB
collectgarbage("collect")
local afterwards = collectgarbage("count")
if trace or tracememory then
- report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB, afterwards %i MB",
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
previous/1024,current/1024,delta/1024,threshold,afterwards)
end
return afterwards
elseif trace or tracememory then
- report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB",
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
previous/1024,current/1024,delta/1024,threshold)
end
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-mrg.lua b/Master/texmf-dist/tex/context/base/mkiv/util-mrg.lua
index 690188ef879..bc835bf563a 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-mrg.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-mrg.lua
@@ -113,6 +113,7 @@ local pack = digit * space^1 * operator4 * optionalspacing +
optionalspaces * separator * optionalspaces
local lines = emptyline^2 / "\n"
local spaces = (space * space) / " "
+local spaces = (space * space * space * space) / " "
----- spaces = ((space+eol)^1 ) / " "
local compact = Cs ( (
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-prs.lua b/Master/texmf-dist/tex/context/base/mkiv/util-prs.lua
index 48d59a9f3f7..08401f22275 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-prs.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-prs.lua
@@ -31,6 +31,7 @@ utilities.parsers.hashes = hashes
local digit = R("09")
local space = P(' ')
local equal = P("=")
+local colon = P(":")
local comma = P(",")
local lbrace = P("{")
local rbrace = P("}")
@@ -72,11 +73,13 @@ lpegpatterns.nested = nestedbraces -- no capture
lpegpatterns.argument = argument -- argument after e.g. =
lpegpatterns.content = content -- rest after e.g =
-local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) + C((nestedbraces + (1-comma))^0)
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ + C((nestedbraces + (1-comma))^0)
local key = C((1-equal-comma)^1)
local pattern_a = (space+comma)^0 * (key * equal * value + key * C(""))
local pattern_c = (space+comma)^0 * (key * equal * value)
+local pattern_d = (space+comma)^0 * (key * (equal+colon) * value + key * C(""))
local key = C((1-space-equal-comma)^1)
local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C("")))
@@ -92,10 +95,12 @@ end
local pattern_a_s = (pattern_a/set)^1
local pattern_b_s = (pattern_b/set)^1
local pattern_c_s = (pattern_c/set)^1
+local pattern_d_s = (pattern_d/set)^1
patterns.settings_to_hash_a = pattern_a_s
patterns.settings_to_hash_b = pattern_b_s
patterns.settings_to_hash_c = pattern_c_s
+patterns.settings_to_hash_d = pattern_d_s
function parsers.make_settings_to_hash_pattern(set,how)
if how == "strict" then
@@ -126,6 +131,18 @@ function parsers.settings_to_hash(str,existing)
end
end
+function parsers.settings_to_hash_colon_too(str)
+ if not str or str == "" then
+ return { }
+ elseif type(str) == "table" then
+ return str
+ else
+ hash = { }
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
+end
+
function parsers.settings_to_hash_tolerant(str,existing)
if not str or str == "" then
return { }
@@ -165,7 +182,7 @@ function parsers.settings_to_hash_strict(str,existing)
end
local separator = comma * space^0
-local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ C((nestedbraces + (1-comma))^0)
local pattern = spaces * Ct(value*(separator*value)^0)
@@ -210,7 +227,7 @@ function parsers.settings_to_numbers(str)
return str
end
-local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ C((nestedbraces + nestedbrackets + nestedparents + (1-comma))^0)
local pattern = spaces * Ct(value*(separator*value)^0)
@@ -242,7 +259,7 @@ function parsers.groupedsplitat(symbol,withaction)
if not pattern then
local symbols = S(symbol)
local separator = space^0 * symbols * space^0
- local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+ local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ C((nestedbraces + (1-(space^0*(symbols+P(-1)))))^0)
if withaction then
local withvalue = Carg(1) * value / function(f,s) return f(s) end
@@ -291,7 +308,9 @@ end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
if h then
- local t, tn, s = { }, 0, sortedkeys(h)
+ local t = { }
+ local tn = 0
+ local s = sortedkeys(h)
omit = omit and tohash(omit)
for i=1,#s do
local key = s[i]
@@ -357,7 +376,8 @@ end)
getmetatable(hashes.settings_to_set).__mode = "kv" -- could be an option (maybe sharing makes sense)
function parsers.simple_hash_to_string(h, separator)
- local t, tn = { }, 0
+ local t = { }
+ local tn = 0
for k, v in sortedhash(h) do
if v then
tn = tn + 1
@@ -398,7 +418,8 @@ local function repeater(n,str)
if n == 1 then
return unpack(s)
else
- local t, tn = { }, 0
+ local t = { }
+ local tn = 0
for i=1,n do
for j=1,#s do
tn = tn + 1
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sac.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sac.lua
index b509d9a9b7c..dc8ba72f1c3 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sac.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sac.lua
@@ -10,15 +10,23 @@ if not modules then modules = { } end modules ['util-sac'] = {
-- with bytes)
local byte, sub = string.byte, string.sub
-local extract = bit32 and bit32.extract
+local tonumber = tonumber
utilities = utilities or { }
local streams = { }
utilities.streams = streams
function streams.open(filename,zerobased)
- local f = io.loaddata(filename)
- return { f, 1, #f, zerobased or false }
+ local f = filename and io.loaddata(filename)
+ if f then
+ return { f, 1, #f, zerobased or false }
+ end
+end
+
+function streams.openstring(f,zerobased)
+ if f then
+ return { f, 1, #f, zerobased or false }
+ end
end
function streams.close()
@@ -233,31 +241,31 @@ function streams.readinteger4le(f)
end
end
-function streams.readfixed4(f)
+function streams.readfixed2(f)
local i = f[2]
- local j = i + 3
+ local j = i + 1
f[2] = j + 1
- local a, b, c, d = byte(f[1],i,j)
+ local a, b = byte(f[1],i,j)
if a >= 0x80 then
- return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000
+ tonumber((a - 0x100) .. "." .. b)
else
- return (0x100 * a + b ) + (0x100 * c + d)/0x10000
+ tonumber((a ) .. "." .. b)
end
end
-function streams.readfixed2(f)
+function streams.readfixed4(f)
local i = f[2]
- local j = i + 1
+ local j = i + 3
f[2] = j + 1
- local a, b = byte(f[1],i,j)
+ local a, b, c, d = byte(f[1],i,j)
if a >= 0x80 then
- return (a - 0x100) + b/0x100
+ tonumber((0x100 * a + b - 0x10000) .. "." .. (0x100 * c + d))
else
- return (a ) + b/0x100
+ tonumber((0x100 * a + b ) .. "." .. (0x100 * c + d))
end
end
-if extract then
+if bit32 then
local extract = bit32.extract
local band = bit32.band
@@ -386,3 +394,80 @@ if sio and sio.readcardinal2 then
streams.readinteger = streams.readinteger1
end
+
+if sio and sio.readcardinaltable then
+
+ local readcardinaltable = sio.readcardinaltable
+ local readintegertable = sio.readintegertable
+
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+
+ function utilities.streams.readintegertable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
+
+else
+
+ local readcardinal1 = streams.readcardinal1
+ local readcardinal2 = streams.readcardinal2
+ local readcardinal3 = streams.readcardinal3
+ local readcardinal4 = streams.readcardinal4
+
+ function streams.readcardinaltable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readcardinal1(f[1],i) end
+ elseif b == 2 then for i=1,n do t[i] = readcardinal2(f[1],i) end
+ elseif b == 3 then for i=1,n do t[i] = readcardinal3(f[1],i) end
+ elseif b == 4 then for i=1,n do t[i] = readcardinal4(f[1],i) end end
+ return t
+ end
+
+ local readinteger1 = streams.readinteger1
+ local readinteger2 = streams.readinteger2
+ local readinteger3 = streams.readinteger3
+ local readinteger4 = streams.readinteger4
+
+ function streams.readintegertable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readinteger1(f[1],i) end
+ elseif b == 2 then for i=1,n do t[i] = readinteger2(f[1],i) end
+ elseif b == 3 then for i=1,n do t[i] = readinteger3(f[1],i) end
+ elseif b == 4 then for i=1,n do t[i] = readinteger4(f[1],i) end end
+ return t
+ end
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-seq.lua b/Master/texmf-dist/tex/context/base/mkiv/util-seq.lua
index d302ff276f1..e7a503fafcd 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-seq.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-seq.lua
@@ -17,26 +17,39 @@ use locals to refer to them when compiling the chain.
-- todo: protect groups (as in tasks)
-local gsub, concat, gmatch = string.gsub, table.concat, string.gmatch
-local type, load = type, load
+local gsub, gmatch = string.gsub, string.gmatch
+local concat, sortedkeys = table.concat, table.sortedkeys
+local type, load, next, tostring = type, load, next, tostring
-utilities = utilities or { }
-local tables = utilities.tables
-local allocate = utilities.storage.allocate
+utilities = utilities or { }
+local tables = utilities.tables
+local allocate = utilities.storage.allocate
-local formatters = string.formatters
+local formatters = string.formatters
+local replacer = utilities.templates.replacer
-local sequencers = { }
-utilities.sequencers = sequencers
+local trace_used = false
+local trace_detail = false
+local report = logs.reporter("sequencer")
+local usedcount = 0
+local usednames = { }
-local functions = allocate()
-sequencers.functions = functions
+trackers.register("sequencers.used", function(v) trace_used = true end)
+trackers.register("sequencers.detail",function(v) trace_detail = true end)
+
+local sequencers = { }
+utilities.sequencers = sequencers
+
+local functions = allocate()
+sequencers.functions = functions
local removevalue = tables.removevalue
local replacevalue = tables.replacevalue
local insertaftervalue = tables.insertaftervalue
local insertbeforevalue = tables.insertbeforevalue
+local usedsequences = { }
+
local function validaction(action)
if type(action) == "string" then
local g = _G
@@ -63,9 +76,11 @@ function sequencers.new(t) -- was reset
gskip = { },
dirty = true,
runner = nil,
+ steps = 0,
}
if t then
s.arguments = t.arguments
+ s.templates = t.templates
s.returnvalues = t.returnvalues
s.results = t.results
local name = t.name
@@ -86,120 +101,142 @@ function sequencers.new(t) -- was reset
end
function sequencers.prependgroup(t,group,where)
- t = known[t]
- if t then
- local order = t.order
- removevalue(order,group)
- insertbeforevalue(order,where,group)
- t.list[group] = { }
- t.dirty = true
- t.runner = nil
+ if t and group then
+ t = known[t]
+ if t then
+ local order = t.order
+ removevalue(order,group)
+ insertbeforevalue(order,where,group)
+ t.list[group] = { }
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.appendgroup(t,group,where)
- t = known[t]
- if t then
- local order = t.order
- removevalue(order,group)
- insertaftervalue(order,where,group)
- t.list[group] = { }
- t.dirty = true
- t.runner = nil
+ if t and group then
+ t = known[t]
+ if t then
+ local order = t.order
+ removevalue(order,group)
+ insertaftervalue(order,where,group)
+ t.list[group] = { }
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.prependaction(t,group,action,where,kind,force)
- t = known[t]
- if t then
- local g = t.list[group]
- if g and (force or validaction(action)) then
- removevalue(g,action)
- insertbeforevalue(g,where,action)
- t.kind[action] = kind
- t.dirty = true
- t.runner = nil
+ if t and group and action then
+ t = known[t]
+ if t then
+ local g = t.list[group]
+ if g and (force or validaction(action)) then
+ removevalue(g,action)
+ insertbeforevalue(g,where,action)
+ t.kind[action] = kind
+ t.dirty = true
+ t.runner = nil
+ end
end
end
end
function sequencers.appendaction(t,group,action,where,kind,force)
- t = known[t]
- if t then
- local g = t.list[group]
- if g and (force or validaction(action)) then
- removevalue(g,action)
- insertaftervalue(g,where,action)
- t.kind[action] = kind
- t.dirty = true
- t.runner = nil
+ if t and group and action then
+ t = known[t]
+ if t then
+ local g = t.list[group]
+ if g and (force or validaction(action)) then
+ removevalue(g,action)
+ insertaftervalue(g,where,action)
+ t.kind[action] = kind
+ t.dirty = true
+ t.runner = nil
+ end
end
end
end
function sequencers.enableaction(t,action)
- t = known[t]
- if t then
- t.askip[action] = false
- t.dirty = true
- t.runner = nil
+ if t and action then
+ t = known[t]
+ if t then
+ t.askip[action] = false
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.disableaction(t,action)
- t = known[t]
- if t then
- t.askip[action] = true
- t.dirty = true
- t.runner = nil
+ if t and action then
+ t = known[t]
+ if t then
+ t.askip[action] = true
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.enablegroup(t,group)
- t = known[t]
- if t then
- t.gskip[action] = false
- t.dirty = true
- t.runner = nil
+ if t and group then
+ t = known[t]
+ if t then
+ t.gskip[group] = false
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.disablegroup(t,group)
- t = known[t]
- if t then
- t.gskip[action] = true
- t.dirty = true
- t.runner = nil
+ if t and group then
+ t = known[t]
+ if t then
+ t.gskip[group] = true
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.setkind(t,action,kind)
- t = known[t]
- if t then
- t.kind[action] = kind
- t.dirty = true
- t.runner = nil
+ if t and action then
+ t = known[t]
+ if t then
+ t.kind[action] = kind
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.removeaction(t,group,action,force)
- t = known[t]
- local g = t and t.list[group]
- if g and (force or validaction(action)) then
- removevalue(g,action)
- t.dirty = true
- t.runner = nil
+ if t and group and action then
+ t = known[t]
+ local g = t and t.list[group]
+ if g and (force or validaction(action)) then
+ removevalue(g,action)
+ t.dirty = true
+ t.runner = nil
+ end
end
end
function sequencers.replaceaction(t,group,oldaction,newaction,force)
- t = known[t]
- if t then
- local g = t.list[group]
- if g and (force or validaction(oldaction)) then
- replacevalue(g,oldaction,newaction)
- t.dirty = true
- t.runner = nil
+ if t and group and oldaction and newaction then
+ t = known[t]
+ if t then
+ local g = t.list[group]
+ if g and (force or validaction(oldaction)) then
+ replacevalue(g,oldaction,newaction)
+ t.dirty = true
+ t.runner = nil
+ end
end
end
end
@@ -209,9 +246,19 @@ local function localize(str)
end
local function construct(t)
- local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip
- local arguments, returnvalues, results = t.arguments or "...", t.returnvalues, t.results
- local variables, calls, n = { }, { }, 0
+ local list = t.list
+ local order = t.order
+ local kind = t.kind
+ local gskip = t.gskip
+ local askip = t.askip
+ local name = t.name or "?"
+ local arguments = t.arguments or "..."
+ local returnvalues = t.returnvalues
+ local results = t.results
+ local variables = { }
+ local calls = { }
+ local n = 0
+ usedcount = usedcount + 1
for i=1,#order do
local group = order[i]
if not gskip[group] then
@@ -219,6 +266,11 @@ local function construct(t)
for i=1,#actions do
local action = actions[i]
if not askip[action] then
+ if trace_used then
+ local action = tostring(action)
+ report("%02i: category %a, group %a, action %a",usedcount,name,group,action)
+ usednames[action] = true
+ end
local localized
if type(action) == "function" then
local name = localize(tostring(action))
@@ -242,6 +294,7 @@ local function construct(t)
end
end
t.dirty = false
+ t.steps = n
if n == 0 then
t.compiled = ""
else
@@ -253,30 +306,27 @@ local function construct(t)
t.compiled = formatters["%s\nreturn function(%s)\n%s\nend"](variables,arguments,calls)
end
end
--- print(t.compiled)
return t.compiled -- also stored so that we can trace
end
sequencers.tostring = construct
sequencers.localize = localize
-compile = function(t,compiler,n) -- already referred to in sequencers.new
+compile = function(t,compiler,...) -- already referred to in sequencers.new
local compiled
if not t or type(t) == "string" then
- -- weird ... t.compiled = t .. so
return false
end
if compiler then
- compiled = compiler(t,n)
+ compiled = compiler(t,...)
t.compiled = compiled
else
- compiled = construct(t,n)
+ compiled = construct(t,...)
end
local runner
if compiled == "" then
runner = false
else
--- inspect(compiled)
runner = compiled and load(compiled)() -- we can use loadstripped here
end
t.runner = runner
@@ -285,52 +335,45 @@ end
sequencers.compile = compile
--- we used to deal with tail as well but now that the lists are always
--- double linked and the kernel function no longer expect tail as
--- argument we stick to head and done (done can probably also go
--- as luatex deals with return values efficiently now .. in the
--- past there was some copying involved, but no longer)
-
--- todo: use sequencer (can have arguments and returnvalues etc now)
-
-local template_yes_state = [[
-%s
-return function(head%s)
- local ok, done = false, false
-%s
- return head, done
-end]]
-
-local template_yes_nostate = [[
-%s
-return function(head%s)
-%s
- return head, true
-end]]
-
-local template_nop = [[
-return function()
- return false, false
-end]]
-
-function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug into tostring
- local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip
- local nostate = t.nostate
- local vars, calls, args, n = { }, { }, nil, 0
- if nofarguments == 0 then
- args = ""
- elseif nofarguments == 1 then
- args = ",one"
- elseif nofarguments == 2 then
- args = ",one,two"
- elseif nofarguments == 3 then -- from here on probably slower than ...
- args = ",one,two,three"
- elseif nofarguments == 4 then
- args = ",one,two,three,four"
- elseif nofarguments == 5 then
- args = ",one,two,three,four,five"
- else
- args = ",..."
+function sequencers.nodeprocessor(t,nofarguments)
+ --
+ local templates = nofarguments
+ --
+ if type(templates) ~= "table" then
+ return ""
+ end
+ --
+ local replacers = { }
+ for k, v in next, templates do
+ replacers[k] = replacer(v)
+ end
+ --
+ local construct = replacers.process
+ local step = replacers.step
+ if not construct or not step then
+ return ""
+ end
+ --
+ local calls = { }
+ local aliases = { }
+ local ncalls = 0
+ local naliases = 0
+ local f_alias = formatters["local %s = %s"]
+ --
+ local list = t.list
+ local order = t.order
+ local kind = t.kind
+ local gskip = t.gskip
+ local askip = t.askip
+ local name = t.name or "?"
+ local steps = 0
+ usedcount = usedcount + 1
+ --
+ if trace_detail then
+ naliases = naliases + 1
+ aliases[naliases] = formatters["local report = logs.reporter('sequencer',%q)"](name)
+ ncalls = ncalls + 1
+ calls[ncalls] = [[report("start")]]
end
for i=1,#order do
local group = order[i]
@@ -339,28 +382,47 @@ function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug
for i=1,#actions do
local action = actions[i]
if not askip[action] then
- local localized = localize(action)
- n = n + 1
- vars[n] = formatters["local %s = %s"](localized,action)
- -- only difference with tostring is kind and rets (why no return)
- if nostate then
- if kind[action] == "nohead" then
- calls[n] = formatters[" %s(head%s)"](localized,args)
- else
- calls[n] = formatters[" head = %s(head%s)"](localized,args)
- end
- else
- if kind[action] == "nohead" then
- calls[n] = formatters[" ok = %s(head%s) if ok then done = true end"](localized,args)
- else
- calls[n] = formatters[" head, ok = %s(head%s) if ok then done = true end"](localized,args)
- end
+ steps = steps + 1
+ if trace_used or trace_detail then
+ local action = tostring(action)
+ report("%02i: category %a, group %a, action %a",usedcount,name,group,action)
+ usednames[action] = true
end
+ if trace_detail then
+ ncalls = ncalls + 1
+ calls[ncalls] = formatters[ [[report(" step %a, action %a")]] ](steps,tostring(action))
+ end
+ local localized = localize(action)
+ local onestep = replacers[kind[action]] or step
+ naliases = naliases + 1
+ ncalls = ncalls + 1
+ aliases[naliases] = f_alias(localized,action)
+ calls [ncalls] = onestep { action = localized }
end
end
end
end
- local processor = #calls > 0 and formatters[nostate and template_yes_nostate or template_yes_state](concat(vars,"\n"),args,concat(calls,"\n")) or template_nop
+ t.steps = steps
+ local processor
+ if steps == 0 then
+ processor = templates.default or construct { }
+ else
+ if trace_detail then
+ ncalls = ncalls + 1
+ calls[ncalls] = [[report("stop")]]
+ end
+ processor = construct {
+ localize = concat(aliases,"\n"),
+ actions = concat(calls,"\n"),
+ }
+ end
+ -- processor = "print('running : " .. (t.name or "?") .. "')\n" .. processor
-- print(processor)
return processor
end
+
+statistics.register("used sequences",function()
+ if next(usednames) then
+ return concat(sortedkeys(usednames)," ")
+ end
+end)
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sha.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sha.lua
index 3e786a834f6..d84e46975fa 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sha.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sha.lua
@@ -8,6 +8,13 @@ if not modules then modules = { } end modules ['util-sha'] = {
comment3 = "due to bit operators this code only works in lua(tex) 5.3",
}
+if sha2 then
+ if utilities then
+ utilities.sha2 = sha2
+ end
+ return sha2
+end
+
-- This doesn't work in luajittex ... maybe some day it will have bit operators too.
-- I'm not really in the mood for making this module aware (by compiling the
-- function depending on the engine that I use but I probably won't use luajittex in
@@ -277,10 +284,10 @@ digest[224] = digest[256]
digest[384] = digest[512]
local finalize = {
- [224] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4", unpack(hash))) end, -- # 56
- [256] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4I4",unpack(hash))) end, -- # 64
- [384] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8", unpack(hash))) end, -- # 96
- [512] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8I8I8",unpack(hash))) end, -- # 128
+ [224] = function(hash,tohex) local s = packstring(">I4I4I4I4I4I4I4", unpack(hash)) return tohex and tohex(s) or s end, -- # 56
+ [256] = function(hash,tohex) local s = packstring(">I4I4I4I4I4I4I4I4",unpack(hash)) return tohex and tohex(s) or s end, -- # 64
+ [384] = function(hash,tohex) local s = packstring(">I8I8I8I8I8I8", unpack(hash)) return tohex and tohex(s) or s end, -- # 96
+ [512] = function(hash,tohex) local s = packstring(">I8I8I8I8I8I8I8I8",unpack(hash)) return tohex and tohex(s) or s end, -- # 128
}
local hash = { }
@@ -293,14 +300,18 @@ local function hashed(str,method,tohex)
end
local sha2 = {
- hash224 = function(str) return hashed(str,224,tohex) end,
- hash256 = function(str) return hashed(str,256,tohex) end,
- hash384 = function(str) return hashed(str,384,tohex) end,
- hash512 = function(str) return hashed(str,512,tohex) end,
- HASH224 = function(str) return hashed(str,224,toHEX) end,
- HASH256 = function(str) return hashed(str,256,toHEX) end,
- HASH384 = function(str) return hashed(str,384,toHEX) end,
- HASH512 = function(str) return hashed(str,512,toHEX) end,
+ digest224 = function(str) return hashed(str,224) end,
+ digest256 = function(str) return hashed(str,256) end,
+ digest384 = function(str) return hashed(str,384) end,
+ digest512 = function(str) return hashed(str,512) end,
+ hash224 = function(str) return hashed(str,224,tohex) end,
+ hash256 = function(str) return hashed(str,256,tohex) end,
+ hash384 = function(str) return hashed(str,384,tohex) end,
+ hash512 = function(str) return hashed(str,512,tohex) end,
+ HASH224 = function(str) return hashed(str,224,toHEX) end,
+ HASH256 = function(str) return hashed(str,256,toHEX) end,
+ HASH384 = function(str) return hashed(str,384,toHEX) end,
+ HASH512 = function(str) return hashed(str,512,toHEX) end,
}
-- local setmetatableindex = table.setmetatableindex
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua
new file mode 100644
index 00000000000..3e66e588838
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua
@@ -0,0 +1,931 @@
+-- original file : copas.lua
+-- for more into : see util-soc.lua
+
+local socket = socket or require("socket")
+local ssl = ssl or nil -- only loaded upon demand
+
+local WATCH_DOG_TIMEOUT = 120
+local UDP_DATAGRAM_MAX = 8192
+
+local type, next, pcall, getmetatable, tostring = type, next, pcall, getmetatable, tostring
+local min, max, random = math.min, math.max, math.random
+local find = string.find
+local insert, remove = table.insert, table.remove
+
+local gettime = socket.gettime
+local selectsocket = socket.select
+
+local createcoroutine = coroutine.create
+local resumecoroutine = coroutine.resume
+local yieldcoroutine = coroutine.yield
+local runningcoroutine = coroutine.running
+
+-- Redefines LuaSocket functions with coroutine safe versions (this allows the use
+-- of socket.http from within copas).
+
+-- Meta information is public even if beginning with an "_"
+
+local function report(fmt,first,...)
+ if logs then
+ report = logs and logs.reporter("copas")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt = "copas: " .. fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
+ end
+ end
+end
+
+local copas = {
+
+ _COPYRIGHT = "Copyright (C) 2005-2016 Kepler Project",
+ _DESCRIPTION = "Coroutine Oriented Portable Asynchronous Services",
+ _VERSION = "Copas 2.0.1",
+
+ autoclose = true,
+ running = false,
+
+ report = report,
+
+}
+
+local function statushandler(status, ...)
+ if status then
+ return ...
+ end
+ local err = (...)
+ if type(err) == "table" then
+ err = err[1]
+ end
+ report("error: %s",tostring(err))
+ return nil, err
+end
+
+function socket.protect(func)
+ return function(...)
+ return statushandler(pcall(func,...))
+ end
+end
+
+function socket.newtry(finalizer)
+ return function (...)
+ local status = (...)
+ if not status then
+ local detail = select(2,...)
+ pcall(finalizer,detail)
+ report("error: %s",tostring(detail))
+ return
+ end
+ return ...
+ end
+end
+
+-- Simple set implementation based on LuaSocket's tinyirc.lua example
+-- adds a FIFO queue for each value in the set
+
+local function newset()
+ local reverse = { }
+ local set = { }
+ local queue = { }
+ setmetatable(set, {
+ __index = {
+ insert =
+ function(set, value)
+ if not reverse[value] then
+ local n = #set +1
+ set[n] = value
+ reverse[value] = n
+ end
+ end,
+ remove =
+ function(set, value)
+ local index = reverse[value]
+ if index then
+ reverse[value] = nil
+ local n = #set
+ local top = set[n]
+ set[n] = nil
+ if top ~= value then
+ reverse[top] = index
+ set[index] = top
+ end
+ end
+ end,
+ push =
+ function (set, key, itm)
+ local entry = queue[key]
+ if entry == nil then -- hm can it be false then?
+ queue[key] = { itm }
+ else
+ entry[#entry + 1] = itm
+ end
+ end,
+ pop =
+ function (set, key)
+ local top = queue[key]
+ if top ~= nil then
+ local ret = remove(top,1)
+ if top[1] == nil then
+ queue[key] = nil
+ end
+ return ret
+ end
+ end
+ }
+ } )
+ return set
+end
+
+local _sleeping = {
+ times = { }, -- list with wake-up times
+ cos = { }, -- list with coroutines, index matches the 'times' list
+ lethargy = { }, -- list of coroutines sleeping without a wakeup time
+
+ insert =
+ function()
+ end,
+ remove =
+ function()
+ end,
+ push =
+ function(self, sleeptime, co)
+ if not co then
+ return
+ end
+ if sleeptime < 0 then
+ --sleep until explicit wakeup through copas.wakeup
+ self.lethargy[co] = true
+ return
+ else
+ sleeptime = gettime() + sleeptime
+ end
+ local t = self.times
+ local c = self.cos
+ local i = 1
+ local n = #t
+ while i <= n and t[i] <= sleeptime do
+ i = i + 1
+ end
+ insert(t,i,sleeptime)
+ insert(c,i,co)
+ end,
+ getnext =
+ -- returns delay until next sleep expires, or nil if there is none
+ function(self)
+ local t = self.times
+ local delay = t[1] and t[1] - gettime() or nil
+ return delay and max(delay, 0) or nil
+ end,
+ pop =
+ -- find the thread that should wake up to the time
+ function(self, time)
+ local t = self.times
+ local c = self.cos
+ if #t == 0 or time < t[1] then
+ return
+ end
+ local co = c[1]
+ remove(t,1)
+ remove(c,1)
+ return co
+ end,
+ wakeup =
+ function(self, co)
+ local let = self.lethargy
+ if let[co] then
+ self:push(0, co)
+ let[co] = nil
+ else
+ local c = self.cos
+ local t = self.times
+ for i=1,#c do
+ if c[i] == co then
+ remove(c,i)
+ remove(t,i)
+ self:push(0, co)
+ return
+ end
+ end
+ end
+ end
+}
+
+local _servers = newset() -- servers being handled
+local _reading = newset() -- sockets currently being read
+local _writing = newset() -- sockets currently being written
+
+local _reading_log = { }
+local _writing_log = { }
+
+local _is_timeout = { -- set of errors indicating a timeout
+ timeout = true, -- default LuaSocket timeout
+ wantread = true, -- LuaSec specific timeout
+ wantwrite = true, -- LuaSec specific timeout
+}
+
+-- Coroutine based socket I/O functions.
+
+local function isTCP(socket)
+ return not find(tostring(socket),"^udp")
+end
+
+-- Reads a pattern from a client and yields to the reading set on timeouts UDP: a
+-- UDP socket expects a second argument to be a number, so it MUST be provided as
+-- the 'pattern' below defaults to a string. Will throw a 'bad argument' error if
+-- omitted.
+
+local function copasreceive(client, pattern, part)
+ if not pattern or pattern == "" then
+ pattern = "*l"
+ end
+ local current_log = _reading_log
+ local s, err
+ repeat
+ s, err, part = client:receive(pattern, part)
+ if s or (not _is_timeout[err]) then
+ current_log[client] = nil
+ return s, err, part
+ end
+ if err == "wantwrite" then
+ current_log = _writing_log
+ current_log[client] = gettime()
+ yieldcoroutine(client, _writing)
+ else
+ current_log = _reading_log
+ current_log[client] = gettime()
+ yieldcoroutine(client, _reading)
+ end
+ until false
+end
+
+-- Receives data from a client over UDP. Not available for TCP. (this is a copy of
+-- receive() method, adapted for receivefrom() use).
+
+local function copasreceivefrom(client, size)
+ local s, err, port
+ if not size or size == 0 then
+ size = UDP_DATAGRAM_MAX
+ end
+ repeat
+ -- upon success err holds ip address
+ s, err, port = client:receivefrom(size)
+ if s or err ~= "timeout" then
+ _reading_log[client] = nil
+ return s, err, port
+ end
+ _reading_log[client] = gettime()
+ yieldcoroutine(client, _reading)
+ until false
+end
+
+-- Same as above but with special treatment when reading chunks, unblocks on any
+-- data received.
+
+local function copasreceivepartial(client, pattern, part)
+ if not pattern or pattern == "" then
+ pattern = "*l"
+ end
+ local logger = _reading_log
+ local queue = _reading
+ local s, err
+ repeat
+ s, err, part = client:receive(pattern, part)
+ if s or (type(pattern) == "number" and part ~= "" and part) or not _is_timeout[err] then
+ logger[client] = nil
+ return s, err, part
+ end
+ if err == "wantwrite" then
+ logger = _writing_log
+ queue = _writing
+ else
+ logger = _reading_log
+ queue = _reading
+ end
+ logger[client] = gettime()
+ yieldcoroutine(client, queue)
+ until false
+end
+
+-- Sends data to a client. The operation is buffered and yields to the writing set
+-- on timeouts Note: from and to parameters will be ignored by/for UDP sockets
+
+local function copassend(client, data, from, to)
+ if not from then
+ from = 1
+ end
+ local lastIndex = from - 1
+ local logger = _writing_log
+ local queue = _writing
+ local s, err
+ repeat
+ s, err, lastIndex = client:send(data, lastIndex + 1, to)
+ -- Adds extra coroutine swap and garantees that high throughput doesn't take
+ -- other threads to starvation.
+ if random(100) > 90 then
+ logger[client] = gettime()
+ yieldcoroutine(client, queue)
+ end
+ if s or not _is_timeout[err] then
+ logger[client] = nil
+ return s, err,lastIndex
+ end
+ if err == "wantread" then
+ logger = _reading_log
+ queue = _reading
+ else
+ logger = _writing_log
+ queue = _writing
+ end
+ logger[client] = gettime()
+ yieldcoroutine(client, queue)
+ until false
+end
+
+-- Sends data to a client over UDP. Not available for TCP. (this is a copy of send()
+-- method, adapted for sendto() use).
+
+local function copassendto(client, data, ip, port)
+ repeat
+ local s, err = client:sendto(data, ip, port)
+ -- Adds extra coroutine swap and garantees that high throughput doesn't
+ -- take other threads to starvation.
+ if random(100) > 90 then
+ _writing_log[client] = gettime()
+ yieldcoroutine(client, _writing)
+ end
+ if s or err ~= "timeout" then
+ _writing_log[client] = nil
+ return s, err
+ end
+ _writing_log[client] = gettime()
+ yieldcoroutine(client, _writing)
+ until false
+end
+
+-- Waits until connection is completed.
+
+local function copasconnect(skt, host, port)
+ skt:settimeout(0)
+ local ret, err, tried_more_than_once
+ repeat
+ ret, err = skt:connect (host, port)
+ -- A non-blocking connect on Windows results in error "Operation already in
+ -- progress" to indicate that it is completing the request async. So
+ -- essentially it is the same as "timeout".
+ if ret or (err ~= "timeout" and err ~= "Operation already in progress") then
+ -- Once the async connect completes, Windows returns the error "already
+ -- connected" to indicate it is done, so that error should be ignored.
+ -- Except when it is the first call to connect, then it was already
+ -- connected to something else and the error should be returned.
+ if not ret and err == "already connected" and tried_more_than_once then
+ ret = 1
+ err = nil
+ end
+ _writing_log[skt] = nil
+ return ret, err
+ end
+ tried_more_than_once = tried_more_than_once or true
+ _writing_log[skt] = gettime()
+ yieldcoroutine(skt, _writing)
+ until false
+end
+
+-- Peforms an (async) ssl handshake on a connected TCP client socket. Replacec all
+-- previous socket references, with the returned new ssl wrapped socket Throws error
+-- and does not return nil+error, as that might silently fail in code like this.
+
+local function copasdohandshake(skt, sslt) -- extra ssl parameters
+ if not ssl then
+ ssl = require("ssl")
+ end
+ if not ssl then
+ report("error: no ssl library")
+ return
+ end
+ local nskt, err = ssl.wrap(skt, sslt)
+ if not nskt then
+ report("error: %s",tostring(err))
+ return
+ end
+ nskt:settimeout(0)
+ local queue
+ repeat
+ local success, err = nskt:dohandshake()
+ if success then
+ return nskt
+ elseif err == "wantwrite" then
+ queue = _writing
+ elseif err == "wantread" then
+ queue = _reading
+ else
+ report("error: %s",tostring(err))
+ return
+ end
+ yieldcoroutine(nskt, queue)
+ until false
+end
+
+-- Flushes a client write buffer.
+
+local function copasflush(client)
+end
+
+-- Public.
+
+copas.connect = copassconnect
+copas.send = copassend
+copas.sendto = copassendto
+copas.receive = copasreceive
+copas.receivefrom = copasreceivefrom
+copas.copasreceivepartial = copasreceivepartial
+copas.copasreceivePartial = copasreceivepartial
+copas.dohandshake = copasdohandshake
+copas.flush = copasflush
+
+-- Wraps a TCP socket to use Copas methods (send, receive, flush and settimeout).
+
+local function _skt_mt_tostring(self)
+ return tostring(self.socket) .. " (copas wrapped)"
+end
+
+local _skt_mt_tcp_index = {
+ send =
+ function(self, data, from, to)
+ return copassend (self.socket, data, from, to)
+ end,
+ receive =
+ function (self, pattern, prefix)
+ if self.timeout == 0 then
+ return copasreceivePartial(self.socket, pattern, prefix)
+ else
+ return copasreceive(self.socket, pattern, prefix)
+ end
+ end,
+
+ flush =
+ function (self)
+ return copasflush(self.socket)
+ end,
+
+ settimeout =
+ function (self, time)
+ self.timeout = time
+ return true
+ end,
+ -- TODO: socket.connect is a shortcut, and must be provided with an alternative
+ -- if ssl parameters are available, it will also include a handshake
+ connect =
+ function(self, ...)
+ local res, err = copasconnect(self.socket, ...)
+ if res and self.ssl_params then
+ res, err = self:dohandshake()
+ end
+ return res, err
+ end,
+ close =
+ function(self, ...)
+ return self.socket:close(...)
+ end,
+ -- TODO: socket.bind is a shortcut, and must be provided with an alternative
+ bind =
+ function(self, ...)
+ return self.socket:bind(...)
+ end,
+ -- TODO: is this DNS related? hence blocking?
+ getsockname =
+ function(self, ...)
+ return self.socket:getsockname(...)
+ end,
+ getstats =
+ function(self, ...)
+ return self.socket:getstats(...)
+ end,
+ setstats =
+ function(self, ...)
+ return self.socket:setstats(...)
+ end,
+ listen =
+ function(self, ...)
+ return self.socket:listen(...)
+ end,
+ accept =
+ function(self, ...)
+ return self.socket:accept(...)
+ end,
+ setoption =
+ function(self, ...)
+ return self.socket:setoption(...)
+ end,
+ -- TODO: is this DNS related? hence blocking?
+ getpeername =
+ function(self, ...)
+ return self.socket:getpeername(...)
+ end,
+ shutdown =
+ function(self, ...)
+ return self.socket:shutdown(...)
+ end,
+ dohandshake =
+ function(self, sslt)
+ self.ssl_params = sslt or self.ssl_params
+ local nskt, err = copasdohandshake(self.socket, self.ssl_params)
+ if not nskt then
+ return nskt, err
+ end
+ self.socket = nskt
+ return self
+ end,
+}
+
+local _skt_mt_tcp = {
+ __tostring = _skt_mt_tostring,
+ __index = _skt_mt_tcp_index,
+}
+
+-- wraps a UDP socket, copy of TCP one adapted for UDP.
+
+local _skt_mt_udp_index = {
+ -- UDP sending is non-blocking, but we provide starvation prevention, so replace
+ -- anyway.
+ sendto =
+ function (self, ...)
+ return copassendto(self.socket,...)
+ end,
+ receive =
+ function (self, size)
+ return copasreceive(self.socket, size or UDP_DATAGRAM_MAX)
+ end,
+ receivefrom =
+ function (self, size)
+ return copasreceivefrom(self.socket, size or UDP_DATAGRAM_MAX)
+ end,
+ -- TODO: is this DNS related? hence blocking?
+ setpeername =
+ function(self, ...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname =
+ function(self, ...)
+ return self.socket:setsockname(...)
+ end,
+ -- do not close client, as it is also the server for udp.
+ close =
+ function(self, ...)
+ return true
+ end
+}
+
+local _skt_mt_udp = {
+ __tostring = _skt_mt_tostring,
+ __index = _skt_mt_udp_index,
+}
+
+for k, v in next, _skt_mt_tcp_index do
+ if not _skt_mt_udp_index[k] then
+ _skt_mt_udp_index[k] = v
+ end
+end
+
+-- Wraps a LuaSocket socket object in an async Copas based socket object.
+
+-- @param skt the socket to wrap
+-- @sslt (optional) Table with ssl parameters, use an empty table to use ssl with defaults
+-- @return wrapped socket object
+
+local function wrap(skt, sslt)
+ if getmetatable(skt) == _skt_mt_tcp or getmetatable(skt) == _skt_mt_udp then
+ return skt -- already wrapped
+ end
+ skt:settimeout(0)
+ if isTCP(skt) then
+ return setmetatable ({ socket = skt, ssl_params = sslt }, _skt_mt_tcp)
+ else
+ return setmetatable ({ socket = skt }, _skt_mt_udp)
+ end
+end
+
+copas.wrap = wrap
+
+-- Wraps a handler in a function that deals with wrapping the socket and doing
+-- the optional ssl handshake.
+
+function copas.handler(handler, sslparams)
+ return function (skt,...)
+ skt = wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
+ end
+ return handler(skt,...)
+ end
+end
+
+-- Error handling (a handler per coroutine).
+
+local _errhandlers = { }
+
+function copas.setErrorHandler(err)
+ local co = runningcoroutine()
+ if co then
+ _errhandlers[co] = err
+ end
+end
+
+local function _deferror (msg, co, skt)
+ report("%s (%s) (%s)", msg, tostring(co), tostring(skt))
+end
+
+-- Thread handling
+
+local function _doTick (co, skt, ...)
+ if not co then
+ return
+ end
+
+ local ok, res, new_q = resumecoroutine(co, skt, ...)
+
+ if ok and res and new_q then
+ new_q:insert(res)
+ new_q:push(res, co)
+ else
+ if not ok then
+ pcall(_errhandlers[co] or _deferror, res, co, skt)
+ end
+ -- Do not auto-close UDP sockets, as the handler socket is also the server socket.
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
+ end
+ _errhandlers[co] = nil
+ end
+end
+
+-- Accepts a connection on socket input.
+
+local function _accept(input, handler)
+ local client = input:accept()
+ if client then
+ client:settimeout(0)
+ local co = createcoroutine(handler)
+ _doTick (co, client)
+ -- _reading:insert(client)
+ end
+ return client
+end
+
+-- Handle threads on a queue.
+
+local function _tickRead(skt)
+ _doTick(_reading:pop(skt), skt)
+end
+
+local function _tickWrite(skt)
+ _doTick(_writing:pop(skt), skt)
+end
+
+-- Adds a server/handler pair to Copas dispatcher.
+
+local function addTCPserver(server, handler, timeout)
+ server:settimeout(timeout or 0)
+ _servers[server] = handler
+ _reading:insert(server)
+end
+
+local function addUDPserver(server, handler, timeout)
+ server:settimeout(timeout or 0)
+ local co = createcoroutine(handler)
+ _reading:insert(server)
+ _doTick(co, server)
+end
+
+function copas.addserver(server, handler, timeout)
+ if isTCP(server) then
+ addTCPserver(server, handler, timeout)
+ else
+ addUDPserver(server, handler, timeout)
+ end
+end
+
+function copas.removeserver(server, keep_open)
+ local s = server
+ local mt = getmetatable(server)
+ if mt == _skt_mt_tcp or mt == _skt_mt_udp then
+ s = server.socket
+ end
+ _servers[s] = nil
+ _reading:remove(s)
+ if keep_open then
+ return true
+ end
+ return server:close()
+end
+
+-- Adds an new coroutine thread to Copas dispatcher. Create a coroutine that skips
+-- the first argument, which is always the socket passed by the scheduler, but `nil`
+-- in case of a task/thread
+
+function copas.addthread(handler, ...)
+ local thread = createcoroutine(function(_, ...) return handler(...) end)
+ _doTick(thread, nil, ...)
+ return thread
+end
+
+-- tasks registering
+
+local _tasks = { }
+
+-- Lets tasks call the default _tick().
+
+local function addtaskRead(task)
+ task.def_tick = _tickRead
+ _tasks[task] = true
+end
+
+-- Lets tasks call the default _tick().
+
+local function addtaskWrite(task)
+ task.def_tick = _tickWrite
+ _tasks[task] = true
+end
+
+local function tasks()
+ return next, _tasks
+end
+
+-- A task to check ready to read events.
+
+local _readable_t = {
+ events =
+ function(self)
+ local i = 0
+ return function ()
+ i = i + 1
+ return self._evs[i]
+ end
+ end,
+ tick =
+ function(self, input)
+ local handler = _servers[input]
+ if handler then
+ input = _accept(input, handler)
+ else
+ _reading:remove(input)
+ self.def_tick(input)
+ end
+ end
+}
+
+addtaskRead(_readable_t)
+
+-- A task to check ready to write events.
+
+local _writable_t = {
+ events =
+ function(self)
+ local i = 0
+ return function()
+ i = i + 1
+ return self._evs[i]
+ end
+ end,
+ tick =
+ function(self, output)
+ _writing:remove(output)
+ self.def_tick(output)
+ end
+}
+
+addtaskWrite(_writable_t)
+
+--sleeping threads task
+
+local _sleeping_t = {
+ tick = function(self, time, ...)
+ _doTick(_sleeping:pop(time), ...)
+ end
+}
+
+-- yields the current coroutine and wakes it after 'sleeptime' seconds.
+-- If sleeptime<0 then it sleeps until explicitly woken up using 'wakeup'
+function copas.sleep(sleeptime)
+ yieldcoroutine((sleeptime or 0), _sleeping)
+end
+
+-- Wakes up a sleeping coroutine 'co'.
+
+function copas.wakeup(co)
+ _sleeping:wakeup(co)
+end
+
+-- Checks for reads and writes on sockets
+
+local last_cleansing = 0
+
+local function _select(timeout)
+
+ local now = gettime()
+
+ local r_evs, w_evs, err = selectsocket(_reading, _writing, timeout)
+
+ _readable_t._evs = r_evs
+ _writable_t._evs = w_evs
+
+ if (last_cleansing - now) > WATCH_DOG_TIMEOUT then
+
+ last_cleansing = now
+
+ -- Check all sockets selected for reading, and check how long they have been
+ -- waiting for data already, without select returning them as readable.
+
+ for skt, time in next, _reading_log do
+
+ if not r_evs[skt] and (time - now) > WATCH_DOG_TIMEOUT then
+
+ -- This one timedout while waiting to become readable, so move it in
+ -- the readable list and try and read anyway, despite not having
+ -- been returned by select.
+
+ local n = #r_evs + 1
+ _reading_log[skt] = nil
+ r_evs[n] = skt
+ r_evs[skt] = n
+ end
+ end
+
+ -- Do the same for writing.
+
+ for skt, time in next, _writing_log do
+ if not w_evs[skt] and (time - now) > WATCH_DOG_TIMEOUT then
+ local n = #w_evs + 1
+ _writing_log[skt] = nil
+ w_evs[n] = skt
+ w_evs[skt] = n
+ end
+ end
+
+ end
+
+ if err == "timeout" and #r_evs + #w_evs > 0 then
+ return nil
+ else
+ return err
+ end
+
+end
+
+-- Check whether there is something to do. It returns false if there are no sockets
+-- for read/write nor tasks scheduled (which means Copas is in an empty spin).
+
+local function copasfinished()
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
+end
+
+-- Dispatcher loop step. It listens to client requests and handles them and returns
+-- false if no data was handled (timeout), or true if there was data handled (or nil
+-- + error message).
+
+local function copasstep(timeout)
+ _sleeping_t:tick(gettime())
+
+ local nextwait = _sleeping:getnext()
+ if nextwait then
+ timeout = timeout and min(nextwait,timeout) or nextwait
+ elseif copasfinished() then
+ return false
+ end
+
+ local err = _select(timeout)
+ if err then
+ if err == "timeout" then
+ return false
+ end
+ return nil, err
+ end
+
+ for task in tasks() do
+ for event in task:events() do
+ task:tick(event)
+ end
+ end
+ return true
+end
+
+copas.finished = copasfinished
+copas.step = copasstep
+
+-- Dispatcher endless loop. It listens to client requests and handles them forever.
+
+function copas.loop(timeout)
+ copas.running = true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running = false
+end
+
+-- _G.copas = copas
+
+package.loaded["copas"] = copas
+
+return copas
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ftp.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ftp.lua
new file mode 100644
index 00000000000..124c8d4ee71
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ftp.lua
@@ -0,0 +1,402 @@
+-- original file : ftp.lua
+-- for more into : see util-soc.lua
+
+local setmetatable, type, next = setmetatable, type, next
+local find, format, gsub, match = string.find, string.format, string.gsub, string.match
+local concat = table.concat
+local mod = math.mod
+
+local socket = socket or require("socket")
+local url = socket.url or require("socket.url")
+local tp = socket.tp or require("socket.tp")
+local ltn12 = ltn12 or require("ltn12")
+
+local tcpsocket = socket.tcp
+local trysocket = socket.try
+local skipsocket = socket.skip
+local sinksocket = socket.sink
+local selectsocket = socket.select
+local bindsocket = socket.bind
+local newtrysocket = socket.newtry
+local sourcesocket = socket.source
+local protectsocket = socket.protect
+
+local parseurl = url.parse
+local unescapeurl = url.unescape
+
+local pumpall = ltn12.pump.all
+local pumpstep = ltn12.pump.step
+local sourcestring = ltn12.source.string
+local sinktable = ltn12.sink.table
+
+local ftp = {
+ TIMEOUT = 60,
+ USER = "ftp",
+ PASSWORD = "anonymous@anonymous.org",
+}
+
+socket.ftp = ftp
+
+local PORT = 21
+
+local methods = { }
+local mt = { __index = methods }
+
+function ftp.open(server, port, create)
+ local tp = trysocket(tp.connect(server, port or PORT, ftp.TIMEOUT, create))
+ local f = setmetatable({ tp = tp }, metat)
+ f.try = newtrysocket(function() f:close() end)
+ return f
+end
+
+function methods.portconnect(self)
+ local try = self.try
+ local server = self.server
+ try(server:settimeout(ftp.TIMEOUT))
+ self.data = try(server:accept())
+ try(self.data:settimeout(ftp.TIMEOUT))
+end
+
+function methods.pasvconnect(self)
+ local try = self.try
+ self.data = try(tcpsocket())
+ self(self.data:settimeout(ftp.TIMEOUT))
+ self(self.data:connect(self.pasvt.address, self.pasvt.port))
+end
+
+function methods.login(self, user, password)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("user", user or ftp.USER))
+ local code, reply = try(tp:check{"2..", 331})
+ if code == 331 then
+ try(tp:command("pass", password or ftp.PASSWORD))
+ try(tp:check("2.."))
+ end
+ return 1
+end
+
+function methods.pasv(self)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("pasv"))
+ local code, reply = try(self.tp:check("2.."))
+ local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
+ local a, b, c, d, p1, p2 = skipsocket(2, find(reply, pattern))
+ try(a and b and c and d and p1 and p2, reply)
+ local address = format("%d.%d.%d.%d", a, b, c, d)
+ local port = p1*256 + p2
+ local server = self.server
+ self.pasvt = {
+ address = address,
+ port = port,
+ }
+ if server then
+ server:close()
+ self.server = nil
+ end
+ return address, port
+end
+
+function methods.epsv(self)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("epsv"))
+ local code, reply = try(tp:check("229"))
+ local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d, prt, address, port = match(reply, pattern)
+ try(port, "invalid epsv response")
+ local address = tp:getpeername()
+ local server = self.server
+ self.pasvt = {
+ address = address,
+ port = port,
+ }
+ if self.server then
+ server:close()
+ self.server = nil
+ end
+ return address, port
+end
+
+function methods.port(self, address, port)
+ local try = self.try
+ local tp = self.tp
+ self.pasvt = nil
+ if not address then
+ address, port = try(tp:getsockname())
+ self.server = try(bindsocket(address, 0))
+ address, port = try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local pl = mod(port,256)
+ local ph = (port - pl)/256
+ local arg = gsub(format("%s,%d,%d", address, ph, pl), "%.", ",")
+ try(tp:command("port", arg))
+ try(tp:check("2.."))
+ return 1
+end
+
+function methods.eprt(self, family, address, port)
+ local try = self.try
+ local tp = self.tp
+ self.pasvt = nil
+ if not address then
+ address, port = try(tp:getsockname())
+ self.server = try(bindsocket(address, 0))
+ address, port = try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local arg = format("|%s|%s|%d|", family, address, port)
+ try(tp:command("eprt", arg))
+ try(tp:check("2.."))
+ return 1
+end
+
+function methods.send(self, sendt)
+ local try = self.try
+ local tp = self.tp
+ -- so we try a table or string ?
+ try(self.pasvt or self.server, "need port or pasv first")
+ if self.pasvt then
+ self:pasvconnect()
+ end
+ local argument = sendt.argument or unescapeurl(gsub(sendt.path or "", "^[/\\]", ""))
+ if argument == "" then
+ argument = nil
+ end
+ local command = sendt.command or "stor"
+ try(tp:command(command, argument))
+ local code, reply = try(tp:check{"2..", "1.."})
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local step = sendt.step or pumpstep
+ local readt = { tp }
+ local checkstep = function(src, snk)
+ local readyt = selectsocket(readt, nil, 0)
+ if readyt[tp] then
+ code = try(tp:check("2.."))
+ end
+ return step(src, snk)
+ end
+ local sink = sinksocket("close-when-done", self.data)
+ try(pumpall(sendt.source, sink, checkstep))
+ if find(code, "1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ local sent = skipsocket(1, self.data:getstats())
+ self.data = nil
+ return sent
+end
+
+function methods.receive(self, recvt)
+ local try = self.try
+ local tp = self.tp
+ try(self.pasvt or self.server, "need port or pasv first")
+ if self.pasvt then self:pasvconnect() end
+ local argument = recvt.argument or unescapeurl(gsub(recvt.path or "", "^[/\\]", ""))
+ if argument == "" then
+ argument = nil
+ end
+ local command = recvt.command or "retr"
+ try(tp:command(command, argument))
+ local code,reply = try(tp:check{"1..", "2.."})
+ if code >= 200 and code <= 299 then
+ recvt.sink(reply)
+ return 1
+ end
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local source = sourcesocket("until-closed", self.data)
+ local step = recvt.step or pumpstep
+ try(pumpall(source, recvt.sink, step))
+ if find(code, "1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ self.data = nil
+ return 1
+end
+
+function methods.cwd(self, dir)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("cwd", dir))
+ try(tp:check(250))
+ return 1
+end
+
+function methods.type(self, typ)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("type", typ))
+ try(tp:check(200))
+ return 1
+end
+
+function methods.greet(self)
+ local try = self.try
+ local tp = self.tp
+ local code = try(tp:check{"1..", "2.."})
+ if find(code, "1..") then
+ try(tp:check("2.."))
+ end
+ return 1
+end
+
+function methods.quit(self)
+ local try = self.try
+ try(self.tp:command("quit"))
+ try(self.tp:check("2.."))
+ return 1
+end
+
+function methods.close(self)
+ local data = self.data
+ if data then
+ data:close()
+ end
+ local server = self.server
+ if server then
+ server:close()
+ end
+ local tp = self.tp
+ if tp then
+ tp:close()
+ end
+end
+
+local function override(t)
+ if t.url then
+ local u = parseurl(t.url)
+ for k, v in next, t do
+ u[k] = v
+ end
+ return u
+ else
+ return t
+ end
+end
+
+local function tput(putt)
+ putt = override(putt)
+ local host = putt.host
+ trysocket(host, "missing hostname")
+ local f = ftp.open(host, putt.port, putt.create)
+ f:greet()
+ f:login(putt.user, putt.password)
+ local typ = putt.type
+ if typ then
+ f:type(typ)
+ end
+ f:epsv()
+ local sent = f:send(putt)
+ f:quit()
+ f:close()
+ return sent
+end
+
+local default = {
+ path = "/",
+ scheme = "ftp",
+}
+
+local function genericform(u)
+ local t = trysocket(parseurl(u, default))
+ trysocket(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
+ trysocket(t.host, "missing hostname")
+ local pat = "^type=(.)$"
+ if t.params then
+ local typ = skipsocket(2, find(t.params, pat))
+ t.type = typ
+ trysocket(typ == "a" or typ == "i", "invalid type '" .. typ .. "'")
+ end
+ return t
+end
+
+ftp.genericform = genericform
+
+local function sput(u, body)
+ local putt = genericform(u)
+ putt.source = sourcestring(body)
+ return tput(putt)
+end
+
+ftp.put = protectsocket(function(putt, body)
+ if type(putt) == "string" then
+ return sput(putt, body)
+ else
+ return tput(putt)
+ end
+end)
+
+local function tget(gett)
+ gett = override(gett)
+ local host = gett.host
+ trysocket(host, "missing hostname")
+ local f = ftp.open(host, gett.port, gett.create)
+ f:greet()
+ f:login(gett.user, gett.password)
+ if gett.type then
+ f:type(gett.type)
+ end
+ f:epsv()
+ f:receive(gett)
+ f:quit()
+ return f:close()
+end
+
+local function sget(u)
+ local gett = genericform(u)
+ local t = { }
+ gett.sink = sinktable(t)
+ tget(gett)
+ return concat(t)
+end
+
+ftp.command = protectsocket(function(cmdt)
+ cmdt = override(cmdt)
+ local command = cmdt.command
+ local argument = cmdt.argument
+ local check = cmdt.check
+ local host = cmdt.host
+ trysocket(host, "missing hostname")
+ trysocket(command, "missing command")
+ local f = ftp.open(host, cmdt.port, cmdt.create)
+ local try = f.try
+ local tp = f.tp
+ f:greet()
+ f:login(cmdt.user, cmdt.password)
+ if type(command) == "table" then
+ local argument = argument or { }
+ for i=1,#command do
+ local cmd = command[i]
+ try(tp:command(cmd, argument[i]))
+ if check and check[i] then
+ try(tp:check(check[i]))
+ end
+ end
+ else
+ try(tp:command(command, argument))
+ if check then
+ try(tp:check(check))
+ end
+ end
+ f:quit()
+ return f:close()
+end)
+
+ftp.get = protectsocket(function(gett)
+ if type(gett) == "string" then
+ return sget(gett)
+ else
+ return tget(gett)
+ end
+end)
+
+package.loaded["socket.ftp"] = ftp
+
+return ftp
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-headers.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-headers.lua
new file mode 100644
index 00000000000..ef51910a5f3
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-headers.lua
@@ -0,0 +1,145 @@
+-- original file : headers.lua
+-- for more into : see util-soc.lua
+
+local next = next
+local lower = string.lower
+local concat = table.concat
+
+local socket = socket or require("socket")
+
+local headers = { }
+socket.headers = headers
+
+local canonic = {
+ ["accept"] = "Accept",
+ ["accept-charset"] = "Accept-Charset",
+ ["accept-encoding"] = "Accept-Encoding",
+ ["accept-language"] = "Accept-Language",
+ ["accept-ranges"] = "Accept-Ranges",
+ ["action"] = "Action",
+ ["alternate-recipient"] = "Alternate-Recipient",
+ ["age"] = "Age",
+ ["allow"] = "Allow",
+ ["arrival-date"] = "Arrival-Date",
+ ["authorization"] = "Authorization",
+ ["bcc"] = "Bcc",
+ ["cache-control"] = "Cache-Control",
+ ["cc"] = "Cc",
+ ["comments"] = "Comments",
+ ["connection"] = "Connection",
+ ["content-description"] = "Content-Description",
+ ["content-disposition"] = "Content-Disposition",
+ ["content-encoding"] = "Content-Encoding",
+ ["content-id"] = "Content-ID",
+ ["content-language"] = "Content-Language",
+ ["content-length"] = "Content-Length",
+ ["content-location"] = "Content-Location",
+ ["content-md5"] = "Content-MD5",
+ ["content-range"] = "Content-Range",
+ ["content-transfer-encoding"] = "Content-Transfer-Encoding",
+ ["content-type"] = "Content-Type",
+ ["cookie"] = "Cookie",
+ ["date"] = "Date",
+ ["diagnostic-code"] = "Diagnostic-Code",
+ ["dsn-gateway"] = "DSN-Gateway",
+ ["etag"] = "ETag",
+ ["expect"] = "Expect",
+ ["expires"] = "Expires",
+ ["final-log-id"] = "Final-Log-ID",
+ ["final-recipient"] = "Final-Recipient",
+ ["from"] = "From",
+ ["host"] = "Host",
+ ["if-match"] = "If-Match",
+ ["if-modified-since"] = "If-Modified-Since",
+ ["if-none-match"] = "If-None-Match",
+ ["if-range"] = "If-Range",
+ ["if-unmodified-since"] = "If-Unmodified-Since",
+ ["in-reply-to"] = "In-Reply-To",
+ ["keywords"] = "Keywords",
+ ["last-attempt-date"] = "Last-Attempt-Date",
+ ["last-modified"] = "Last-Modified",
+ ["location"] = "Location",
+ ["max-forwards"] = "Max-Forwards",
+ ["message-id"] = "Message-ID",
+ ["mime-version"] = "MIME-Version",
+ ["original-envelope-id"] = "Original-Envelope-ID",
+ ["original-recipient"] = "Original-Recipient",
+ ["pragma"] = "Pragma",
+ ["proxy-authenticate"] = "Proxy-Authenticate",
+ ["proxy-authorization"] = "Proxy-Authorization",
+ ["range"] = "Range",
+ ["received"] = "Received",
+ ["received-from-mta"] = "Received-From-MTA",
+ ["references"] = "References",
+ ["referer"] = "Referer",
+ ["remote-mta"] = "Remote-MTA",
+ ["reply-to"] = "Reply-To",
+ ["reporting-mta"] = "Reporting-MTA",
+ ["resent-bcc"] = "Resent-Bcc",
+ ["resent-cc"] = "Resent-Cc",
+ ["resent-date"] = "Resent-Date",
+ ["resent-from"] = "Resent-From",
+ ["resent-message-id"] = "Resent-Message-ID",
+ ["resent-reply-to"] = "Resent-Reply-To",
+ ["resent-sender"] = "Resent-Sender",
+ ["resent-to"] = "Resent-To",
+ ["retry-after"] = "Retry-After",
+ ["return-path"] = "Return-Path",
+ ["sender"] = "Sender",
+ ["server"] = "Server",
+ ["smtp-remote-recipient"] = "SMTP-Remote-Recipient",
+ ["status"] = "Status",
+ ["subject"] = "Subject",
+ ["te"] = "TE",
+ ["to"] = "To",
+ ["trailer"] = "Trailer",
+ ["transfer-encoding"] = "Transfer-Encoding",
+ ["upgrade"] = "Upgrade",
+ ["user-agent"] = "User-Agent",
+ ["vary"] = "Vary",
+ ["via"] = "Via",
+ ["warning"] = "Warning",
+ ["will-retry-until"] = "Will-Retry-Until",
+ ["www-authenticate"] = "WWW-Authenticate",
+ ["x-mailer"] = "X-Mailer",
+}
+
+headers.canonic = setmetatable(canonic, {
+ __index = function(t,k)
+ socket.report("invalid header: %s",k)
+ t[k] = k
+ return k
+ end
+})
+
+function headers.normalize(headers)
+ if not headers then
+ return { }
+ end
+ local normalized = { }
+ for k, v in next, headers do
+ normalized[#normalized+1] = canonic[k] .. ": " .. v
+ end
+ normalized[#normalized+1] = ""
+ normalized[#normalized+1] = ""
+ return concat(normalized,"\r\n")
+end
+
+function headers.lower(lowered,headers)
+ if not lowered then
+ return { }
+ end
+ if not headers then
+ lowered, headers = { }, lowered
+ end
+ for k, v in next, headers do
+ lowered[lower(k)] = v
+ end
+ return lowered
+end
+
+socket.headers = headers
+
+package.loaded["socket.headers"] = headers
+
+return headers
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-http.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-http.lua
new file mode 100644
index 00000000000..c3a28be822a
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-http.lua
@@ -0,0 +1,436 @@
+-- original file : http.lua
+-- for more into : see util-soc.lua
+
+local tostring, tonumber, setmetatable, next, type = tostring, tonumber, setmetatable, next, type
+local find, lower, format, gsub, match = string.find, string.lower, string.format, string.gsub, string.match
+local concat = table.concat
+
+local socket = socket or require("socket")
+local url = socket.url or require("socket.url")
+local ltn12 = ltn12 or require("ltn12")
+local mime = mime or require("mime")
+local headers = socket.headers or require("socket.headers")
+
+local normalizeheaders = headers.normalize
+
+local parseurl = url.parse
+local buildurl = url.build
+local absoluteurl = url.absolute
+local unescapeurl = url.unescape
+
+local skipsocket = socket.skip
+local sinksocket = socket.sink
+local sourcesocket = socket.source
+local trysocket = socket.try
+local tcpsocket = socket.tcp
+local newtrysocket = socket.newtry
+local protectsocket = socket.protect
+
+local emptysource = ltn12.source.empty
+local stringsource = ltn12.source.string
+local rewindsource = ltn12.source.rewind
+local pumpstep = ltn12.pump.step
+local pumpall = ltn12.pump.all
+local sinknull = ltn12.sink.null
+local sinktable = ltn12.sink.table
+
+local lowerheaders = headers.lower
+
+local mimeb64 = mime.b64
+
+-- todo: localize ltn12
+
+local http = {
+ TIMEOUT = 60, -- connection timeout in seconds
+ USERAGENT = socket._VERSION, -- user agent field sent in request
+}
+
+socket.http = http
+
+local PORT = 80
+local SCHEMES = {
+ http = true,
+}
+
+-- Reads MIME headers from a connection, unfolding where needed
+
+local function receiveheaders(sock, headers)
+ if not headers then
+ headers = { }
+ end
+ -- get first line
+ local line, err = sock:receive()
+ if err then
+ return nil, err
+ end
+ -- headers go until a blank line is found
+ while line ~= "" do
+ -- get field-name and value
+ local name, value = skipsocket(2, find(line, "^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil, "malformed reponse headers"
+ end
+ name = lower(name)
+ -- get next line (value might be folded)
+ line, err = sock:receive()
+ if err then
+ return nil, err
+ end
+ -- unfold any folded values
+ while find(line, "^%s") do
+ value = value .. line
+ line = sock:receive()
+ if err then
+ return nil, err
+ end
+ end
+ -- save pair in table
+ local found = headers[name]
+ if found then
+ value = found .. ", " .. value
+ end
+ headers[name] = value
+ end
+ return headers
+end
+
+-- Extra sources and sinks
+
+socket.sourcet["http-chunked"] = function(sock, headers)
+ return setmetatable (
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ }, {
+ __call = function()
+ local line, err = sock:receive()
+ if err then
+ return nil, err
+ end
+ local size = tonumber(gsub(line, ";.*", ""), 16)
+ if not size then
+ return nil, "invalid chunk size"
+ end
+ if size > 0 then
+ local chunk, err, part = sock:receive(size)
+ if chunk then
+ sock:receive()
+ end
+ return chunk, err
+ else
+ headers, err = receiveheaders(sock, headers)
+ if not headers then
+ return nil, err
+ end
+ end
+ end
+ }
+ )
+end
+
+socket.sinkt["http-chunked"] = function(sock)
+ return setmetatable(
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ },
+ {
+ __call = function(self, chunk, err)
+ if not chunk then
+ chunk = ""
+ end
+ return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
+ end
+ })
+end
+
+-- Low level HTTP API
+
+local methods = { }
+local mt = { __index = methods }
+
+local function openhttp(host, port, create)
+ local c = trysocket((create or tcpsocket)())
+ local h = setmetatable({ c = c }, mt)
+ local try = newtrysocket(function() h:close() end)
+ h.try = try
+ try(c:settimeout(http.TIMEOUT))
+ try(c:connect(host, port or PORT))
+ return h
+end
+
+http.open = openhttp
+
+function methods.sendrequestline(self, method, uri)
+ local requestline = format("%s %s HTTP/1.1\r\n", method or "GET", uri)
+ return self.try(self.c:send(requestline))
+end
+
+function methods.sendheaders(self,headers)
+ self.try(self.c:send(normalizeheaders(headers)))
+ return 1
+end
+
+function methods.sendbody(self, headers, source, step)
+ if not source then
+ source = emptysource()
+ end
+ if not step then
+ step = pumpstep
+ end
+ local mode = "http-chunked"
+ if headers["content-length"] then
+ mode = "keep-open"
+ end
+ return self.try(pumpall(source, sinksocket(mode, self.c), step))
+end
+
+function methods.receivestatusline(self)
+ local try = self.try
+ local status = try(self.c:receive(5))
+ if status ~= "HTTP/" then
+ return nil, status -- HTTP/0.9
+ end
+ status = try(self.c:receive("*l", status))
+ local code = skipsocket(2, find(status, "HTTP/%d*%.%d* (%d%d%d)"))
+ return try(tonumber(code), status)
+end
+
+function methods.receiveheaders(self)
+ return self.try(receiveheaders(self.c))
+end
+
+function methods.receivebody(self, headers, sink, step)
+ if not sink then
+ sink = sinknull()
+ end
+ if not step then
+ step = pumpstep
+ end
+ local length = tonumber(headers["content-length"])
+ local encoding = headers["transfer-encoding"] -- shortcut
+ local mode = "default" -- connection close
+ if encoding and encoding ~= "identity" then
+ mode = "http-chunked"
+ elseif length then
+ mode = "by-length"
+ end
+ --hh: so length can be nil
+ return self.try(pumpall(sourcesocket(mode, self.c, length), sink, step))
+end
+
+function methods.receive09body(self, status, sink, step)
+ local source = rewindsource(sourcesocket("until-closed", self.c))
+ source(status)
+ return self.try(pumpall(source, sink, step))
+end
+
+function methods.close(self)
+ return self.c:close()
+end
+
+-- High level HTTP API
+
+local function adjusturi(request)
+ if not request.proxy and not http.PROXY then
+ request = {
+ path = trysocket(request.path, "invalid path 'nil'"),
+ params = request.params,
+ query = request.query,
+ fragment = request.fragment,
+ }
+ end
+ return buildurl(request)
+end
+
+local function adjustheaders(request)
+ local headers = {
+ ["user-agent"] = http.USERAGENT,
+ ["host"] = gsub(request.authority, "^.-@", ""),
+ ["connection"] = "close, TE",
+ ["te"] = "trailers"
+ }
+ local username = request.user
+ local password = request.password
+ if username and password then
+ headers["authorization"] = "Basic " .. (mimeb64(username .. ":" .. unescapeurl(password)))
+ end
+ local proxy = request.proxy or http.PROXY
+ if proxy then
+ proxy = parseurl(proxy)
+ local username = proxy.user
+ local password = proxy.password
+ if username and password then
+ headers["proxy-authorization"] = "Basic " .. (mimeb64(username .. ":" .. password))
+ end
+ end
+ local requestheaders = request.headers
+ if requestheaders then
+ headers = lowerheaders(headers,requestheaders)
+ end
+ return headers
+end
+
+-- default url parts
+
+local default = {
+ host = "",
+ port = PORT,
+ path = "/",
+ scheme = "http"
+}
+
+local function adjustrequest(originalrequest)
+ local url = originalrequest.url
+ local request = url and parseurl(url,default) or { }
+ for k, v in next, originalrequest do
+ request[k] = v
+ end
+ local host = request.host
+ local port = request.port
+ local uri = request.uri
+ if not host or host == "" then
+ trysocket(nil, "invalid host '" .. tostring(host) .. "'")
+ end
+ if port == "" then
+ request.port = PORT
+ end
+ if not uri or uri == "" then
+ request.uri = adjusturi(request)
+ end
+ request.headers = adjustheaders(request)
+ local proxy = request.proxy or http.PROXY
+ if proxy then
+ proxy = parseurl(proxy)
+ request.host = proxy.host
+ request.port = proxy.port or 3128
+ end
+ return request
+end
+
+local maxredericts = 4
+local validredirects = { [301] = true, [302] = true, [303] = true, [307] = true }
+local validmethods = { [false] = true, GET = true, HEAD = true }
+
+local function shouldredirect(request, code, headers)
+ local location = headers.location
+ if not location then
+ return false
+ end
+ location = gsub(location, "%s", "")
+ if location == "" then
+ return false
+ end
+ local scheme = match(location, "^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then
+ return false
+ end
+ local method = request.method
+ local redirect = request.redirect
+ local redirects = request.nredirects or 0
+ return redirect and validredirects[code] and validmethods[method] and redirects <= maxredericts
+end
+
+local function shouldreceivebody(request, code)
+ if request.method == "HEAD" then
+ return nil
+ end
+ if code == 204 or code == 304 then
+ return nil
+ end
+ if code >= 100 and code < 200 then
+ return nil
+ end
+ return 1
+end
+
+local tredirect, trequest, srequest
+
+tredirect = function(request, location)
+ local result, code, headers, status = trequest {
+ url = absoluteurl(request.url,location),
+ source = request.source,
+ sink = request.sink,
+ headers = request.headers,
+ proxy = request.proxy,
+ nredirects = (request.nredirects or 0) + 1,
+ create = request.create,
+ }
+ if not headers then
+ headers = { }
+ end
+ if not headers.location then
+ headers.location = location
+ end
+ return result, code, headers, status
+end
+
+trequest = function(originalrequest)
+ local request = adjustrequest(originalrequest)
+ local connection = openhttp(request.host, request.port, request.create)
+ local headers = request.headers
+ connection:sendrequestline(request.method, request.uri)
+ connection:sendheaders(headers)
+ if request.source then
+ connection:sendbody(headers, request.source, request.step)
+ end
+ local code, status = connection:receivestatusline()
+ if not code then
+ connection:receive09body(status, request.sink, request.step)
+ return 1, 200
+ end
+ while code == 100 do
+ headers = connection:receiveheaders()
+ code, status = connection:receivestatusline()
+ end
+ headers = connection:receiveheaders()
+ if shouldredirect(request, code, headers) and not request.source then
+ connection:close()
+ return tredirect(originalrequest,headers.location)
+ end
+ if shouldreceivebody(request, code) then
+ connection:receivebody(headers, request.sink, request.step)
+ end
+ connection:close()
+ return 1, code, headers, status
+end
+
+-- turns an url and a body into a generic request
+
+local function genericform(url, body)
+ local buffer = { }
+ local request = {
+ url = url,
+ sink = sinktable(buffer),
+ target = buffer,
+ }
+ if body then
+ request.source = stringsource(body)
+ request.method = "POST"
+ request.headers = {
+ ["content-length"] = #body,
+ ["content-type"] = "application/x-www-form-urlencoded"
+ }
+ end
+ return request
+end
+
+http.genericform = genericform
+
+srequest = function(url, body)
+ local request = genericform(url, body)
+ local _, code, headers, status = trequest(request)
+ return concat(request.target), code, headers, status
+end
+
+http.request = protectsocket(function(request, body)
+ if type(request) == "string" then
+ return srequest(request, body)
+ else
+ return trequest(request)
+ end
+end)
+
+package.loaded["socket.http"] = http
+
+return http
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ltn12.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ltn12.lua
new file mode 100644
index 00000000000..54110ab7a30
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-ltn12.lua
@@ -0,0 +1,387 @@
+-- original file : ltn12.lua
+-- for more into : see util-soc.lua
+
+local select, unpack = select, unpack
+local insert, remove = table.insert, table.remove
+local sub = string.sub
+
+local function report(fmt,first,...)
+ if logs then
+ report = logs and logs.reporter("ltn12")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt = "ltn12: " .. fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
+ end
+ end
+end
+
+local filter = { }
+local source = { }
+local sink = { }
+local pump = { }
+
+local ltn12 = {
+
+ _VERSION = "LTN12 1.0.3",
+
+ BLOCKSIZE = 2048,
+
+ filter = filter,
+ source = source,
+ sink = sink,
+ pump = pump,
+
+ report = report,
+
+}
+
+-- returns a high level filter that cycles a low-level filter
+
+function filter.cycle(low, ctx, extra)
+ if low then
+ return function(chunk)
+ return (low(ctx, chunk, extra))
+ end
+ end
+end
+
+-- chains a bunch of filters together
+
+function filter.chain(...)
+ local arg = { ... }
+ local n = select('#',...)
+ local top = 1
+ local index = 1
+ local retry = ""
+ return function(chunk)
+ retry = chunk and retry
+ while true do
+ local action = arg[index]
+ if index == top then
+ chunk = action(chunk)
+ if chunk == "" or top == n then
+ return chunk
+ elseif chunk then
+ index = index + 1
+ else
+ top = top + 1
+ index = top
+ end
+ else
+ chunk = action(chunk or "")
+ if chunk == "" then
+ index = index - 1
+ chunk = retry
+ elseif chunk then
+ if index == n then
+ return chunk
+ else
+ index = index + 1
+ end
+ else
+ report("error: filter returned inappropriate 'nil'")
+ return
+ end
+ end
+ end
+ end
+end
+
+-- create an empty source
+
+local function empty()
+ return nil
+end
+
+function source.empty()
+ return empty
+end
+
+-- returns a source that just outputs an error
+
+local function sourceerror(err)
+ return function()
+ return nil, err
+ end
+end
+
+source.error = sourceerror
+
+-- creates a file source
+
+function source.file(handle, io_err)
+ if handle then
+ local blocksize = ltn12.BLOCKSIZE
+ return function()
+ local chunk = handle:read(blocksize)
+ if not chunk then
+ handle:close()
+ end
+ return chunk
+ end
+ else
+ return sourceerror(io_err or "unable to open file")
+ end
+end
+
+-- turns a fancy source into a simple source
+
+function source.simplify(src)
+ return function()
+ local chunk, err_or_new = src()
+ if err_or_new then
+ src = err_or_new
+ end
+ if chunk then
+ return chunk
+ else
+ return nil, err_or_new
+ end
+ end
+end
+
+-- creates string source
+
+function source.string(s)
+ if s then
+ local blocksize = ltn12.BLOCKSIZE
+ local i = 1
+ return function()
+ local nexti = i + blocksize
+ local chunk = sub(s, i, nexti - 1)
+ i = nexti
+ if chunk ~= "" then
+ return chunk
+ else
+ return nil
+ end
+ end
+ else return source.empty() end
+end
+
+-- creates rewindable source
+
+function source.rewind(src)
+ local t = { }
+ return function(chunk)
+ if chunk then
+ insert(t, chunk)
+ else
+ chunk = remove(t)
+ if chunk then
+ return chunk
+ else
+ return src()
+ end
+ end
+ end
+end
+
+-- chains a source with one or several filter(s)
+
+function source.chain(src, f, ...)
+ if ... then
+ f = filter.chain(f, ...)
+ end
+ local last_in = ""
+ local last_out = ""
+ local state = "feeding"
+ local err
+ return function()
+ if not last_out then
+ report("error: source is empty")
+ return
+ end
+ while true do
+ if state == "feeding" then
+ last_in, err = src()
+ if err then
+ return nil, err
+ end
+ last_out = f(last_in)
+ if not last_out then
+ if last_in then
+ report("error: filter returned inappropriate 'nil'")
+ end
+ return nil
+ elseif last_out ~= "" then
+ state = "eating"
+ if last_in then
+ last_in = ""
+ end
+ return last_out
+ end
+ else
+ last_out = f(last_in)
+ if last_out == "" then
+ if last_in == "" then
+ state = "feeding"
+ else
+ report("error: filter returned nothing")
+ return
+ end
+ elseif not last_out then
+ if last_in then
+ report("filter returned inappropriate 'nil'")
+ end
+ return nil
+ else
+ return last_out
+ end
+ end
+ end
+ end
+end
+
+-- creates a source that produces contents of several sources, one after the
+-- other, as if they were concatenated
+
+function source.cat(...)
+ local arg = { ... }
+ local src = remove(arg,1)
+ return function()
+ while src do
+ local chunk, err = src()
+ if chunk then
+ return chunk
+ end
+ if err then
+ return nil, err
+ end
+ src = remove(arg,1)
+ end
+ end
+end
+
+-- creates a sink that stores into a table
+
+function sink.table(t)
+ if not t then
+ t = { }
+ end
+ local f = function(chunk, err)
+ if chunk then
+ insert(t, chunk)
+ end
+ return 1
+ end
+ return f, t
+end
+
+-- turns a fancy sink into a simple sink
+
+function sink.simplify(snk)
+ return function(chunk, err)
+ local ret, err_or_new = snk(chunk, err)
+ if not ret then
+ return nil, err_or_new
+ end
+ if err_or_new then
+ snk = err_or_new
+ end
+ return 1
+ end
+end
+
+-- creates a sink that discards data
+
+local function null()
+ return 1
+end
+
+function sink.null()
+ return null
+end
+
+-- creates a sink that just returns an error
+
+local function sinkerror(err)
+ return function()
+ return nil, err
+ end
+end
+
+sink.error = sinkerror
+
+-- creates a file sink
+
+function sink.file(handle, io_err)
+ if handle then
+ return function(chunk, err)
+ if not chunk then
+ handle:close()
+ return 1
+ else
+ return handle:write(chunk)
+ end
+ end
+ else
+ return sinkerror(io_err or "unable to open file")
+ end
+end
+
+-- chains a sink with one or several filter(s)
+
+function sink.chain(f, snk, ...)
+ if ... then
+ local args = { f, snk, ... }
+ snk = remove(args, #args)
+ f = filter.chain(unpack(args))
+ end
+ return function(chunk, err)
+ if chunk ~= "" then
+ local filtered = f(chunk)
+ local done = chunk and ""
+ while true do
+ local ret, snkerr = snk(filtered, err)
+ if not ret then
+ return nil, snkerr
+ end
+ if filtered == done then
+ return 1
+ end
+ filtered = f(done)
+ end
+ else
+ return 1
+ end
+ end
+end
+
+-- pumps one chunk from the source to the sink
+
+function pump.step(src, snk)
+ local chunk, src_err = src()
+ local ret, snk_err = snk(chunk, src_err)
+ if chunk and ret then
+ return 1
+ else
+ return nil, src_err or snk_err
+ end
+end
+
+-- pumps all data from a source to a sink, using a step function
+
+function pump.all(src, snk, step)
+ if not step then
+ step = pump.step
+ end
+ while true do
+ local ret, err = step(src, snk)
+ if not ret then
+ if err then
+ return nil, err
+ else
+ return 1
+ end
+ end
+ end
+end
+
+package.loaded["ltn12"] = ltn12
+
+return ltn12
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-mime.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-mime.lua
new file mode 100644
index 00000000000..4b5d2baff10
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-mime.lua
@@ -0,0 +1,104 @@
+-- original file : mime.lua
+-- for more into : see util-soc.lua
+
+local type, tostring = type, tostring
+
+local mime = require("mime.core")
+local ltn12 = ltn12 or require("ltn12")
+
+local filtercycle = ltn12.filter.cycle
+
+local function report(fmt,first,...)
+ if logs then
+ report = logs and logs.reporter("mime")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt = "mime: " .. fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
+ end
+ end
+end
+
+mime.report = report
+
+local encodet = { }
+local decodet = { }
+local wrapt = { }
+
+mime.encodet = encodet
+mime.decodet = decodet
+mime.wrapt = wrapt
+
+local mime_b64 = mime.b64
+local mime_qp = mime.qp
+local mime_unb64 = mime.unb64
+local mime_unqp = mime.unqp
+local mime_wrp = mime.wrp
+local mime_qpwrp = mime.qpwrp
+local mime_eol = mime_eol
+local mime_dot = mime_dot
+
+encodet['base64'] = function()
+ return filtercycle(mime_b64,"")
+end
+
+encodet['quoted-printable'] = function(mode)
+ return filtercycle(mime_qp, "", mode == "binary" and "=0D=0A" or "\r\n")
+end
+
+decodet['base64'] = function()
+ return filtercycle(mime_unb64, "")
+end
+
+decodet['quoted-printable'] = function()
+ return filtercycle(mime_unqp, "")
+end
+
+local wraptext = function(length)
+ if not length then
+ length = 76
+ end
+ return filtercycle(mime_wrp, length, length)
+end
+
+local wrapquoted = function()
+ return filtercycle(mime_qpwrp, 76, 76)
+end
+
+wrapt['text'] = wraptext
+wrapt['base64'] = wraptext
+wrapt['default'] = wraptext
+wrapt['quoted-printable'] = wrapquoted
+
+function mime.normalize(marker)
+ return filtercycle(mime_eol, 0, marker)
+end
+
+function mime.stuff()
+ return filtercycle(mime_dot, 2)
+end
+
+local function choose(list)
+ return function(name, opt1, opt2)
+ if type(name) ~= "string" then
+ name, opt1, opt2 = "default", name, opt1
+ end
+ local filter = list[name or "nil"]
+ if filter then
+ return filter(opt1, opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
+ end
+ end
+end
+
+mime.encode = choose(encodet)
+mime.decode = choose(decodet)
+mime.wrap = choose(wrapt)
+
+package.loaded["mime"] = mime
+
+return mime
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-reset.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-reset.lua
new file mode 100644
index 00000000000..a4a489b0f90
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-reset.lua
@@ -0,0 +1,13 @@
+local loaded = package.loaded
+
+loaded["socket"] = nil
+loaded["copas"] = nil
+loaded["ltn12"] = nil
+loaded["mbox"] = nil
+loaded["mime"] = nil
+loaded["socket.url"] = nil
+loaded["socket.headers"] = nil
+loaded["socket.tp"] = nil
+loaded["socket.http"] = nil
+loaded["socket.ftp"] = nil
+loaded["socket.smtp"] = nil
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-smtp.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-smtp.lua
new file mode 100644
index 00000000000..621d1b6e39e
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-smtp.lua
@@ -0,0 +1,267 @@
+-- original file : smtp.lua
+-- for more into : see util-soc.lua
+
+local type, setmetatable, next = type, setmetatable, next
+local find, lower, format = string.find, string.lower, string.format
+local osdate, osgetenv = os.date, os.getenv
+local random = math.random
+
+local socket = socket or require("socket")
+local headers = socket.headers or require("socket.headers")
+local ltn12 = ltn12 or require("ltn12")
+local tp = socket.tp or require("socket.tp")
+local mime = mime or require("mime")
+
+local mimeb64 = mime.b64
+local mimestuff = mime.stuff
+
+local skipsocket = socket.skip
+local trysocket = socket.try
+local newtrysocket = socket.newtry
+local protectsocket = socket.protect
+
+local normalizeheaders = headers.normalize
+local lowerheaders = headers.lower
+
+local createcoroutine = coroutine.create
+local resumecoroutine = coroutine.resume
+local yieldcoroutine = coroutine.resume
+
+local smtp = {
+ TIMEOUT = 60,
+ SERVER = "localhost",
+ PORT = 25,
+ DOMAIN = osgetenv("SERVER_NAME") or "localhost",
+ ZONE = "-0000",
+}
+
+socket.smtp = smtp
+
+local methods = { }
+local mt = { __index = methods }
+
+function methods.greet(self, domain)
+ local try = self.try
+ local tp = self.tp
+ try(tp:check("2.."))
+ try(tp:command("EHLO", domain or _M.DOMAIN))
+ return skipsocket(1, try(tp:check("2..")))
+end
+
+function methods.mail(self, from)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("MAIL", "FROM:" .. from))
+ return try(tp:check("2.."))
+end
+
+function methods.rcpt(self, to)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("RCPT", "TO:" .. to))
+ return try(tp:check("2.."))
+end
+
+function methods.data(self, src, step)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("DATA"))
+ try(tp:check("3.."))
+ try(tp:source(src, step))
+ try(tp:send("\r\n.\r\n"))
+ return try(tp:check("2.."))
+end
+
+function methods.quit(self)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("QUIT"))
+ return try(tp:check("2.."))
+end
+
+function methods.close(self)
+ return self.tp:close()
+end
+
+function methods.login(self, user, password)
+ local try = self.try
+ local tp = self.tp
+ try(tp:command("AUTH", "LOGIN"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(user) .. "\r\n"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(password) .. "\r\n"))
+ return try(tp:check("2.."))
+end
+
+function methods.plain(self, user, password)
+ local try = self.try
+ local tp = self.tp
+ local auth = "PLAIN " .. mimeb64("\0" .. user .. "\0" .. password)
+ try(tp:command("AUTH", auth))
+ return try(tp:check("2.."))
+end
+
+function methods.auth(self, user, password, ext)
+ if not user or not password then
+ return 1
+ end
+ local try = self.try
+ if find(ext, "AUTH[^\n]+LOGIN") then
+ return self:login(user,password)
+ elseif find(ext, "AUTH[^\n]+PLAIN") then
+ return self:plain(user,password)
+ else
+ try(nil, "authentication not supported")
+ end
+end
+
+function methods.send(self, mail)
+ self:mail(mail.from)
+ local receipt = mail.rcpt
+ if type(receipt) == "table" then
+ for i=1,#receipt do
+ self:rcpt(receipt[i])
+ end
+ elseif receipt then
+ self:rcpt(receipt)
+ end
+ self:data(ltn12.source.chain(mail.source, mimestuff()), mail.step)
+end
+
+local function opensmtp(self, server, port, create)
+ if not server or server == "" then
+ server = smtp.SERVER
+ end
+ if not port or port == "" then
+ port = smtp.PORT
+ end
+ local s = {
+ tp = trysocket(tp.connect(server, port, smtp.TIMEOUT, create)),
+ try = newtrysocket(function()
+ s:close()
+ end),
+ }
+ setmetatable(s, mt)
+ return s
+end
+
+smtp.open = opensmtp
+
+local nofboundaries = 0
+
+local function newboundary()
+ nofboundaries = nofboundaries + 1
+ return format('%s%05d==%05u', osdate('%d%m%Y%H%M%S'), random(0,99999), nofboundaries)
+end
+
+local send_message
+
+local function send_headers(headers)
+ yieldcoroutine(normalizeheaders(headers))
+end
+
+local function send_multipart(message)
+ local boundary = newboundary()
+ local headers = lowerheaders(message.headers)
+ local body = message.body
+ local preamble = body.preamble
+ local epilogue = body.epilogue
+ local content = headers['content-type'] or 'multipart/mixed'
+ headers['content-type'] = content .. '; boundary="' .. boundary .. '"'
+ send_headers(headers)
+ if preamble then
+ yieldcoroutine(preamble)
+ yieldcoroutine("\r\n")
+ end
+ for i=1,#body do
+ yieldcoroutine("\r\n--" .. boundary .. "\r\n")
+ send_message(body[i])
+ end
+ yieldcoroutine("\r\n--" .. boundary .. "--\r\n\r\n")
+ if epilogue then
+ yieldcoroutine(epilogue)
+ yieldcoroutine("\r\n")
+ end
+end
+
+local default_content_type = 'text/plain; charset="UTF-8"'
+
+local function send_source(message)
+ local headers = lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type'] = default_content_type
+ end
+ send_headers(headers)
+ local getchunk = message.body
+ while true do
+ local chunk, err = getchunk()
+ if err then
+ yieldcoroutine(nil, err)
+ elseif chunk then
+ yieldcoroutine(chunk)
+ else
+ break
+ end
+ end
+end
+
+local function send_string(message)
+ local headers = lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type'] = default_content_type
+ end
+ send_headers(headers)
+ yieldcoroutine(message.body)
+end
+
+function send_message(message)
+ local body = message.body
+ if type(body) == "table" then
+ send_multipart(message)
+ elseif type(body) == "function" then
+ send_source(message)
+ else
+ send_string(message)
+ end
+end
+
+local function adjust_headers(message)
+ local headers = lowerheaders(message.headers)
+ if not headers["date"] then
+ headers["date"] = osdate("!%a, %d %b %Y %H:%M:%S ") .. (message.zone or smtp.ZONE)
+ end
+ if not headers["x-mailer"] then
+ headers["x-mailer"] = socket._VERSION
+ end
+ headers["mime-version"] = "1.0"
+ return headers
+end
+
+function smtp.message(message)
+ message.headers = adjust_headers(message)
+ local action = createcoroutine(function()
+ send_message(message)
+ end)
+ return function()
+ local ret, a, b = resumecoroutine(action)
+ if ret then
+ return a, b
+ else
+ return nil, a
+ end
+ end
+end
+
+smtp.send = protectsocket(function(mail)
+ local snd = opensmtp(smtp,mail.server, mail.port, mail.create)
+ local ext = snd:greet(mail.domain)
+ snd:auth(mail.user, mail.password, ext)
+ snd:send(mail)
+ snd:quit()
+ return snd:close()
+end)
+
+package.loaded["socket.smtp"] = smtp
+
+return smtp
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-socket.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-socket.lua
new file mode 100644
index 00000000000..3da155749fd
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-socket.lua
@@ -0,0 +1,193 @@
+-- original file : socket.lua
+-- for more into : see util-soc.lua
+
+local type, tostring, setmetatable = type, tostring, setmetatable
+local min = math.min
+local format = string.format
+
+local socket = require("socket.core")
+
+local connect = socket.connect
+local tcp4 = socket.tcp4
+local tcp6 = socket.tcp6
+local getaddrinfo = socket.dns.getaddrinfo
+
+local defaulthost = "0.0.0.0"
+
+local function report(fmt,first,...)
+ if logs then
+ report = logs and logs.reporter("socket")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt = "socket: " .. fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
+ end
+ end
+end
+
+socket.report = report
+
+function socket.connect4(address, port, laddress, lport)
+ return connect(address, port, laddress, lport, "inet")
+end
+
+function socket.connect6(address, port, laddress, lport)
+ return connect(address, port, laddress, lport, "inet6")
+end
+
+function socket.bind(host, port, backlog)
+ if host == "*" or host == "" then
+ host = defaulthost
+ end
+ local addrinfo, err = getaddrinfo(host)
+ if not addrinfo then
+ return nil, err
+ end
+ for i=1,#addrinfo do
+ local alt = addrinfo[i]
+ local sock, err = (alt.family == "inet" and tcp4 or tcp6)()
+ if not sock then
+ return nil, err or "unknown error"
+ end
+ sock:setoption("reuseaddr", true)
+ local res, err = sock:bind(alt.addr, port)
+ if res then
+ res, err = sock:listen(backlog)
+ if res then
+ return sock
+ else
+ sock:close()
+ end
+ else
+ sock:close()
+ end
+ end
+ return nil, "invalid address"
+end
+
+socket.try = socket.newtry()
+
+function socket.choose(list)
+ return function(name, opt1, opt2)
+ if type(name) ~= "string" then
+ name, opt1, opt2 = "default", name, opt1
+ end
+ local f = list[name or "nil"]
+ if f then
+ return f(opt1, opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
+ end
+ end
+end
+
+local sourcet = { }
+local sinkt = { }
+
+socket.sourcet = sourcet
+socket.sinkt = sinkt
+
+socket.BLOCKSIZE = 2048
+
+sinkt["close-when-done"] = function(sock)
+ return setmetatable (
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ },
+ {
+ __call = function(self, chunk, err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ sock:close()
+ return 1 -- why 1
+ end
+ end
+ }
+ )
+end
+
+sinkt["keep-open"] = function(sock)
+ return setmetatable (
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ }, {
+ __call = function(self, chunk, err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ return 1 -- why 1
+ end
+ end
+ }
+ )
+end
+
+sinkt["default"] = sinkt["keep-open"]
+
+socket.sink = socket.choose(sinkt)
+
+sourcet["by-length"] = function(sock, length)
+ local blocksize = socket.BLOCKSIZE
+ return setmetatable (
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ },
+ {
+ __call = function()
+ if length <= 0 then
+ return nil
+ end
+ local chunk, err = sock:receive(min(blocksize,length))
+ if err then
+ return nil, err
+ end
+ length = length - #chunk
+ return chunk
+ end
+ }
+ )
+end
+
+sourcet["until-closed"] = function(sock)
+ local blocksize = socket.BLOCKSIZE
+ local done = false
+ return setmetatable (
+ {
+ getfd = function() return sock:getfd() end,
+ dirty = function() return sock:dirty() end,
+ }, {
+ __call = function()
+ if done then
+ return nil
+ end
+ local chunk, status, partial = sock:receive(blocksize)
+ if not status then
+ return chunk
+ elseif status == "closed" then
+ sock:close()
+ done = true
+ return partial
+ else
+ return nil, status
+ end
+ end
+ }
+ )
+end
+
+sourcet["default"] = sourcet["until-closed"]
+
+socket.source = socket.choose(sourcet)
+
+_G.socket = socket -- for now global
+
+package.loaded["socket"] = socket
+
+return socket
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-tp.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-tp.lua
new file mode 100644
index 00000000000..e651e44f7fe
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-tp.lua
@@ -0,0 +1,144 @@
+-- original file : tp.lua
+-- for more into : see util-soc.lua
+
+local setmetatable, next, type, tonumber = setmetatable, next, type, tonumber
+local find, upper = string.find, string.upper
+
+local socket = socket or require("socket")
+local ltn12 = ltn12 or require("ltn12")
+
+local skipsocket = socket.skip
+local sinksocket = socket.sink
+local tcpsocket = socket.tcp
+
+local ltn12pump = ltn12.pump
+local pumpall = ltn12pump.all
+local pumpstep = ltn12pump.step
+
+local tp = {
+ TIMEOUT = 60,
+}
+
+socket.tp = tp
+
+local function get_reply(c)
+ local line, err = c:receive()
+ local reply = line
+ if err then return
+ nil, err
+ end
+ local code, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)"))
+ if not code then
+ return nil, "invalid server reply"
+ end
+ if sep == "-" then
+ local current
+ repeat
+ line, err = c:receive()
+ if err then
+ return nil, err
+ end
+ current, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)"))
+ reply = reply .. "\n" .. line
+ until code == current and sep == " "
+ end
+ return code, reply
+end
+
+local methods = { }
+local mt = { __index = methods }
+
+function methods.getpeername(self)
+ return self.c:getpeername()
+end
+
+function methods.getsockname(self)
+ return self.c:getpeername()
+end
+
+function methods.check(self, ok)
+ local code, reply = get_reply(self.c)
+ if not code then
+ return nil, reply
+ end
+ local c = tonumber(code)
+ local t = type(ok)
+ if t == "function" then
+ return ok(c,reply)
+ elseif t == "table" then
+ for i=1,#ok do
+ if find(code,ok[i]) then
+ return c, reply
+ end
+ end
+ return nil, reply
+ elseif find(code, ok) then
+ return c, reply
+ else
+ return nil, reply
+ end
+end
+
+function methods.command(self, cmd, arg)
+ cmd = upper(cmd)
+ if arg then
+ cmd = cmd .. " " .. arg .. "\r\n"
+ else
+ cmd = cmd .. "\r\n"
+ end
+ return self.c:send(cmd)
+end
+
+function methods.sink(self, snk, pat)
+ local chunk, err = self.c:receive(pat)
+ return snk(chunk, err)
+end
+
+function methods.send(self, data)
+ return self.c:send(data)
+end
+
+function methods.receive(self, pat)
+ return self.c:receive(pat)
+end
+
+function methods.getfd(self)
+ return self.c:getfd()
+end
+
+function methods.dirty(self)
+ return self.c:dirty()
+end
+
+function methods.getcontrol(self)
+ return self.c
+end
+
+function methods.source(self, source, step)
+ local sink = sinksocket("keep-open", self.c)
+ local ret, err = pumpall(source, sink, step or pumpstep)
+ return ret, err
+end
+
+function methods.close(self)
+ self.c:close()
+ return 1
+end
+
+function tp.connect(host, port, timeout, create)
+ local c, e = (create or tcpsocket)()
+ if not c then
+ return nil, e
+ end
+ c:settimeout(timeout or tp.TIMEOUT)
+ local r, e = c:connect(host, port)
+ if not r then
+ c:close()
+ return nil, e
+ end
+ return setmetatable({ c = c }, mt)
+end
+
+package.loaded["socket.tp"] = tp
+
+return tp
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-url.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-url.lua
new file mode 100644
index 00000000000..fa472b65041
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-url.lua
@@ -0,0 +1,268 @@
+-- original file : url.lua
+-- for more into : see util-soc.lua
+
+local tonumber, tostring, type = tonumber, tostring, type
+
+local gsub, sub, match, find, format, byte, char = string.gsub, string.sub, string.match, string.find, string.format, string.byte, string.char
+local insert = table.insert
+
+local socket = socket or require("socket")
+
+local url = {
+ _VERSION = "URL 1.0.3",
+}
+
+socket.url = url
+
+function url.escape(s)
+ return (gsub(s, "([^A-Za-z0-9_])", function(c)
+ return format("%%%02x", byte(c))
+ end))
+end
+
+local function make_set(t) -- table.tohash
+ local s = { }
+ for i=1,#t do
+ s[t[i]] = true
+ end
+ return s
+end
+
+local segment_set = make_set {
+ "-", "_", ".", "!", "~", "*", "'", "(",
+ ")", ":", "@", "&", "=", "+", "$", ",",
+}
+
+local function protect_segment(s)
+ return gsub(s, "([^A-Za-z0-9_])", function(c)
+ if segment_set[c] then
+ return c
+ else
+ return format("%%%02X", byte(c))
+ end
+ end)
+end
+
+function url.unescape(s)
+ return (gsub(s, "%%(%x%x)", function(hex)
+ return char(tonumber(hex,16))
+ end))
+end
+
+local function absolute_path(base_path, relative_path)
+ if find(relative_path,"^/") then
+ return relative_path
+ end
+ local path = gsub(base_path, "[^/]*$", "")
+ path = path .. relative_path
+ path = gsub(path, "([^/]*%./)", function (s)
+ if s ~= "./" then
+ return s
+ else
+ return ""
+ end
+ end)
+ path = gsub(path, "/%.$", "/")
+ local reduced
+ while reduced ~= path do
+ reduced = path
+ path = gsub(reduced, "([^/]*/%.%./)", function (s)
+ if s ~= "../../" then
+ return ""
+ else
+ return s
+ end
+ end)
+ end
+ path = gsub(reduced, "([^/]*/%.%.)$", function (s)
+ if s ~= "../.." then
+ return ""
+ else
+ return s
+ end
+ end)
+ return path
+end
+
+function url.parse(url, default)
+ local parsed = { }
+ for k, v in next, default or parsed do
+ parsed[k] = v
+ end
+ if not url or url == "" then
+ return nil, "invalid url"
+ end
+ url = gsub(url, "#(.*)$", function(f)
+ parsed.fragment = f
+ return ""
+ end)
+ url = gsub(url, "^([%w][%w%+%-%.]*)%:", function(s)
+ parsed.scheme = s
+ return ""
+ end)
+ url = gsub(url, "^//([^/]*)", function(n)
+ parsed.authority = n
+ return ""
+ end)
+ url = gsub(url, "%?(.*)", function(q)
+ parsed.query = q
+ return ""
+ end)
+ url = gsub(url, "%;(.*)", function(p)
+ parsed.params = p
+ return ""
+ end)
+ if url ~= "" then
+ parsed.path = url
+ end
+ local authority = parsed.authority
+ if not authority then
+ return parsed
+ end
+ authority = gsub(authority,"^([^@]*)@", function(u)
+ parsed.userinfo = u
+ return ""
+ end)
+ authority = gsub(authority, ":([^:%]]*)$", function(p)
+ parsed.port = p
+ return ""
+ end)
+ if authority ~= "" then
+ parsed.host = match(authority, "^%[(.+)%]$") or authority
+ end
+ local userinfo = parsed.userinfo
+ if not userinfo then
+ return parsed
+ end
+ userinfo = gsub(userinfo, ":([^:]*)$", function(p)
+ parsed.password = p
+ return ""
+ end)
+ parsed.user = userinfo
+ return parsed
+end
+
+function url.build(parsed)
+ local url = parsed.path or ""
+ if parsed.params then
+ url = url .. ";" .. parsed.params
+ end
+ if parsed.query then
+ url = url .. "?" .. parsed.query
+ end
+ local authority = parsed.authority
+ if parsed.host then
+ authority = parsed.host
+ if find(authority, ":") then -- IPv6?
+ authority = "[" .. authority .. "]"
+ end
+ if parsed.port then
+ authority = authority .. ":" .. tostring(parsed.port)
+ end
+ local userinfo = parsed.userinfo
+ if parsed.user then
+ userinfo = parsed.user
+ if parsed.password then
+ userinfo = userinfo .. ":" .. parsed.password
+ end
+ end
+ if userinfo then authority = userinfo .. "@" .. authority end
+ end
+ if authority then
+ url = "//" .. authority .. url
+ end
+ if parsed.scheme then
+ url = parsed.scheme .. ":" .. url
+ end
+ if parsed.fragment then
+ url = url .. "#" .. parsed.fragment
+ end
+ return url
+end
+
+function url.absolute(base_url, relative_url)
+ local base_parsed
+ if type(base_url) == "table" then
+ base_parsed = base_url
+ base_url = url.build(base_parsed)
+ else
+ base_parsed = url.parse(base_url)
+ end
+ local relative_parsed = url.parse(relative_url)
+ if not base_parsed then
+ return relative_url
+ elseif not relative_parsed then
+ return base_url
+ elseif relative_parsed.scheme then
+ return relative_url
+ else
+ relative_parsed.scheme = base_parsed.scheme
+ if not relative_parsed.authority then
+ relative_parsed.authority = base_parsed.authority
+ if not relative_parsed.path then
+ relative_parsed.path = base_parsed.path
+ if not relative_parsed.params then
+ relative_parsed.params = base_parsed.params
+ if not relative_parsed.query then
+ relative_parsed.query = base_parsed.query
+ end
+ end
+ else
+ relative_parsed.path = absolute_path(base_parsed.path or "", relative_parsed.path)
+ end
+ end
+ return url.build(relative_parsed)
+ end
+end
+
+function url.parse_path(path)
+ local parsed = { }
+ path = path or ""
+ gsub(path, "([^/]+)", function (s)
+ insert(parsed, s)
+ end)
+ for i=1,#parsed do
+ parsed[i] = url.unescape(parsed[i])
+ end
+ if sub(path, 1, 1) == "/" then
+ parsed.is_absolute = 1
+ end
+ if sub(path, -1, -1) == "/" then
+ parsed.is_directory = 1
+ end
+ return parsed
+end
+
+function url.build_path(parsed, unsafe)
+ local path = ""
+ local n = #parsed
+ if unsafe then
+ for i = 1, n-1 do
+ path = path .. parsed[i] .. "/"
+ end
+ if n > 0 then
+ path = path .. parsed[n]
+ if parsed.is_directory then
+ path = path .. "/"
+ end
+ end
+ else
+ for i = 1, n-1 do
+ path = path .. protect_segment(parsed[i]) .. "/"
+ end
+ if n > 0 then
+ path = path .. protect_segment(parsed[n])
+ if parsed.is_directory then
+ path = path .. "/"
+ end
+ end
+ end
+ if parsed.is_absolute then
+ path = "/" .. path
+ end
+ return path
+end
+
+package.loaded["socket.url"] = url
+
+return url
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-soc.lua b/Master/texmf-dist/tex/context/base/mkiv/util-soc.lua
index 3a52ee86de3..590287a25b1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-soc.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-soc.lua
@@ -6,6 +6,29 @@ if not modules then modules = { } end modules ['util-soc'] = {
license = "see context related readme files"
}
+--[[--
+
+In LuaTeX we provide the socket library that is more or less the standard one for
+Lua. It has been around for a while and seems to be pretty stable. The binary
+module is copmpiled into LuaTeX and the accompanying .lua files are preloaded.
+These files are mostly written by Diego Nehab, Andre Carregal, Javier Guerra, and
+Fabio Mascarenhas with contributions from Diego Nehab, Mike Pall, David Burgess,
+Leonardo Godinho, Thomas Harning Jr., and Gary NG. The originals are part of and
+copyrighted by the Kepler project.
+
+Here we reload a slightly reworked version of these .lua files. We keep the same
+(documented) interface but streamlined some fo the code. No more modules, no more
+pre 5.2 Lua, etc. Also, as it loads into the ConTeXt ecosystem, we plug in some
+logging. (and maybe tracing in the future). As we don't support serial ports in
+LuaTeX, related code has been dropped.
+
+The files are reformatted so that we can more easilly add additional features
+and/or tracing options. Any error introduced there is our fault! The url module
+might be replaced by the one in ConTeXt. When we need mbox a suitable variant
+will be provided.
+
+--]]--
+
local format = string.format
local smtp = require("socket.smtp")
@@ -95,3 +118,12 @@ function mail.send(specification)
return true
end
end
+
+-- for now we have this here:
+
+if socket then
+
+ math.initialseed = tonumber(string.sub(string.reverse(tostring(math.ceil(socket.gettime()*10000))),1,6))
+ math.randomseed(math.initialseed)
+
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-ffi.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-ffi.lua
index 2a2bc656934..3731933f1e1 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-ffi.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-ffi.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['util-sql-imp-ffi'] = {
-- I looked at luajit-mysql to see how the ffi mapping was done but it didn't work
-- out that well (at least not on windows) but I got the picture. As I have somewhat
--- different demands I simplified / redid the ffi bti and just took the swiglib
+-- different demands I simplified / redid the ffi bit and just took the swiglib
-- variant and adapted that.
local tonumber = tonumber
@@ -17,6 +17,7 @@ local format, byte = string.format, string.byte
local lpegmatch = lpeg.match
local setmetatable, type = setmetatable, type
local sleep = os.sleep
+local formatters = string.formatters
local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end)
local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end)
@@ -33,6 +34,9 @@ ffi.cdef [[
a query. The rest is handled already in the Lua code elsewhere.
*/
+ void free(void*ptr);
+ void * malloc(size_t size);
+
typedef void MYSQL_instance;
typedef void MYSQL_result;
typedef char **MYSQL_row;
@@ -115,6 +119,14 @@ ffi.cdef [[
MYSQL_result *result
);
+ unsigned int mysql_affected_rows (
+ MYSQL_instance *mysql
+ );
+
+ unsigned int mysql_field_count (
+ MYSQL_instance *mysql
+ );
+
unsigned int mysql_num_fields (
MYSQL_result *res
);
@@ -163,12 +175,14 @@ local dataprepared = helpers.preparetemplate
local serialize = sql.serialize
local deserialize = sql.deserialize
-local mysql_initialize = mysql.mysql_init
+local mysql_open_session = mysql.mysql_init
local mysql_open_connection = mysql.mysql_real_connect
local mysql_execute_query = mysql.mysql_real_query
local mysql_close_connection = mysql.mysql_close
+local mysql_affected_rows = mysql.mysql_affected_rows
+local mysql_field_count = mysql.mysql_field_count
local mysql_field_seek = mysql.mysql_field_seek
local mysql_num_fields = mysql.mysql_num_fields
local mysql_fetch_fields = mysql.mysql_fetch_fields
@@ -180,6 +194,7 @@ local mysql_init = mysql.mysql_init
local mysql_store_result = mysql.mysql_store_result
local mysql_free_result = mysql.mysql_free_result
+local mysql_error_number = mysql.mysql_errno
local mysql_error_message = mysql.mysql_error
local NULL = ffi.cast("MYSQL_result *",0)
@@ -187,325 +202,361 @@ local NULL = ffi.cast("MYSQL_result *",0)
local ffi_tostring = ffi.string
local ffi_gc = ffi.gc
------ mysqldata = ffi.cast("MYSQL_instance*",mysql.malloc(1024*1024))
-local instance = mysql.mysql_init(nil) -- (mysqldata)
+local instance = mysql.mysql_init(nil)
local mysql_constant_false = false
local mysql_constant_true = true
-local function finish(t)
- local r = t._result_
- if r then
- ffi_gc(r,mysql_free_result)
+local wrapresult do
+
+ local function collect(t)
+ local result = t._result_
+ if result then
+ ffi_gc(result,mysql_free_result)
+ end
end
-end
-local function getcolnames(t)
- return t.names
-end
+ local function finish(t)
+ local result = t._result_
+ if result then
+ t._result_ = nil
+ ffi_gc(result,mysql_free_result)
+ end
+ end
-local function getcoltypes(t)
- return t.types
-end
+ local function getcoldata(t)
+ local result = t._result_
+ local nofrows = t.nofrows
+ local noffields = t.noffields
+ local names = { }
+ local types = { }
+ local fields = mysql_fetch_fields(result)
+ for i=1,noffields do
+ local field = fields[i-1]
+ names[i] = ffi_tostring(field.name)
+ types[i] = tonumber(field.type) -- todo
+ end
+ t.names = names
+ t.types = types
+ end
-local function numrows(t)
- return tonumber(t.nofrows)
-end
+ local function getcolnames(t)
+ local names = t.names
+ if names then
+ return names
+ end
+ getcoldata(t)
+ return t.names
+ end
-local function list(t)
- local result = t._result_
- if result then
- local row = mysql_fetch_row(result)
- -- local len = mysql_fetch_lengths(result)
- local result = { }
- for i=1,t.noffields do
- result[i] = ffi_tostring(row[i-1])
+ local function getcoltypes(t)
+ local types = t.types
+ if types then
+ return types
end
- return result
+ getcoldata(t)
+ return t.types
end
-end
-local function hash(t)
- local result = t._result_
- local fields = t.names
- if result then
- local row = mysql_fetch_row(result)
- -- local len = mysql_fetch_lengths(result)
- local result = { }
- for i=1,t.noffields do
- result[fields[i]] = ffi_tostring(row[i-1])
+ local function numrows(t)
+ return t.nofrows
+ end
+
+ -- local function fetch(t)
+ -- local
+ -- local row = mysql_fetch_row(result)
+ -- local result = { }
+ -- for i=1,t.noffields do
+ -- result[i] = ffi_tostring(row[i-1])
+ -- end
+ -- return unpack(result)
+ -- end
+
+ local mt = {
+ __gc = collect,
+ __index = {
+ _result_ = nil,
+ close = finish,
+ numrows = numrows,
+ getcolnames = getcolnames,
+ getcoltypes = getcoltypes,
+ -- fetch = fetch, -- not efficient
+ }
+ }
+
+ wrapresult = function(connection)
+ local result = mysql_store_result(connection)
+ if result ~= NULL then
+ mysql_field_seek(result,0)
+ local t = {
+ _result_ = result,
+ nofrows = tonumber(mysql_num_rows (result) or 0) or 0,
+ noffields = tonumber(mysql_num_fields(result) or 0) or 0,
+ }
+ return setmetatable(t,mt)
+ elseif tonumber(mysql_field_count(connection) or 0) or 0 > 0 then
+ return tonumber(mysql_affected_rows(connection))
end
- return result
end
-end
-local function wholelist(t)
- return fetch_all_rows(t._result_)
end
-local mt = { __index = {
- -- regular
- finish = finish,
- list = list,
- hash = hash,
- wholelist = wholelist,
- -- compatibility
- numrows = numrows,
- getcolnames = getcolnames,
- getcoltypes = getcoltypes,
- -- fallback
- _result_ = nil,
- names = { },
- types = { },
- noffields = 0,
- nofrows = 0,
- }
-}
+local initializesession do
-local nt = setmetatable({},mt)
+ -- timeouts = [ connect_timeout |wait_timeout | interactive_timeout ]
--- session
+ local timeout -- = 3600 -- to be tested
-local function close(t)
- mysql_close_connection(t._connection_)
-end
+ -- connection
-local function execute(t,query)
- if query and query ~= "" then
- local connection = t._connection_
- local result = mysql_execute_query(connection,query,#query)
- if result == 0 then
- local result = mysql_store_result(connection)
- if result ~= NULL then
- mysql_field_seek(result,0)
- local nofrows = tonumber(mysql_num_rows(result) or 0)
- local noffields = tonumber(mysql_num_fields(result))
- local names = { }
- local types = { }
- local fields = mysql_fetch_fields(result)
- for i=1,noffields do
- local field = fields[i-1]
- names[i] = ffi_tostring(field.name)
- types[i] = tonumber(field.type) -- todo
- end
- local t = {
- _result_ = result,
- names = names,
- types = types,
- noffields = noffields,
- nofrows = nofrows,
- }
- return setmetatable(t,mt)
+ local function close(t)
+ -- just a struct ?
+ end
+
+ local function execute(t,query)
+ if query and query ~= "" then
+ local connection = t._connection_
+ local result = mysql_execute_query(connection,query,#query)
+ if result == 0 then
+ return wrapresult(connection)
else
- return nt
+ -- mysql_error_number(connection)
+ return false, ffi_tostring(mysql_error_message(connection))
end
end
+ return false
end
- return false
-end
-local mt = { __index = {
- close = close,
- execute = execute,
+ local mt = {
+ __index = {
+ close = close,
+ execute = execute,
+ }
}
-}
-local function open(t,database,username,password,host,port)
- local connection = mysql_open_connection(
- t._session_,
- host or "localhost",
- username or "",
- password or "",
- database or "",
- port or 0,
- NULL,
- 0
- )
- if connection ~= NULL then
- local t = {
- _connection_ = connection,
- }
- return setmetatable(t,mt)
+ -- session
+
+ local function open(t,database,username,password,host,port)
+ local connection = mysql_open_connection(
+ t._session_,
+ host or "localhost",
+ username or "",
+ password or "",
+ database or "",
+ port or 0,
+ NULL,
+ 0
+ )
+ if connection ~= NULL then
+ if timeout then
+ execute(connection,formatters["SET SESSION connect_timeout=%s ;"](timeout))
+ end
+ local t = {
+ _connection_ = connection,
+ }
+ return setmetatable(t,mt)
+ end
end
-end
-local function message(t)
- return mysql_error_message(t._session_)
-end
-
-local function close(t)
- -- dummy, as we have a global session
-end
+ local function message(t)
+ return mysql_error_message(t._session_)
+ end
-local mt = {
- __index = {
- connect = open,
- close = close,
- message = message,
- }
-}
+ local function close(t)
+ local connection = t._connection_
+ if connection and connection ~= NULL then
+ ffi_gc(connection, mysql_close)
+ t.connection = nil
+ end
+ end
-local function initialize()
- local session = {
- _session_ = mysql_initialize(instance) -- maybe share, single thread anyway
+ local mt = {
+ __index = {
+ connect = open,
+ close = close,
+ message = message,
+ },
}
- return setmetatable(session,mt)
-end
--- -- -- --
+ initializesession = function()
+ local session = {
+ _session_ = mysql_open_session(instance) -- maybe share, single thread anyway
+ }
+ return setmetatable(session,mt)
+ end
-local function connect(session,specification)
- return session:connect(
- specification.database or "",
- specification.username or "",
- specification.password or "",
- specification.host or "",
- specification.port
- )
end
-local function error_in_connection(specification,action)
- report_state("error in connection: [%s] user %s into %s at %s:%s",
- action or "unknown",
- specification.username or "no username",
- specification.database or "no database",
- specification.host or "no host",
- specification.port or "no port"
- )
-end
+local executequery do
-local function datafetched(specification,query,converter)
- if not query or query == "" then
- report_state("no valid query")
- return { }, { }
+ local function connect(session,specification)
+ return session:connect(
+ specification.database or "",
+ specification.username or "",
+ specification.password or "",
+ specification.host or "",
+ specification.port
+ )
end
- local id = specification.id
- local session, connection
- if id then
- local c = cache[id]
- if c then
- session = c.session
- connection = c.connection
+
+ local function fetched(specification,query,converter)
+ if not query or query == "" then
+ report_state("no valid query")
+ return false
end
- if not connection then
- session = initialize()
- connection = connect(session,specification)
+ local id = specification.id
+ local session, connection
+ if id then
+ local c = cache[id]
+ if c then
+ session = c.session
+ connection = c.connection
+ end
if not connection then
- for i=1,nofretries do
- sleep(retrydelay)
- report_state("retrying to connect: [%s.%s] %s@%s to %s:%s",
- id,i,
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
- connection = connect(session,specification)
- if connection then
- break
- end
+ session = initializesession()
+ if not session then
+ return formatters["no session for %a"](id)
end
- end
- if connection then
- cache[id] = { session = session, connection = connection }
- end
- end
- else
- session = initialize()
- connection = connect(session,specification)
- if not connection then
- for i=1,nofretries do
- sleep(retrydelay)
- report_state("retrying to connect: [%s] %s@%s to %s:%s",
- i,
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
connection = connect(session,specification)
- if connection then
- break
+ if not connection then
+ return formatters["no connection for %a"](id)
end
+ cache[id] = { session = session, connection = connection }
+ end
+ else
+ session = initializesession()
+ if not session then
+ return "no session"
+ end
+ connection = connect(session,specification)
+ if not connection then
+ return "no connection"
end
end
- end
- if not connection then
- report_state("error in connection: %s@%s to %s:%s",
+ if not connection then
+ report_state("error in connection: %s@%s to %s:%s",
specification.database or "no database",
specification.username or "no username",
specification.host or "no host",
specification.port or "no port"
)
- return { }, { }
- end
- query = lpegmatch(querysplitter,query)
- local result, message, okay
- for i=1,#query do
- local q = query[i]
- local r, m = connection:execute(q)
- if m then
- report_state("error in query, stage: %s",string.collapsespaces(q or "?"))
- message = message and format("%s\n%s",message,m) or m
+ return "no connection"
end
- if type(r) == "table" then
- result = r
- okay = true
- elseif not m then
- okay = true
+ query = lpegmatch(querysplitter,query)
+ local result, okay
+ for i=1,#query do
+ local q = query[i]
+ local r, m = connection:execute(q)
+ if m then
+ report_state("error in query to host %a: %s",specification.host,string.collapsespaces(q or "?"))
+ if m then
+ report_state("message: %s",m)
+ end
+ end
+ local t = type(r)
+ if t == "table" then
+ result = r
+ okay = true
+ elseif t == "number" then
+ okay = true
+ end
end
- end
- local data, keys
- if result then
- if converter then
- data = converter.ffi(result)
- else
- keys = result.names
- data = { }
- for i=1,result.nofrows do
- data[i] = result:hash()
+ if not okay then -- can go
+ -- why do we close a session
+ if connection then
+ connection:close()
+ end
+ if session then
+ session:close()
end
+ if id then
+ cache[id] = nil
+ end
+ return "execution error"
end
- result:finish() -- result:close()
- elseif message then
- report_state("message %s",message)
- end
- if not keys then
- keys = { }
- end
- if not data then
- data = { }
- end
- if not id then
- connection:close()
- session:close()
+ local data, keys
+ if result then
+ if converter then
+ data = converter.ffi(result)
+ else
+ local _result_ = result._result_
+ local noffields = result.noffields
+ local nofrows = result.nofrows
+ keys = result:getcolnames()
+ data = { }
+ if noffields > 0 and nofrows > 0 then
+ for i=1,nofrows do
+ local cells = { }
+ local row = mysql_fetch_row(_result_)
+ for j=1,noffields do
+ local s = row[j-1]
+ local k = keys[j]
+ if s == NULL then
+ cells[k] = ""
+ else
+ cells[k] = ffi_tostring(s)
+ end
+ end
+ data[i] = cells
+ end
+ end
+ end
+ result:close()
+ end
+ --
+ if not id then
+ if connection then
+ connection:close()
+ end
+ if session then
+ session:close()
+ end
+ end
+ return false, data, keys
end
- return data, keys
-end
-local function execute(specification)
- if trace_sql then
- report_state("executing library")
- end
- if not validspecification(specification) then
- report_state("error in specification")
- return
- end
- local query = dataprepared(specification)
- if not query then
- report_state("error in preparation")
- return
- end
- local data, keys = datafetched(specification,query,specification.converter)
- if not data then
- report_state("error in fetching")
- return
+ local function datafetched(specification,query,converter)
+ local callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter)
+ if not callokay then
+ report_state("call error, retrying")
+ callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter)
+ elseif connectionerror then
+ report_state("error: %s, retrying",connectionerror)
+ callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter)
+ end
+ if not callokay then
+ report_state("persistent call error")
+ elseif connectionerror then
+ report_state("persistent error: %s",connectionerror)
+ end
+ return data or { }, keys or { }
end
- local one = data[1]
- if one then
- setmetatable(data,{ __index = one } )
+
+ executequery = function(specification)
+ if trace_sql then
+ report_state("executing library")
+ end
+ if not validspecification(specification) then
+ report_state("error in specification")
+ return
+ end
+ local query = dataprepared(specification)
+ if not query then
+ report_state("error in preparation")
+ return
+ end
+ local data, keys = datafetched(specification,query,specification.converter)
+ if not data then
+ report_state("error in fetching")
+ return
+ end
+ local one = data[1]
+ if one then
+ setmetatable(data,{ __index = one } )
+ end
+ return data, keys
end
- return data, keys
+
end
local wraptemplate = [[
@@ -530,13 +581,14 @@ return function(result)
if not result then
return { }
end
- local nofrows = result.nofrows or 0
+ local nofrows = result.nofrows
if nofrows == 0 then
return { }
end
- local noffields = result.noffields or 0
- local _result_ = result._result_
+ local noffields = result.noffields
local target = { } -- no %s needed here
+ local _result_ = result._result_
+ -- we can share cells
for i=1,nofrows do
local cells = { }
local row = mysql_fetch_row(_result_)
@@ -552,7 +604,7 @@ return function(result)
%s
}
end
- result:finish() -- result:close()
+ result:close()
return target
end
]]
@@ -560,9 +612,9 @@ end
local celltemplate = "cells[%s]"
methods.ffi = {
- runner = function() end, -- never called
- execute = execute,
- initialize = initialize, -- returns session
+ runner = function() end, -- never called
+ execute = executequery,
+ initialize = initializesession, -- returns session
usesfiles = false,
wraptemplate = wraptemplate,
celltemplate = celltemplate,
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-library.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-library.lua
index a2b692e4588..dbbeb32cc46 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-library.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-library.lua
@@ -156,13 +156,13 @@ local function fetched(specification,query,converter)
okay = true
end
end
- if not okay then -- can go
- if session then
- session:close()
- end
+ if not okay then
if connection then
connection:close()
end
+ if session then
+ session:close()
+ end
if id then
cache[id] = nil
end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-sqlite.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-sqlite.lua
index 04d5ced3a25..cf4a3a8b04d 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-sqlite.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sql-imp-sqlite.lua
@@ -132,7 +132,6 @@ setmetatable(cache, {
local f_preamble = formatters[ [[
ATTACH `%s` AS `%s` ;
PRAGMA `%s`.synchronous = normal ;
-PRAGMA journal_mode = truncate ;
]] ]
local function execute(specification)
@@ -211,17 +210,19 @@ local function execute(specification)
else
local column = { }
callback = function(data,nofcolumns,values,fields)
- for i=0,nofcolumns-1 do
+ for i=1,nofcolumns do
local field
if keysdone then
- field = keys[i+1]
+ field = keys[i]
else
-- field = get_list_item(fields,i)
- field = ffi_tostring(fields[i])
+ field = ffi_tostring(fields[i-1])
keys[i+1] = field
end
- -- column[field] = get_list_item(values,i)
- column[field] = ffi_tostring(values[i])
+ if field then
+ -- column[field] = get_list_item(values,i)
+ column[field] = ffi_tostring(values[i-1])
+ end
end
nofrows = nofrows + 1
keysdone = true
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sql-logins.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sql-logins.lua
index dcb48fb356a..c19bfbdf81f 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sql-logins.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sql-logins.lua
@@ -211,9 +211,10 @@ end
logins.userpurge = userpurge
local function verdict(okay,...)
- if not trace_logins then
- -- no tracing
- elseif okay then
+-- if not trace_logins then
+-- -- no tracing
+-- else
+ if okay then
report_logins("%s, granted",formatter(...))
else
report_logins("%s, blocked",formatter(...))
@@ -244,6 +245,11 @@ function logins.userpermitted(db,name)
}
end
if not data or not data.name then
+ if not data then
+ report_logins("no user data for %a",name)
+ else
+ report_logins("no name entry for %a",name)
+ end
local d = {
name = name,
state = 0,
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sql-users.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sql-users.lua
index 7204fb310da..57c99b2a776 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sql-users.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sql-users.lua
@@ -25,12 +25,16 @@ local trace_sql = false trackers.register("sql.users.trace", function(v) trace_
local report = logs.reporter("sql","users")
local split = lpeg.splitat(":")
+
local valid = nil
local hash = function(s) return "MD5:" .. sumHEXA(s) end
+local sha2 = sha2 or (utilities and utilities.sha2)
-if LUAVERSION >= 5.3 then
+if not sha2 and LUAVERSION >= 5.3 then
+ sha2 = require("util-sha")
+end
- local sha2 = require("util-sha")
+if sha2 then
local HASH224 = sha2.HASH224
local HASH256 = sha2.HASH256
@@ -238,9 +242,7 @@ function users.valid(db,username,password,address)
name = username,
},
}
-
local data = data and data[1]
-
if not data then
return false, "unknown user"
elseif not data.enabled then
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sta.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sta.lua
index d140cacdcd8..7819395f69c 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sta.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sta.lua
@@ -289,24 +289,24 @@ end
--
-- local concat = table.concat
--
--- local pdfpageliteral = nodes.pool.pdfpageliteral
+-- local pageliteral = nodes.pool.pageliteral
--
-- function demostacker.start(s,t,first,last)
-- local n = whatever[t[last]]
-- -- s.report("start: %s",n)
--- return pdfpageliteral(n)
+-- return pageliteral(n)
-- end
--
-- function demostacker.stop(s,t,first,last)
-- local n = whatever[false]
-- -- s.report("stop: %s",n)
--- return pdfpageliteral(n)
+-- return pageliteral(n)
-- end
--
-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
-- local n = whatever[t2[last2]]
-- -- s.report("change: %s",n)
--- return pdfpageliteral(n)
+-- return pageliteral(n)
-- end
--
-- demostacker.mode = "switch"
@@ -325,7 +325,7 @@ end
-- r[#r+1] = whatever[t[i]]
-- end
-- -- s.report("start: %s",concat(r," "))
--- return pdfpageliteral(concat(r," "))
+-- return pageliteral(concat(r," "))
-- end
--
-- function demostacker.stop(s,t,first,last)
@@ -334,7 +334,7 @@ end
-- r[#r+1] = whatever[false]
-- end
-- -- s.report("stop: %s",concat(r," "))
--- return pdfpageliteral(concat(r," "))
+-- return pageliteral(concat(r," "))
-- end
--
-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
@@ -346,7 +346,7 @@ end
-- r[#r+1] = whatever[t2[i]]
-- end
-- -- s.report("change: %s",concat(r," "))
--- return pdfpageliteral(concat(r," "))
+-- return pageliteral(concat(r," "))
-- end
--
-- demostacker.mode = "stack"
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-sto.lua b/Master/texmf-dist/tex/context/base/mkiv/util-sto.lua
index 5b6915eaf01..a08d25ced18 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-sto.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-sto.lua
@@ -196,6 +196,19 @@ function table.getmetatablekey(t,key,value)
return m and m[key]
end
+function table.makeweak(t)
+ if not t then
+ t = { }
+ end
+ local m = getmetatable(t)
+ if m then
+ m.__mode = "v"
+ else
+ setmetatable(t,{ __mode = "v" })
+ end
+ return t
+end
+
-- Problem: we have no __next (which is ok as it would probably slow down lua) so
-- we cannot loop over the keys.
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-str.lua b/Master/texmf-dist/tex/context/base/mkiv/util-str.lua
index 05ff9f304d7..713c294ebe7 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-str.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-str.lua
@@ -22,46 +22,72 @@ local utfchar, utfbyte, utflen = utf.char, utf.byte, utf.len
----- loadstripped = utilities.lua.loadstripped
----- setmetatableindex = table.setmetatableindex
-local loadstripped = nil
-local oldfashioned = LUAVERSION < 5.2
-
-if oldfashioned then
-
- loadstripped = function(str,shortcuts)
- return load(str)
- end
-
-else
-
- loadstripped = function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+local loadstripped = function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
-
end
-- todo: make a special namespace for the formatter
if not number then number = { } end -- temp hack for luatex-fonts
-local stripper = patterns.stripzeros
+local stripzero = patterns.stripzero
+local stripzeros = patterns.stripzeros
local newline = patterns.newline
local endofstring = patterns.endofstring
+local anything = patterns.anything
local whitespace = patterns.whitespace
+local space = patterns.space
local spacer = patterns.spacer
local spaceortab = patterns.spaceortab
+local digit = patterns.digit
+local sign = patterns.sign
+local period = patterns.period
+
+-- local function points(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0pt" or lpegmatch(stripzeros,format("%.5fpt",n/65536))
+-- end
+
+-- local function basepoints(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0bp" or lpegmatch(stripzeros,format("%.5fbp", n*(7200/7227)/65536))
+-- end
+
+local ptf = 1 / 65536
+local bpf = (7200/7227) / 65536
local function points(n)
+ if n == 0 then
+ return "0pt"
+ end
n = tonumber(n)
- return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * ptf
+ if n % 1 == 0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt
end
local function basepoints(n)
+ if n == 0 then
+ return "0pt"
+ end
n = tonumber(n)
- return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536))
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * bpf
+ if n % 1 == 0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt
end
number.points = points
@@ -72,7 +98,6 @@ number.basepoints = basepoints
local rubish = spaceortab^0 * newline
local anyrubish = spaceortab + newline
-local anything = patterns.anything
local stripped = (spaceortab^1 / "") * newline
local leading = rubish^0 / ""
local trailing = (anyrubish^1 * endofstring) / ""
@@ -140,7 +165,7 @@ local pattern =
+ newline * Cp() / function(position)
extra, start = 0, position
end
- + patterns.anything
+ + anything
)^1)
function strings.tabtospace(str,tab)
@@ -183,27 +208,31 @@ end
-- return str
-- end
-local space = spacer^0
-local nospace = space/""
-local endofline = nospace * newline
+local optionalspace = spacer^0
+local nospace = optionalspace/""
+local endofline = nospace * newline
-local stripend = (whitespace^1 * endofstring)/""
+local stripend = (whitespace^1 * endofstring)/""
-local normalline = (nospace * ((1-space*(newline+endofstring))^1) * nospace)
+local normalline = (nospace * ((1-optionalspace*(newline+endofstring))^1) * nospace)
-local stripempty = endofline^1/""
-local normalempty = endofline^1
-local singleempty = endofline * (endofline^0/"")
-local doubleempty = endofline * endofline^-1 * (endofline^0/"")
+local stripempty = endofline^1/""
+local normalempty = endofline^1
+local singleempty = endofline * (endofline^0/"")
+local doubleempty = endofline * endofline^-1 * (endofline^0/"")
+local stripstart = stripempty^0
-local stripstart = stripempty^0
+local intospace = whitespace^1/" "
+local noleading = whitespace^1/""
+local notrailing = noleading * endofstring
-local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 )
-local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 )
-local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 )
-local p_retain_normal = Cs ( ( normalline + normalempty )^0 )
-local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 )
-local p_retain_noempty = Cs ( ( normalline + singleempty )^0 )
+local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 )
+local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 )
+local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 )
+local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1 )^0 )
+local p_retain_normal = Cs ( ( normalline + normalempty )^0 )
+local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 )
+local p_retain_noempty = Cs ( ( normalline + singleempty )^0 )
-- function striplines(str,prune,collapse,noempty)
-- if prune then
@@ -229,10 +258,11 @@ local striplinepatterns = {
["prune"] = p_prune_normal,
["prune and collapse"] = p_prune_collapse, -- default
["prune and no empty"] = p_prune_noempty,
+ ["prune and to space"] = p_prune_intospace,
["retain"] = p_retain_normal,
["retain and collapse"] = p_retain_collapse,
["retain and no empty"] = p_retain_noempty,
- ["collapse"] = patterns.collapser, -- how about: stripper fullstripper
+ ["collapse"] = patterns.collapser,
}
setmetatable(striplinepatterns,{ __index = function(t,k) return p_prune_collapse end })
@@ -243,6 +273,10 @@ function strings.striplines(str,how)
return str and lpegmatch(striplinepatterns[how],str) or str
end
+function strings.collapse(str) -- maybe also in strings
+ return str and lpegmatch(p_prune_intospace,str) or str
+end
+
-- also see: string.collapsespaces
strings.striplong = strings.striplines -- for old times sake
@@ -258,13 +292,14 @@ strings.striplong = strings.striplines -- for old times sake
-- " zus wim jet",
-- " ",
-- }, "\n")
-
+--
-- local str = table.concat( {
-- " aaaa",
-- " bb",
-- " cccccc",
+-- " ",
-- }, "\n")
-
+--
-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do
-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k))
-- end
@@ -335,6 +370,7 @@ end
-- automatic %...a 'whatever' (string, table, ...)
-- automatic %...A "whatever" (string, table, ...)
-- zap %...z skip
+-- stripped %...N %...N
-- comma/period real %...m
-- period/comma real %...M
-- formatted float %...k n.m
@@ -410,27 +446,45 @@ end
-- maybe to util-num
-local digit = patterns.digit
-local period = patterns.period
-local three = digit * digit * digit
+local two = digit * digit
+local three = two * digit
+local prefix = (Carg(1) * three)^1
local splitter = Cs (
- (((1 - (three^1 * period))^1 + C(three)) * (Carg(1) * three)^1 + C((1-period)^1))
- * (P(1)/"" * Carg(2)) * C(2)
+ (((1 - (three^1 * period))^1 + C(three)) * prefix + C((1-period)^1))
+ * (anything/"" * Carg(2)) * C(2)
+)
+
+local splitter3 = Cs (
+ three * prefix * endofstring +
+ two * prefix * endofstring +
+ digit * prefix * endofstring +
+ three +
+ two +
+ digit
)
patterns.formattednumber = splitter
function number.formatted(n,sep1,sep2)
- local s = type(s) == "string" and n or format("%0.2f",n)
- if sep1 == true then
- return lpegmatch(splitter,s,1,".",",")
- elseif sep1 == "." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
- elseif sep1 == "," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ if sep1 == false then
+ if type(n) == "number" then
+ n = tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ if type(n) == "number" then
+ n = format("%0.2f",n)
+ end
+ if sep1 == true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1 == "." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1 == "," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+ else
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+ end
end
end
@@ -443,14 +497,22 @@ end
-- print(number.formatted(1234567))
-- print(number.formatted(12345678))
-- print(number.formatted(12345678,true))
+-- print(number.formatted(1,false))
+-- print(number.formatted(12,false))
+-- print(number.formatted(123,false))
+-- print(number.formatted(1234,false))
+-- print(number.formatted(12345,false))
+-- print(number.formatted(123456,false))
+-- print(number.formatted(1234567,false))
+-- print(number.formatted(12345678,false))
-- print(number.formatted(1234.56,"!","?"))
local p = Cs(
P("-")^0
* (P("0")^1/"")^0
- * (1-P("."))^0
- * (P(".") * P("0")^1 * P(-1)/"" + P(".")^0)
- * P(1-P("0")^1*P(-1))^0
+ * (1-period)^0
+ * (period * P("0")^1 * endofstring/"" + period^0)
+ * P(1-P("0")^1*endofstring)^0
)
function number.compactfloat(n,fmt)
@@ -469,12 +531,11 @@ end
local zero = P("0")^1 / ""
local plus = P("+") / ""
local minus = P("-")
-local separator = S(".")
-local digit = R("09")
+local separator = period
local trailing = zero^1 * #S("eE")
-local exponent = (S("eE") * (plus + Cs((minus * zero^0 * P(-1))/"") + minus) * zero^0 * (P(-1) * Cc("0") + P(1)^1))
+local exponent = (S("eE") * (plus + Cs((minus * zero^0 * endofstring)/"") + minus) * zero^0 * (endofstring * Cc("0") + anything^1))
local pattern_a = Cs(minus^0 * digit^1 * (separator/"" * trailing + separator * (trailing + digit)^0) * exponent)
-local pattern_b = Cs((exponent + P(1))^0)
+local pattern_b = Cs((exponent + anything)^0)
function number.sparseexponent(f,n)
if not n then
@@ -524,62 +585,36 @@ local template = [[
return function(%s) return %s end
]]
-local preamble, environment = "", { }
-
-if oldfashioned then
-
- preamble = [[
-local lpeg=lpeg
-local type=type
-local tostring=tostring
-local tonumber=tonumber
-local format=string.format
-local concat=table.concat
-local signed=number.signed
-local points=number.points
-local basepoints= number.basepoints
-local utfchar=utf.char
-local utfbyte=utf.byte
-local lpegmatch=lpeg.match
-local nspaces=string.nspaces
-local utfpadding=string.utfpadding
-local tracedchar=string.tracedchar
-local autosingle=string.autosingle
-local autodouble=string.autodouble
-local sequenced=table.sequenced
-local formattednumber=number.formatted
-local sparseexponent=number.sparseexponent
-local formattedfloat=number.formattedfloat
- ]]
-
-else
-
- environment = {
- global = global or _G,
- lpeg = lpeg,
- type = type,
- tostring = tostring,
- tonumber = tonumber,
- format = string.format,
- concat = table.concat,
- signed = number.signed,
- points = number.points,
- basepoints = number.basepoints,
- utfchar = utf.char,
- utfbyte = utf.byte,
- lpegmatch = lpeg.match,
- nspaces = string.nspaces,
- utfpadding = string.utfpadding,
- tracedchar = string.tracedchar,
- autosingle = string.autosingle,
- autodouble = string.autodouble,
- sequenced = table.sequenced,
- formattednumber = number.formatted,
- sparseexponent = number.sparseexponent,
- formattedfloat = number.formattedfloat,
- }
-
-end
+local preamble = ""
+
+local environment = {
+ global = global or _G,
+ lpeg = lpeg,
+ type = type,
+ tostring = tostring,
+ tonumber = tonumber,
+ format = string.format,
+ concat = table.concat,
+ signed = number.signed,
+ points = number.points,
+ basepoints = number.basepoints,
+ utfchar = utf.char,
+ utfbyte = utf.byte,
+ lpegmatch = lpeg.match,
+ nspaces = string.nspaces,
+ utfpadding = string.utfpadding,
+ tracedchar = string.tracedchar,
+ autosingle = string.autosingle,
+ autodouble = string.autodouble,
+ sequenced = table.sequenced,
+ formattednumber = number.formatted,
+ sparseexponent = number.sparseexponent,
+ formattedfloat = number.formattedfloat,
+ stripzero = lpeg.patterns.stripzero,
+ stripzeros = lpeg.patterns.stripzeros,
+
+ FORMAT = string.f9,
+}
-- -- --
@@ -593,10 +628,10 @@ setmetatable(arguments, { __index =
end
})
-local prefix_any = C((S("+- .") + R("09"))^0)
-local prefix_sub = (C((S("+-") + R("09"))^0) + Cc(0))
- * P(".")
- * (C((S("+-") + R("09"))^0) + Cc(0))
+local prefix_any = C((sign + space + period + digit)^0)
+local prefix_sub = (C((sign + digit)^0) + Cc(0))
+ * period
+ * (C((sign + digit)^0) + Cc(0))
local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0)
-- we've split all cases as then we can optimize them (let's omit the fuzzy u)
@@ -697,6 +732,17 @@ local format_F = function(f) -- beware, no cast to number
end
end
+-- if string.f9 then
+-- format_F = function(f) -- beware, no cast to number
+-- n = n + 1
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or FORMAT(a%s))",n,n,n,n,n)
+-- else
+-- return format("((a%s %% 1 == 0) and format('%%i',a%s) or FORMAT(a%s,'%%%sf'))",n,n,n,f)
+-- end
+-- end
+-- end
+
local format_k = function(b,a) -- slow
n = n + 1
return format("formattedfloat(a%s,%i,%i)",n,b or 0, a or 0)
@@ -840,9 +886,43 @@ local format_L = function()
return format("(a%s and 'TRUE' or 'FALSE')",n)
end
-local format_N = function() -- strips leading zeros
+local format_n = function() -- strips leading and trailing zeros and removes .0
+ n = n + 1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+
+-- local format_N = function() -- strips leading and trailing zeros (also accepts string)
+-- n = n + 1
+-- return format("tostring(tonumber(a%s) or a%s)",n,n)
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or ((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or ((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+local format_N = function(f) -- strips leading and trailing zeros
n = n + 1
- return format("tostring(tonumber(a%s) or a%s)",n,n)
+ -- stripzero (singular) as we only have a number
+ if not f or f == "" then
+ f = ".9"
+ end -- always a leading number !
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a = function(f)
@@ -882,7 +962,11 @@ local format_m = function(f)
if not f or f == "" then
f = ","
end
- return format([[formattednumber(a%s,%q,".")]],n,f)
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M = function(f)
@@ -890,7 +974,11 @@ local format_M = function(f)
if not f or f == "" then
f = "."
end
- return format([[formattednumber(a%s,%q,",")]],n,f)
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
--
@@ -902,42 +990,100 @@ end
--
+-- local strip
+--
+-- local format_Z = function(f)
+-- n = n + 1
+-- if not f or f == "" then
+-- f = ".9"
+-- end
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or (strip and lpegmatch(stripzero,format('%%%sf',a%s))) or format('%%%sf',a%s))",n,n,f,n,f,n)
+-- end
+--
+-- function strings.stripformatterzeros()
+-- strip = true
+-- end
+
+-- add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp")
+--
+-- add(formatters,"foo:bar",[[foo(...)]], { foo = function(...) print(...) return "!" end })
+-- print(string.formatters["foo %3!foo:bar! bar"](1,2,3))
+
+
local format_rest = function(s)
return format("%q",s) -- catches " and \n and such
end
+-- local format_extension = function(extensions,f,name)
+-- local extension = extensions[name] or "tostring(%s)"
+-- local f = tonumber(f) or 1
+-- local w = find(extension,"%.%.%.")
+-- if f == 0 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","")
+-- end
+-- return extension
+-- elseif f == 1 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","%%s")
+-- end
+-- n = n + 1
+-- local a = "a" .. n
+-- return format(extension,a,a) -- maybe more times?
+-- elseif f < 0 then
+-- local a = "a" .. (n + f + 1)
+-- return format(extension,a,a)
+-- else
+-- if w then
+-- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+-- end
+-- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+-- -- cache we don't save much and there are hardly any extensions anyway
+-- local t = { }
+-- for i=1,f do
+-- n = n + 1
+-- -- t[#t+1] = "a" .. n
+-- t[i] = "a" .. n
+-- end
+-- return format(extension,unpack(t))
+-- end
+-- end
+
local format_extension = function(extensions,f,name)
local extension = extensions[name] or "tostring(%s)"
local f = tonumber(f) or 1
local w = find(extension,"%.%.%.")
- if f == 0 then
- if w then
+ if w then
+ -- we have a wildcard
+ if f == 0 then
extension = gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f == 1 then
- if w then
+ return extension
+ elseif f == 1 then
extension = gsub(extension,"%.%.%.","%%s")
- end
- n = n + 1
- local a = "a" .. n
- return format(extension,a,a) -- maybe more times?
- elseif f < 0 then
- local a = "a" .. (n + f + 1)
- return format(extension,a,a)
- else
- if w then
+ n = n + 1
+ local a = "a" .. n
+ return format(extension,a,a) -- maybe more times?
+ elseif f < 0 then
+ local a = "a" .. (n + f + 1)
+ return format(extension,a,a)
+ else
extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+ -- cache we don't save much and there are hardly any extensions anyway
+ local t = { }
+ for i=1,f do
+ n = n + 1
+ -- t[#t+1] = "a" .. n
+ t[i] = "a" .. n
+ end
+ return format(extension,unpack(t))
end
- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
- -- cache we don't save much and there are hardly any extensions anyway
- local t = { }
- for i=1,f do
+ else
+ extension = gsub(extension,"%%s",function()
n = n + 1
- -- t[#t+1] = "a" .. n
- t[i] = "a" .. n
- end
- return format(extension,unpack(t))
+ return "a" .. n
+ end)
+ return extension
end
end
@@ -962,6 +1108,7 @@ local builder = Cs { "start",
+ V("C")
+ V("S") -- new
+ V("Q") -- new
+ + V("n") -- new
+ V("N") -- new
+ V("k") -- new
--
@@ -986,7 +1133,7 @@ local builder = Cs { "start",
)
+ V("*")
)
- * (P(-1) + Carg(1))
+ * (endofstring + Carg(1))
)^0,
--
["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string)
@@ -1005,7 +1152,8 @@ local builder = Cs { "start",
--
["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring)
- ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros)
+ ["n"] = (prefix_any * P("n")) / format_n, -- %n => tonumber (strips leading and trailing zeros, as well as .0, expects number)
+ ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading and trailing zeros, also takes string)
["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character
@@ -1029,10 +1177,11 @@ local builder = Cs { "start",
["j"] = (prefix_any * P("j")) / format_j, -- %j => %e (float) stripped exponent (irrational)
["J"] = (prefix_any * P("J")) / format_J, -- %J => %E (float) stripped exponent (irrational)
--
- ["m"] = (prefix_tab * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .)
- ["M"] = (prefix_tab * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
+ ["m"] = (prefix_any * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .)
+ ["M"] = (prefix_any * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
--
["z"] = (prefix_any * P("z")) / format_z, -- %z => skip n arguments
+ -- ["Z"] = (prefix_any * P("Z")) / format_Z, -- %Z => optionally strip zeros
--
["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring)
["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring)
@@ -1057,7 +1206,7 @@ local preset = {
}
local direct =
- P("%") * (S("+- .") + R("09"))^0 * S("sqidfgGeExXo") * P(-1)
+ P("%") * (sign + space + period + digit)^0 * S("sqidfgGeExXo") * endofstring
/ [[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
@@ -1134,36 +1283,22 @@ strings.formatters = { }
-- _connector_ is an experiment
-if oldfashioned then
-
- function strings.formatters.new(noconcat)
- local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } }
- setmetatable(t, { __index = make, __call = use })
- return t
+function strings.formatters.new(noconcat)
+ local e = { } -- better make a copy as we can overload
+ for k, v in next, environment do
+ e[k] = v
end
-
-else
-
- function strings.formatters.new(noconcat)
- local e = { } -- better make a copy as we can overload
- for k, v in next, environment do
- e[k] = v
- end
- local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e }
- setmetatable(t, { __index = make, __call = use })
- return t
- end
-
+ local t = {
+ _type_ = "formatter",
+ _connector_ = noconcat and "," or "..",
+ _extensions_ = { },
+ _preamble_ = "",
+ _environment_ = e,
+ }
+ setmetatable(t, { __index = make, __call = use })
+ return t
end
--- function strings.formatters.new()
--- local t = { _extensions_ = { }, _preamble_ = "", _type_ = "formatter", _n_ = 0 }
--- local m = { _t_ = t }
--- setmetatable(t, { __index = m, __call = use })
--- setmetatable(m, { __index = make })
--- return t
--- end
-
local formatters = strings.formatters.new() -- the default instance
string.formatters = formatters -- in the main string namespace
@@ -1186,27 +1321,17 @@ strings.formatters.add = add
-- registered in the default instance (should we fall back on this one?)
-patterns.xmlescape = Cs((P("<")/"<" + P(">")/">" + P("&")/"&" + P('"')/""" + P(1))^0)
-patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0)
+patterns.xmlescape = Cs((P("<")/"<" + P(">")/">" + P("&")/"&" + P('"')/""" + anything)^0)
+patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + anything)^0)
patterns.luaescape = Cs(((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0) -- maybe also \0
patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0 * Cc('"'))
-- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
-- faster again when other q-escapables are found (the ones we don't need to escape)
-if oldfashioned then
-
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
-
-else
-
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape })
-
-end
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape })
-- -- yes or no:
--
@@ -1243,7 +1368,6 @@ end
local dquote = patterns.dquote -- P('"')
local equote = patterns.escaped + dquote / '\\"' + 1
-local space = patterns.space
local cquote = Cc('"')
local pattern =
@@ -1277,3 +1401,11 @@ function strings.newcollector()
end
end
end
+
+--
+
+local f_16_16 = formatters["%0.5N"]
+
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua b/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua
index 1b069e2ae21..b51c6589a07 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua
@@ -22,7 +22,8 @@ local utftoeight = utf.toeight
local splitter = lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables
- local composed, t = nil, { }
+ local composed = nil
+ local t = { }
local snippets = lpegmatch(splitter,target)
for i=1,#snippets - (nolast and 1 or 0) do
local name = snippets[i]
@@ -819,3 +820,54 @@ if setinspector then
end
end)
end
+
+-- ordered hashes (for now here but in the table namespace):
+
+-- local t = table.orderedhash()
+--
+-- t["1"] = { "a", "b" }
+-- t["2"] = { }
+-- t["2a"] = { "a", "c", "d" }
+--
+-- for k, v in table.ordered(t) do
+-- ...
+-- end
+
+local mt = {
+ __newindex = function(t,k,v)
+ local n = t.last + 1
+ t.last = n
+ t.list[n] = k
+ t.hash[k] = v
+ end,
+ __index = function(t,k)
+ return t.hash[k]
+ end,
+ __len = function(t)
+ return t.last
+ end,
+}
+
+function table.orderedhash()
+ return setmetatable({ list = { }, hash = { }, last = 0 }, mt)
+end
+
+function table.ordered(t)
+ local n = t.last
+ if n > 0 then
+ local l = t.list
+ local i = 1
+ local h = t.hash
+ local f = function()
+ if i <= n then
+ local k = i
+ local v = h[l[k]]
+ i = i + 1
+ return k, v
+ end
+ end
+ return f, 1, h[l[1]]
+ else
+ return function() end
+ end
+end
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-you.lua b/Master/texmf-dist/tex/context/base/mkiv/util-you.lua
index 32a7e07d4e9..5802e7d7afd 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/util-you.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/util-you.lua
@@ -30,7 +30,6 @@ utilities.youless = youless
local lpegmatch = lpeg.match
local formatters = string.formatters
-local sortedhash = table.sortedhash
local tonumber, type, next = tonumber, type, next
--
cgit v1.2.3