From 8faafb7250a84be6f1d96be67cbbe27d500d3b47 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 5 Jan 2012 19:27:25 +0100 Subject: beta 2011.11.13 23:53 --- scripts/context/lua/mtx-context.lua | 1 + tex/context/base/back-exp.lua | 143 ++++++---- tex/context/base/context-version.pdf | Bin 4116 -> 4118 bytes tex/context/base/context-version.png | Bin 106126 -> 106240 bytes tex/context/base/core-env.mkiv | 2 +- tex/context/base/font-otn.lua | 50 ++-- tex/context/base/math-vfu.lua | 18 +- tex/context/base/status-files.pdf | Bin 24101 -> 24150 bytes tex/context/base/status-lua.pdf | Bin 168949 -> 168961 bytes tex/context/base/syst-aux.mkiv | 32 ++- tex/context/base/tabl-tab.mkiv | 15 +- tex/context/base/tabl-tbl.mkiv | 23 +- tex/context/base/typo-mar.lua | 308 +++++++++++++-------- tex/context/base/typo-pag.lua | 17 +- tex/context/fonts/lm-math.lfg | 4 +- tex/context/fonts/px-math.lfg | 1 + tex/context/fonts/tx-math.lfg | 1 + tex/generic/context/luatex/luatex-fonts-merged.lua | 52 ++-- 18 files changed, 409 insertions(+), 258 deletions(-) diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 08d6b4c0a..7323e8b04 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -452,6 +452,7 @@ scripts.context.multipass = { -- suffixes = { ".tuo", ".tuc" }, suffixes = { ".tuc" }, nofruns = 8, +-- nofruns = 7, -- test oscillation } function scripts.context.multipass.hashfiles(jobname) diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua index d7a50da3a..98d87b1ee 100644 --- a/tex/context/base/back-exp.lua +++ b/tex/context/base/back-exp.lua @@ -26,6 +26,7 @@ local insert, remove = table.insert, table.remove local topoints = number.topoints local utfvalues = string.utfvalues local fromunicode16 = fonts.mappings.fromunicode16 +local sortedhash = table.sortedhash local trace_export = false trackers.register ("export.trace", function(v) trace_export = v end) local trace_spacing = false trackers.register ("export.trace.spacing", function(v) trace_spacing = v end) @@ -251,7 +252,8 @@ local function hashlistdata() local ci = c[i] local tag = ci.references.tag if tag then - listdata[ci.metadata.kind .. ":" .. ci.metadata.name .. "-" .. tag] = ci + local m = ci.metadata + listdata[m.kind .. ":" .. m.name .. "-" .. tag] = ci end end end @@ -346,10 +348,12 @@ local function allusedstyles(xmlfile) -- result[#result+1] = format(documenttemplate,bodyfont,width,align,hyphen) -- - for element, details in table.sortedpairs(usedstyles) do - for detail, data in table.sortedpairs(details) do - local s = xml.css.fontspecification(data.style) - local c = xml.css.colorspecification(data.color) + local colorspecification = xml.css.fontspecification + local fontspecification = xml.css.fontspecification + for element, details in sortedhash(usedstyles) do + for detail, data in sortedhash(details) do + local s = fontspecification(data.style) + local c = colorspecification(data.color) result[#result+1] = format(styletemplate,element,detail, s.style or "inherit", s.variant or "inherit", @@ -375,8 +379,8 @@ local imagetemplate = [[ local function allusedimages(xmlfile) local result = { format("/* images for file %s */",xmlfile) } - for element, details in table.sortedpairs(usedimages) do - for detail, data in table.sortedpairs(details) do + for element, details in sortedhash(usedimages) do + for detail, data in sortedhash(details) do local name = data.name if file.extname(name) == "pdf" then -- temp hack .. we will have a remapper @@ -446,12 +450,13 @@ local function checkdocument(root) if data then for i=1,#data do local di = data[i] - if type(di) == "table" then - if di.tg == "ignore" then - di.element = "" - else - checkdocument(di) - end + if di.content then + -- ok + elseif di.tg == "ignore" then + di.element = "" + checkdocument(di) + else + -- can't happen end end end @@ -742,8 +747,11 @@ function extras.link(result,element,detail,n,fulltag,di) if data then for i=1,#data do local di = data[i] - if di and extras.link(result,element,detail,n,di.fulltag,di) then - return true + if di then + local fulltag = di.fulltag + if fulltag and extras.link(result,element,detail,n,fulltag,di) then + return true + end end end end @@ -817,16 +825,19 @@ local function checkmath(root) -- we can provide utf.toentities as an option if roottg == "msubsup" then local nucleus, superscript, subscript for i=1,ndata do - if type(data[i]) == "table" then - if not nucleus then - nucleus = i - elseif not superscript then - superscript = i - elseif not subscript then - subscript = i - else - -- error - end + local di = data[i] + if not di then + -- weird + elseif di.content then + -- text + elseif not nucleus then + nucleus = i + elseif not superscript then + superscript = i + elseif not subscript then + subscript = i + else + -- error end end if superscript and subscript then @@ -841,7 +852,12 @@ local function checkmath(root) -- we can provide utf.toentities as an option root.attributes = attributes for i=1,ndata do local di = data[i] - if type(di) == "table" then + if not di then + -- weird + elseif di.content then + n = n + 1 + new[n] = di + else local tg = di.tg if tg == "mleft" then attributes.left = tostring(di.data[1].data[1]) @@ -854,9 +870,6 @@ local function checkmath(root) -- we can provide utf.toentities as an option di.__i__ = n new[n] = di end - else - n = n + 1 - new[n] = di end end root.data = new @@ -866,8 +879,10 @@ local function checkmath(root) -- we can provide utf.toentities as an option return elseif ndata == 1 then local d = data[1] - if type(d) ~= "table" then - return -- can be string or false + if not d then + return + elseif d.content then + return elseif #root.data == 1 then local tg = d.tg if automathrows and roottg == "mrow" then @@ -887,7 +902,7 @@ local function checkmath(root) -- we can provide utf.toentities as an option local i = 1 while i <= ndata do -- -- -- TOO MUCH NESTED CHECKING -- -- -- local di = data[i] - if di and type(di) == "table" then + if di and not di.content then local tg = di.tg local detail = di.detail if tg == "math" then @@ -1014,34 +1029,43 @@ local function checkmath(root) -- we can provide utf.toentities as an option end function stripmath(di) - local tg = di.tg - if tg == "mtext" or tg == "ms" then + if not di then + -- + elseif di.content then return di else - local data = di.data - local ndata = #data - local n = 0 - for i=1,ndata do - local di = data[i] - if type(di) == "table" then - di = stripmath(di) + local tg = di.tg + if tg == "mtext" or tg == "ms" then + return di + else + local data = di.data + local ndata = #data + local n = 0 + for i=1,ndata do + local di = data[i] + if di and not di.content then + di = stripmath(di) + end + if di then + local content = di.content + if not content then + n = n + 1 + di.__i__ = n + data[n] = di + elseif content == " " or content == "" then + -- skip + else + n = n + 1 + data[n] = di + end + end end - if not di or di == " " or di == "" then - -- skip - elseif type(di) == "table" then - n = n + 1 - di.__i__ = n - data[n] = di - else - n = n + 1 - data[n] = di + for i=ndata,n+1,-1 do + data[i] = nil + end + if #data > 0 then + return di end - end - for i=ndata,n+1,-1 do - data[i] = nil - end - if #data > 0 then - return di end end end @@ -1066,8 +1090,8 @@ end local a, z, A, Z = 0x61, 0x7A, 0x41, 0x5A -function extras.mi(result,element,detail,n,fulltag,di) - local str = di.data[1] +function extras.mi(result,element,detail,n,fulltag,di) -- check with content + local str = di.data[1].content if str and sub(str,1,1) ~= "&" then -- hack but good enough (maybe gsub op eerste) for v in utfvalues(str) do if (v >= a and v <= z) or (v >= A and v <= Z) then @@ -1176,7 +1200,8 @@ function extras.tabulate(result,element,detail,n,fulltag,di) local content = false for i=1,#did do local d = did[i].data - if d and #d > 0 then + local c = d and c.content + if c and #c > 0 then content = true break end diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 3f89f3a03..e628eca52 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 6ed66c29c..0fc57d8f7 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv index b095008b5..e81f1e6b3 100644 --- a/tex/context/base/core-env.mkiv +++ b/tex/context/base/core-env.mkiv @@ -223,7 +223,7 @@ \expandafter\edef\csname\@mode@:\systemmodeprefix#1\endcsname{\number\csname\@mode@\systemmodeprefix#1\endcsname}% \expandafter\pushmacro\csname\@mode@:\systemmodeprefix#1\endcsname} -\def\resetsystemmode#1% +\def\popsystemmode#1% {\ifcsname\@mode@:\systemmodeprefix#1\endcsname \expandafter\popmacro\csname\@mode@:\systemmodeprefix#1\endcsname \csname\@mode@\systemmodeprefix#1\endcsname\csname\@mode@:\systemmodeprefix#1\endcsname\relax diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index e11e8d917..12ea97561 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -420,11 +420,11 @@ function handlers.gsub_single(start,kind,lookupname,replacement) return start, true end -local function set_alternative_glyph(start,alternatives,kind,chainname,chainlookupname,lookupname) -- chainname and chainlookupname optional +local function get_alternative_glyph(start,alternatives,value) -- needs checking: (global value, brrr) - local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue local choice = nil local n = #alternatives + local char = start.char -- if value == "random" then local r = random(1,n) @@ -447,30 +447,14 @@ local function set_alternative_glyph(start,alternatives,kind,chainname,chainlook value, choice = format("no %s variants, ignoring",value), false end elseif value == 0 then - value, choice = format("choice %s (no change)",value), start.char + value, choice = format("choice %s (no change)",value), char elseif value < 1 then value, choice = format("no %s variants, taking %s",value,1), alternatives[1] else value, choice = format("choice %s",value), alternatives[value] end end - if trace_alternatives then - if choice then - logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index) - else - logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char)) - end - end - if choice then - start.char = choice - if trace_alternatives then - logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index) - end - else - if trace_alternatives then - logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char)) - end - end + return choice end local function multiple_glyphs(start,multiple) -- marks ? @@ -501,7 +485,18 @@ local function multiple_glyphs(start,multiple) -- marks ? end function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence) - set_alternative_glyph(start,alternative,kind,lookupname) + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue + local choice = get_alternative_glyph(start,alternative,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(char),gref(choice),choice) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %s for %s",pref(kind,lookupname),tostring(value),gref(char)) + end + end return start, true end @@ -1102,6 +1097,7 @@ chainmores.gsub_multiple = chainprocs.gsub_multiple function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local current = start local subtables = currentlookup.subtables + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue while current do if current.id == glyph_code then -- is this check needed? local currentchar = current.char @@ -1114,7 +1110,17 @@ function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,look else alternatives = alternatives[currentchar] if alternatives then - set_alternative_glyph(current,alternatives,kind,chainname,chainlookupname,lookupname) + local choice = get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %s (%s)",cref(kind,chainname,chainlookupname,lookupname),gref(char),gref(choice),choice) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),tostring(value),gref(char)) + end + end elseif trace_bugs then logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar)) end diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua index dff7e84fa..c3f234166 100644 --- a/tex/context/base/math-vfu.lua +++ b/tex/context/base/math-vfu.lua @@ -421,7 +421,7 @@ end) function vfmath.define(specification,set,goodies) local name = specification.name -- symbolic name local size = specification.size -- given size - local loaded, fontlist, main = { }, { }, nil + local loaded, fontlist, names, main = { }, { }, { }, nil local start = (trace_virtual or trace_timings) and os.clock() local okset, n = { }, 0 for s=1,#set do @@ -438,7 +438,17 @@ function vfmath.define(specification,set,goodies) if ss.main then main = s end - local f, id = fonts.constructors.readanddefine(ssname,size) + local alreadyloaded = names[ssname] -- for px we load one twice (saves .04 sec) + local f, id + if alreadyloaded then + f, id = alreadyloaded.f, alreadyloaded.id + if trace_virtual then + report_virtual("loading font %s subfont %s with name %s is reused",name,s,ssname) + end + else + f, id = fonts.constructors.readanddefine(ssname,size) + names[ssname] = { f = f, id = id } + end if not f or id == 0 then report_virtual("loading font %s subfont %s with name %s at %s is skipped, not found",name,s,ssname,size) else @@ -446,7 +456,9 @@ function vfmath.define(specification,set,goodies) okset[n] = ss loaded[n] = f fontlist[n] = { id = id, size = size } - if not shared[s] then shared[n] = { } end + if not shared[s] then + shared[n] = { } + end if trace_virtual then report_virtual("loading font %s subfont %s with name %s at %s as id %s using encoding %s",name,s,ssname,size,id,ss.vector or "none") end diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index f355d9406..d24a42400 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 46b8d7014..307c92c4f 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index 3a9424098..0438480df 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -168,12 +168,14 @@ \let\@@expanded\empty % always long and global (less restores) -\def\expanded#1% +\unexpanded\def\expanded#1% {\xdef\@@expanded{\noexpand#1}\@@expanded} -\def\startexpanded#1\stopexpanded % see x-fo for example +\unexpanded\def\startexpanded#1\stopexpanded % see x-fo for example {\xdef\@@expanded{#1}\@@expanded} +\let\stopexpanded\relax + %D Recent \TEX's have a primitive \expanded % not yet as we need to adapt ##'s in calls @@ -3396,7 +3398,7 @@ \def\@@irecurse{@@ir@@} % ecurse} % stepper \def\@@arecurse{@@ar@@} % ecurse} % action -\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname{#4}% \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel @@ -4420,7 +4422,7 @@ {\def\dodogotopar{#1}% \redogotopar\par} -\def\GetPar +\unexpanded\def\GetPar {\expanded {\dowithpar {\the\BeforePar @@ -4429,7 +4431,7 @@ \BeforePar\emptytoks \AfterPar\emptytoks}}} -\def\GotoPar +\unexpanded\def\GotoPar {\expanded {\dogotopar {\the\BeforePar @@ -4468,7 +4470,7 @@ %D ... \par %D \stoptyping -\def\dowithpargument#1% +\unexpanded\def\dowithpargument#1% {\def\nextpar##1 \par{#1{##1}}% \def\nextarg##1{#1{##1}}% \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}} @@ -4495,7 +4497,7 @@ %D ... %D \stoptyping -\def\dowithwargument#1% +\unexpanded\def\dowithwargument#1% {\def\nextwar##1 {#1{##1}}% \def\nextarg##1{#1{##1}}% \doifnextbgroupelse\nextarg\nextwar} @@ -4626,10 +4628,10 @@ \newtoks\@@scratchtoks -\def\appendtoks {\doappendtoks \relax} -\def\prependtoks {\doprependtoks \relax} -\def\appendtoksonce {\doappendtoksonce \relax} -\def\prependtoksonce{\doprependtoksonce\relax} +\unexpanded\def\appendtoks {\doappendtoks \relax} +\unexpanded\def\prependtoks {\doprependtoks \relax} +\unexpanded\def\appendtoksonce {\doappendtoksonce \relax} +\unexpanded\def\prependtoksonce{\doprependtoksonce\relax} \def\dodoappendtoks {\dodoglobal\@@toks\doubleexpandafter{\expandafter\the\expandafter\@@toks\the\@@scratchtoks}} @@ -4657,7 +4659,7 @@ %D The test macro: -\def\doifintokselse#1#2% #1 en #2 zijn toks +\unexpanded\def\doifintokselse#1#2% #1 en #2 zijn toks {\edef\asciia{\detokenize\expandafter{\the#1}}% \edef\asciib{\detokenize\expandafter{\the#2}}% \doifstringinstringelse\asciia\asciib} @@ -4670,7 +4672,7 @@ % {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]} % {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]} -\def\removetoks#1\from#2% +\unexpanded\def\removetoks#1\from#2% {\def\doremovetoks##1#1##2\empty\empty\empty##3\\% {\def\!!stringa{##3}% \ifx\!!stringa\empty#2{##1}\else#2{##1##2}\fi}% @@ -4678,8 +4680,8 @@ %D Also: -\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} -\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} +\unexpanded\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} +\unexpanded\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} %D Hm. diff --git a/tex/context/base/tabl-tab.mkiv b/tex/context/base/tabl-tab.mkiv index 6590c6625..d7e842a62 100644 --- a/tex/context/base/tabl-tab.mkiv +++ b/tex/context/base/tabl-tab.mkiv @@ -893,7 +893,7 @@ \def\@VLd{.125em} -\def\do!ttInsertVrule % will be merged in 2005 +\def\do!ttInsertVrule {\vrule\!!width \ifnum\!tgCode=\plusone \ifx\!tgValue\empty @@ -983,6 +983,9 @@ \def\donormaltableshortrule % was: \!ttShortHrule {\omit \!ttGetHalfRuleThickness + \ifx\tablecurrenthrulecolor\empty\else + \switchtocolor[\tablecurrenthrulecolor]% see *DL* + \fi \leaders\hrule\!!height\scratchdimen\!!depth\scratchdimen\hfill \emptyhbox \ignorespaces} @@ -2055,9 +2058,9 @@ \unexpanded\def\dotableDL {\dochecktabledivision - \dosingleempty\dotableDL} + \dosingleempty\dodotableDL} -\def\dotableDL[#1]% +\def\dodotableDL[#1]% {\ifnum\tableactionstate=\tablerulestate \writestatus\m!TABLE{skipping \string\DL}% \else @@ -2072,9 +2075,9 @@ \iffirstargument \global\let\tablecurrenthrulecolor\empty \rawprocesscommalist[#1]\dotabledrulecommand - \ifx\tablecurrenthrulecolor\empty\else - \switchtocolor[\tablecurrenthrulecolor]% - \fi + % \ifx\tablecurrenthrulecolor\empty\else + % \switchtocolor[\tablecurrenthrulecolor]% see *DL* + % \fi \fi \ifcase\tabledrulespan \global\advance\currenttablecolumn \plusone diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index c7b5e7b1b..99d507cf3 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -790,6 +790,8 @@ % \starttabulate[preamble] % \starttabulate -> \starttabulate[|l|p|] +% todo: commandhandler + \def\definetabulate {\dotripleempty\dodefinetabulate} @@ -875,7 +877,8 @@ {\csname\e!start#1::\ifcsname\e!start#1::#2\endcsname#2\fi\endcsname} \setuvalue{\e!start\v!tabulate}% - {\bgroup\dodoubleempty\donormalstarttabulate} + {\bgroup % whole thing + \dodoubleempty\donormalstarttabulate} \def\doinhibitnestedtabulate {\setuvalue{\e!start\v!tabulate}% @@ -920,7 +923,7 @@ \whitespace \tabulateparameter\c!before \fi - \bgroup + \bgroup % settings \resetcharacteralign % todo: spacing around tabulate when bodyfont is set % expansion en test needed ? @@ -1710,12 +1713,12 @@ % \ifcase\tabulaterepeathead \ifinsidesplitfloat - \setbox\tabulatebox\vbox \bgroup + \global\setbox\tabulatebox\vbox \bgroup \else \startframedcontent[\tabulateparameter\c!frame]% \fi \else - \setbox\tabulatebox\vbox \bgroup + \global\setbox\tabulatebox\vbox \bgroup \fi % \dostarttagged\t!tabulate\empty @@ -1729,19 +1732,23 @@ % \ifcase\tabulaterepeathead \ifinsidesplitfloat - \egroup \splittabulatebox\tabulatebox + \egroup % box + \egroup % settings + \splittabulatebox\tabulatebox \else \stopframedcontent + \egroup \fi \else - \egroup \splittabulatebox\tabulatebox + \egroup % box + \egroup % settings + \splittabulatebox\tabulatebox \fi % - \egroup \ifinsidefloat \else \tabulateparameter\c!after \fi - \egroup} + \egroup} % whole thing % \egroup diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index 6e941bac0..4d9043424 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -31,7 +31,7 @@ if not modules then modules = { } end modules ['typo-mar'] = { -- whatever[tag] = nil -- end -- --- function anchors.startmove(tag,how) +-- function anchors.startmove(tag,how) -- save/restore nodes but they don't support moves -- local w = whatever[tag] -- if not w then -- -- error @@ -84,93 +84,103 @@ local trace_marginstack = false trackers.register("typesetters.margindata.stack local report_margindata = logs.reporter("typesetters","margindata") -local tasks = nodes.tasks -local prependaction = tasks.prependaction -local disableaction = tasks.disableaction -local enableaction = tasks.enableaction - -local variables = interfaces.variables - -local conditionals = tex.conditionals - -local v_top = variables.top -local v_depth = variables.depth -local v_local = variables["local"] -local v_global = variables["global"] -local v_left = variables.left -local v_right = variables.right -local v_flushleft = variables.flushleft -local v_flushright = variables.flushright -local v_inner = variables.inner -local v_outer = variables.outer -local v_margin = variables.margin -local v_edge = variables.edge -local v_default = variables.default -local v_normal = variables.normal -local v_yes = variables.yes -local v_first = variables.first - -local has_attribute = node.has_attribute -local set_attribute = node.set_attribute -local unset_attribute = node.unset_attribute -local copy_node_list = node.copy_list -local slide_nodes = node.slide -local hpack_nodes = node.hpack -- nodes.fasthpack not really faster here -local traverse_id = node.traverse_id -local free_node_list = node.flush_list -local insert_node_after= node.insert_after - -local link_nodes = nodes.link - -local nodecodes = nodes.nodecodes -local listcodes = nodes.listcodes -local gluecodes = nodes.gluecodes -local whatsitcodes = nodes.whatsitcodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local penalty_code = nodecodes.penalty -local whatsit_code = nodecodes.whatsit -local line_code = listcodes.line -local leftskip_code = gluecodes.leftskip -local rightskip_code = gluecodes.rightskip -local userdefined_code = whatsitcodes.userdefined - -local dir_code = whatsitcodes.dir -local localpar_code = whatsitcodes.localpar - -local nodepool = nodes.pool - -local new_kern = nodepool.kern -local new_penalty = nodepool.penalty -local new_stretch = nodepool.stretch -local new_usernumber = nodepool.usernumber -local new_latelua = nodepool.latelua - -local texcount = tex.count -local texdimen = tex.dimen -local texbox = tex.box - -local isleftpage = layouts.status.isleftpage -local registertogether = builders.paragraphs.registertogether - -local a_margindata = attributes.private("margindata") - -local inline_mark = nodepool.userids["margins.inline"] - -local margins = { } -typesetters.margins = margins - -local locations = { v_left, v_right, v_inner, v_outer } -- order might change -local categories = { } -local displaystore = { } -- [category][location][scope] -local inlinestore = { } -- [number] -local nofsaved = 0 -local nofstored = 0 -local nofinlined = 0 -local nofdelayed = 0 +local tasks = nodes.tasks +local prependaction = tasks.prependaction +local disableaction = tasks.disableaction +local enableaction = tasks.enableaction + +local variables = interfaces.variables + +local conditionals = tex.conditionals + +local v_top = variables.top +local v_depth = variables.depth +local v_local = variables["local"] +local v_global = variables["global"] +local v_left = variables.left +local v_right = variables.right +local v_flushleft = variables.flushleft +local v_flushright = variables.flushright +local v_inner = variables.inner +local v_outer = variables.outer +local v_margin = variables.margin +local v_edge = variables.edge +local v_default = variables.default +local v_normal = variables.normal +local v_yes = variables.yes +local v_continue = variables.continue +local v_first = variables.first + +local has_attribute = node.has_attribute +local set_attribute = node.set_attribute +local unset_attribute = node.unset_attribute +local copy_node_list = node.copy_list +local slide_nodes = node.slide +local hpack_nodes = node.hpack -- nodes.fasthpack not really faster here +local traverse_id = node.traverse_id +local free_node_list = node.flush_list +local insert_node_after = node.insert_after +local insert_node_before = node.insert_before + +local link_nodes = nodes.link + +local nodecodes = nodes.nodecodes +local listcodes = nodes.listcodes +local gluecodes = nodes.gluecodes +local whatsitcodes = nodes.whatsitcodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local penalty_code = nodecodes.penalty +local whatsit_code = nodecodes.whatsit +local line_code = listcodes.line +local leftskip_code = gluecodes.leftskip +local rightskip_code = gluecodes.rightskip +local userdefined_code = whatsitcodes.userdefined + +local dir_code = whatsitcodes.dir +local localpar_code = whatsitcodes.localpar + +local nodepool = nodes.pool + +local new_kern = nodepool.kern +local new_glue = nodepool.glue +local new_penalty = nodepool.penalty +local new_stretch = nodepool.stretch +local new_usernumber = nodepool.usernumber +local new_latelua = nodepool.latelua + +local texcount = tex.count +local texdimen = tex.dimen +local texbox = tex.box + +local points = number.points + +local isleftpage = layouts.status.isleftpage +local registertogether = builders.paragraphs.registertogether + +local jobpositions = job.positions +local getposition = jobpositions.position + +local a_margindata = attributes.private("margindata") + +local inline_mark = nodepool.userids["margins.inline"] + +local margins = { } +typesetters.margins = margins + +local locations = { v_left, v_right, v_inner, v_outer } -- order might change +local categories = { } +local displaystore = { } -- [category][location][scope] +local inlinestore = { } -- [number] +local nofsaved = 0 +local nofstored = 0 +local nofinlined = 0 +local nofdelayed = 0 +local h_anchors = 0 +local v_anchors = 0 local mt1 = { __index = function(t,location) @@ -339,7 +349,7 @@ end -- When the prototype inner/outer code that was part of this proved to be -- okay it was moved elsewhere. -local status, nofstatus, anchors = { }, 0, 0 +local status, nofstatus = { }, 0 local function realign(current,candidate) local location = candidate.location @@ -396,15 +406,15 @@ local function realign(current,candidate) current.width = 0 if candidate.inline then -- this mess is needed for alignments (combinations) - anchors = anchors + 1 - local anchor = new_latelua(format("_plib_.setraw('_md_:%s',pdf.h)",anchors)) - local blob_x = job.positions.v("_md_:"..anchors) or 0 - local text_x = job.positions.x("text:"..tex.count.realpageno) or 0 + h_anchors = h_anchors + 1 + local anchor = new_latelua(format("_plib_.setraw('_mh_:%s',pdf.h)",h_anchors)) + local blob_x = jobpositions.v("_mh_:"..h_anchors) or 0 + local text_x = jobpositions.x("text:"..texcount.realpageno) or 0 local move_x = text_x - blob_x delta = delta - move_x current.list = hpack_nodes(link_nodes(anchor,new_kern(-delta),current.list,new_kern(delta))) if trace_margindata then - report_margindata("realigned: %s, location: %s, margin: %s, move: %s",candidate.n,location,margin,number.points(move_x)) + report_margindata("realigned: %s, location: %s, margin: %s, move: %s",candidate.n,location,margin,points(move_x)) end else current.list = hpack_nodes(link_nodes(new_kern(-delta),current.list,new_kern(delta))) @@ -412,7 +422,6 @@ local function realign(current,candidate) report_margindata("realigned: %s, location: %s, margin: %s",candidate.n,location,margin) end end - current.width = 0 end @@ -424,15 +433,62 @@ local function realigned(current,a) return true end +-- Stacking is done in two ways: the v_yes option stacks per paragraph (or line, +-- depending on what gets by) and mostly concerns margin data dat got ste at more or +-- less the same time. The v_continue option uses position tracking and works on +-- larger range. However, crossing pages is not part of it. Anyway, when you have +-- such messed up margin data you'd better think twice. +-- +-- The stacked table keeps track (per location) of the offsets (the v_yes case). This +-- table gets saved when the v_continue case is active. We use a special variant +-- of position tracking, after all we only need the page number and vertical position. + local stacked = { } +local cache = { } local function resetstacked() - for i=1,#locations do - stacked[locations[i]] = false - end +-- for i=1,#locations do +-- stacked[locations[i]] = false +-- end + stacked = { } +end + +-- resetstacked() + +function margins.ha(tag) + local p = cache[tag] + p.r = texcount.realpageno + p.y = pdf.v + _plib_.setraw('_mv_:'..tag,p) + cache[tag] = nil +end + +local function markovershoot(current) + h_anchors = h_anchors + 1 + cache[h_anchors] = stacked + local anchor = new_latelua(format("typesetters.margins.ha(%s)",h_anchors)) -- todo: alleen als offset > line + current.list = hpack_nodes(link_nodes(anchor,current.list)) end -resetstacked() +local function getovershoot(location) + local previous = '_mv_:' .. h_anchors + local current = '_mv_:' .. (h_anchors + 1) + local p = jobpositions.v(previous) + local c = jobpositions.v(current) + if p and c and p.r and p.r == c.r then + local distance = p.y - c.y + local offset = p[location] or 0 + local overshoot = offset - distance + if trace_marginstack then + report_margindata("location: %s, distance: %s, offset: %s, overshoot: %s", + location,points(distance),points(offset),points(overshoot)) + end + if overshoot > 0 then + return overshoot + end + end + return 0 +end local function inject(parent,head,candidate) local box = candidate.box @@ -447,7 +503,7 @@ local function inject(parent,head,candidate) local line = candidate.line local baseline = candidate.baseline local offset = stacked[location] - local firstonstack = offset == false + local firstonstack = offset == false or offset == nil nofstatus = nofstatus + 1 nofdelayed = nofdelayed + 1 status[nofstatus] = candidate @@ -473,6 +529,9 @@ local function inject(parent,head,candidate) if stack == v_yes then offset = offset + candidate.dy shift = shift + offset + elseif stack == v_continue then + offset = offset + candidate.dy + getovershoot(location) + shift = shift + offset end -- -- -- -- Maybe we also need to patch offset when we apply methods, but how ... @@ -537,21 +596,25 @@ local function inject(parent,head,candidate) -- we need to add line etc to offset as well offset = offset + depth local room = { - height = height, - depth = offset, - slack = candidate.bottomspace, -- todo: 'depth' => strutdepth + height = height, + depth = offset, + slack = candidate.bottomspace, -- todo: 'depth' => strutdepth + lineheight = candidate.lineheight, -- only for tracing } -offset = offset + height + offset = offset + height stacked[location] = offset -- todo: if no real depth then zero if trace_margindata then report_margindata("status, offset: %s",offset) end - return head, room + return head, room, stack == v_continue end -local function flushinline(parent,head,done) +local function flushinline(parent,head) local current = head + local done = false + local continue = false + local room, don, con while current and nofinlined > 0 do local id = current.id if id == whatsit_code then @@ -561,24 +624,28 @@ local function flushinline(parent,head,done) if candidate then -- no vpack, as we want to realign inlinestore[n] = nil nofinlined = nofinlined - 1 - head = inject(parent,head,candidate) -- maybe return applied offset + head, room, con = inject(parent,head,candidate) -- maybe return applied offset + continue = continue or con done = true nofstored = nofstored - 1 end end elseif id == hlist_code or id == vlist_code then -- optional (but sometimes needed) - current.list, done = flushinline(current,current.list,done) + current.list, don, con = flushinline(current,current.list) + continue = continue or con + done = done or don end current = current.next end - return head, done + return head, done, continue end local function flushed(scope,parent) -- current is hlist - local done = false local head = parent.list - local room + local done = false + local continue = false + local room, con, don for c=1,#categories do local category = categories[c] for l=1,#locations do @@ -587,8 +654,9 @@ local function flushed(scope,parent) -- current is hlist while true do local candidate = remove(store,1) -- brr, local stores are sparse if candidate then -- no vpack, as we want to realign - head, room = inject(parent,head,candidate) -- maybe return applied offset + head, room, con = inject(parent,head,candidate) done = true + continue = continue or con nofstored = nofstored - 1 registertogether(parent,room) else @@ -601,13 +669,15 @@ local function flushed(scope,parent) -- current is hlist if done then parent.list = head end - head, done = flushinline(parent,head,false) + head, don, con = flushinline(parent,head) + continue = continue or con + done = done or don end if done then parent.list = hpack_nodes(head,parent.width,"exactly") - resetstacked() + -- resetstacked() end - return done + return done, continue end -- only when group : vbox|vmode_par @@ -623,8 +693,12 @@ local function handler(scope,head,group) while current do local id = current.id if (id == vlist_code or id == hlist_code) and not has_attribute(current,a_margindata) then - if flushed(scope,current) then + local don, continue = flushed(scope,current) + if don then set_attribute(current,a_margindata,0) -- signal to prevent duplicate processing + if continue then + markovershoot(current) + end if nofstored <= 0 then break end @@ -634,7 +708,7 @@ local function handler(scope,head,group) current = current.next end -- if done then - -- resetstacked() + resetstacked() -- why doesn't done work ok here? -- end return head, done else diff --git a/tex/context/base/typo-pag.lua b/tex/context/base/typo-pag.lua index 92c8e2c62..482a3a9f8 100644 --- a/tex/context/base/typo-pag.lua +++ b/tex/context/base/typo-pag.lua @@ -24,13 +24,15 @@ local points = number.points local a_keeptogether = attributes.private("keeptogether") -local trace_keeptogether = false trackers.register("parbuilders.keeptogether", function(v) trace_keeptogether = v end) +local trace_keeptogether = false local report_keeptogether = logs.reporter("parbuilders","keeptogether") local cache = { } local last = 0 local enabled = false +trackers.register("parbuilders.keeptogether", function(v) trace_keeptogether = v end) + -- todo: also support lines = 3 etc (e.g. dropped caps) but how to set that -- when no hlists are there ? ... maybe the local_par @@ -71,8 +73,17 @@ function builders.paragraphs.registertogether(line,specification) -- might chang local a = a or last local c = cache[a] if trace_keeptogether then - report_keeptogether("registered, index: %s, height: %s, depth: %s, slack: %s", - a,points(c.height),points(c.depth),points(c.slack)) + local noflines = specification.lineheight + local height = c.height + local depth = c.depth + local slack = c.slack + if not noflines or noflines == 0 then + noflines = "unknown" + else + noflines = math.round((height + depth - slack) / noflines) + end + report_keeptogether("registered, index: %s, height: %s, depth: %s, slack: %s, noflines: %s", + a,points(height),points(depth),points(slack),noflines) end end end diff --git a/tex/context/fonts/lm-math.lfg b/tex/context/fonts/lm-math.lfg index e6b64c638..a2c095bc2 100644 --- a/tex/context/fonts/lm-math.lfg +++ b/tex/context/fonts/lm-math.lfg @@ -1,3 +1,5 @@ +-- we could consider taking more from 'tex-mr-missing' + -- This patch code is moved from font-pat.lua to this goodies -- files as it does not belong in the core code. @@ -188,7 +190,7 @@ local ten = { local twelve = { { name = "lmroman12-regular.otf", features = "virtualmath", main = true }, - { name = "rm-lmr12.tfm", vector = "tex-mr-missing" } , + { name = "rm-lmr12.tfm", vector = "tex-mr-missing" }, { name = "lmmi12.tfm", vector = "tex-mi", skewchar=0x7F }, { name = "lmmi12.tfm", vector = "tex-it", skewchar=0x7F }, { name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } , diff --git a/tex/context/fonts/px-math.lfg b/tex/context/fonts/px-math.lfg index 1d18bad36..afb0270a2 100644 --- a/tex/context/fonts/px-math.lfg +++ b/tex/context/fonts/px-math.lfg @@ -11,6 +11,7 @@ return { virtuals = { ["px-math"] = { { name = "texgyrepagella-regular.otf", features = "virtualmath", main = true }, + { name = "texgyrepagella-regular.otf", features = "virtualmath", vector = "tex-mr-missing" } , { name = "rpxr.tfm", vector = "tex-mr" } , { name = "rpxmi.tfm", vector = "tex-mi", skewchar=0x7F }, { name = "rpxpplri.tfm", vector = "tex-it", skewchar=0x7F }, diff --git a/tex/context/fonts/tx-math.lfg b/tex/context/fonts/tx-math.lfg index 8423aaaf4..2ad173486 100644 --- a/tex/context/fonts/tx-math.lfg +++ b/tex/context/fonts/tx-math.lfg @@ -11,6 +11,7 @@ return { virtuals = { ["tx-math"] = { { name = "texgyretermes-regular.otf", features = "virtualmath", main = true }, + { name = "texgyretermes-regular.otf", features = "virtualmath", vector = "tex-mr-missing" }, { name = "rtxr.tfm", vector = "tex-mr" } , { name = "rtxptmri.tfm", vector = "tex-it", skewchar=0x7F }, { name = "rtxmi.tfm", vector = "tex-mi", skewchar=0x7F }, diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 928b9c2d5..8a951089c 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 11/12/11 12:34:20 +-- merge date : 11/13/11 23:53:45 do -- begin closure to overcome local limits and interference @@ -8892,11 +8892,11 @@ function handlers.gsub_single(start,kind,lookupname,replacement) return start, true end -local function set_alternative_glyph(start,alternatives,kind,chainname,chainlookupname,lookupname) -- chainname and chainlookupname optional +local function get_alternative_glyph(start,alternatives,value) -- needs checking: (global value, brrr) - local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue local choice = nil local n = #alternatives + local char = start.char -- if value == "random" then local r = random(1,n) @@ -8919,30 +8919,14 @@ local function set_alternative_glyph(start,alternatives,kind,chainname,chainlook value, choice = format("no %s variants, ignoring",value), false end elseif value == 0 then - value, choice = format("choice %s (no change)",value), start.char + value, choice = format("choice %s (no change)",value), char elseif value < 1 then value, choice = format("no %s variants, taking %s",value,1), alternatives[1] else value, choice = format("choice %s",value), alternatives[value] end end - if trace_alternatives then - if choice then - logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index) - else - logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char)) - end - end - if choice then - start.char = choice - if trace_alternatives then - logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index) - end - else - if trace_alternatives then - logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char)) - end - end + return choice end local function multiple_glyphs(start,multiple) -- marks ? @@ -8973,7 +8957,18 @@ local function multiple_glyphs(start,multiple) -- marks ? end function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence) - set_alternative_glyph(start,alternative,kind,lookupname) + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue + local choice = get_alternative_glyph(start,alternative,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(char),gref(choice),choice) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %s for %s",pref(kind,lookupname),tostring(value),gref(char)) + end + end return start, true end @@ -9574,6 +9569,7 @@ chainmores.gsub_multiple = chainprocs.gsub_multiple function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local current = start local subtables = currentlookup.subtables + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue while current do if current.id == glyph_code then -- is this check needed? local currentchar = current.char @@ -9586,7 +9582,17 @@ function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,look else alternatives = alternatives[currentchar] if alternatives then - set_alternative_glyph(current,alternatives,kind,chainname,chainlookupname,lookupname) + local choice = get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %s (%s)",cref(kind,chainname,chainlookupname,lookupname),gref(char),gref(choice),choice) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),tostring(value),gref(char)) + end + end elseif trace_bugs then logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar)) end -- cgit v1.2.3