diff options
| author | Hans Hagen <pragma@wxs.nl> | 2010-03-25 23:12:00 +0100 | 
|---|---|---|
| committer | Hans Hagen <pragma@wxs.nl> | 2010-03-25 23:12:00 +0100 | 
| commit | 41bb7ad440ec4b0d5c35e174792e3c4845313e7b (patch) | |
| tree | 28bbc2b1363523f632f6dcbc8bc096072f77f5de | |
| parent | 28351dce705d3546bc4a67b554ee474d2f3cce4a (diff) | |
| download | context-41bb7ad440ec4b0d5c35e174792e3c4845313e7b.tar.gz | |
beta 2010.03.25 23:12
27 files changed, 875 insertions, 266 deletions
diff --git a/tex/context/base/bibl-tra.mkiv b/tex/context/base/bibl-tra.mkiv index 7ea883e52..7b6fc84cb 100644 --- a/tex/context/base/bibl-tra.mkiv +++ b/tex/context/base/bibl-tra.mkiv @@ -306,15 +306,27 @@  \newif\ifbibcitecompress\bibcitecompresstrue -\appendtoks -  \processaction -    [\@@pbnumbering] -    [    \v!yes=>\let\@@pbinumbercommand\firstofoneargument, -          \v!no=>\let\@@pbinumbercommand\gobbleoneargument, -       \v!short=>\def\@@pbinumbercommand##1{\bibgetvars\currentpublicationkey}, -         \v!bib=>\def\@@pbinumbercommand##1{\bibgetvarn\currentpublicationkey}, -     \s!unknown=>\let\@@pbinumbercommand\firstofoneargument]% -\to \everysetuppublications +% \appendtoks +%   \processaction +%     [\@@pbnumbering] +%     [    \v!yes=>\let\@@pbinumbercommand\firstofoneargument, +%           \v!no=>\let\@@pbinumbercommand\gobbleoneargument, +%        \v!short=>\def\@@pbinumbercommand##1{\bibgetvars\currentpublicationkey}, +%          \v!bib=>\def\@@pbinumbercommand##1{\bibgetvarn\currentpublicationkey}, +%      \s!unknown=>\let\@@pbinumbercommand\firstofoneargument]% +% \to \everysetuppublications + +\def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument} + +\letvalue{\??pb:\c!numbercommand:\v!yes  }\firstofoneargument +\letvalue{\??pb:\c!numbercommand:\v!no   }\gobbleoneargument +\setvalue{\??pb:\c!numbercommand:\v!short}#1{\bibgetvars\currentpublicationkey} +\setvalue{\??pb:\c!numbercommand:\v!bib  }#1{\bibgetvarn\currentpublicationkey} + +% to be tested +% +% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibgetvars\currentpublicationkey\firstofoneargument} +% \setvalue{\??pb:\c!numbercommand:\v!bib  }{\bibgetvarn\currentpublicationkey\firstofoneargument}  \appendtoks    \processaction diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua index f7921f6fc..2ed91eb4b 100644 --- a/tex/context/base/char-def.lua +++ b/tex/context/base/char-def.lua @@ -887,7 +887,7 @@ characters.data={    direction="on",    linebreak="op",    mathclass="open", -  mathname="lbracket", +  mathname="lbrack",    mirror=0x005D,    unicodeslot=0x005B,   }, @@ -911,7 +911,7 @@ characters.data={    direction="on",    linebreak="cl",    mathclass="close", -  mathname="rbracket", +  mathname="rbrack",    mirror=0x005B,    unicodeslot=0x005D,   }, diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index 7299475d3..abee8fc9d 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -1837,7 +1837,7 @@ function resolvers.find_given_files(filename)      local hashes = instance.hashes      for k=1,#hashes do          local hash = hashes[k] -        local files = instance.files[hash.tag] +        local files = instance.files[hash.tag] or { }          local blist = files[bname]          if not blist then              local rname = "remap:"..bname diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua index e2fa3f290..558e2fc80 100644 --- a/tex/context/base/font-ota.lua +++ b/tex/context/base/font-ota.lua @@ -41,6 +41,8 @@ local insert_node_after  = node.insert_after  local insert_node_before = node.insert_before  local traverse_node_list = node.traverse +local new_glue_node      = nodes.glue +  local fontdata = fonts.ids  local state    = attributes.private('state') @@ -302,11 +304,12 @@ function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special ve      end      first, last = finish(first,last)      if removejoiners then +        -- is never head          for i=1,#joiners do -            head = delete_node(head,joiners[i]) +            delete_node(head,joiners[i])          end          for i=1,#nonjoiners do -            head = replace_node(head,nonjoiners[i],nodes.glue(0)) -- or maybe a kern +            replace_node(head,nonjoiners[i],new_glue_node(0)) -- or maybe a kern          end      end      return head, done diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index a91bd1d71..507235545 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -39,6 +39,7 @@ local format, lower, find, match, gsub, gmatch = string.format, string.lower, st  local texsprint, texbox = tex.sprint, tex.box  local contains = table.contains  local concat = table.concat +local todimen = string.todimen  local ctxcatcodes = tex.ctxcatcodes  local variables = interfaces.variables @@ -47,6 +48,7 @@ local trace_figures    = false  trackers.register("figures.locating",   function  local trace_bases      = false  trackers.register("figures.bases",      function(v) trace_bases      = v end)  local trace_programs   = false  trackers.register("figures.programs",   function(v) trace_programs   = v end)  local trace_conversion = false  trackers.register("figures.conversion", function(v) trace_conversion = v end) +local trace_inclusion  = false  trackers.register("figures.inclusion",  function(v) trace_inclusion  = v end)  --- some extra img functions --- @@ -794,22 +796,29 @@ end  function figures.checkers.mov(data)      local dr, du, ds = data.request, data.used, data.status -    dr.width = (dr.width or figures.defaultwidth):todimen() -    dr.height = (dr.height or figures.defaultheight):todimen() -    du.width = dr.width -    du.height = dr.height -    du.foundname = du.fullname -    local code = backends.codeinjections.insertmovie { -        width      = du.width or dr.width, -        height     = du.height or dr.height, -        factor     = number.dimenfactors.bp, -        ["repeat"] = dr["repeat"], -        controls   = dr.controls, -        preview    = dr.preview, -        label      = dr.label, -        foundname  = du.foundname, -    } -    texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}%s\\stopfoundexternalfigure",du.width,du.height,code)) +    local width = todimen(dr.width or figures.defaultwidth) +    local height = todimen(dr.height or figures.defaultheight) +    local foundname = du.fullname +    dr.width, dr.height = width, height +    du.width, du.height, du.foundname = width, height, foundname +    if trace_inclusion then +        logs.report("figures","including movie '%s': width %s, height %s",foundname,width,height) +    end +    -- we need to push the node.write in between ... we could make a shared helper for this +    context.startfoundexternalfigure(width .. "sp",height .. "sp") +    context(function() +        backends.codeinjections.insertmovie { +            width      = width, +            height     = height, +            factor     = number.dimenfactors.bp, +            ["repeat"] = dr["repeat"], +            controls   = dr.controls, +            preview    = dr.preview, +            label      = dr.label, +            foundname  = foundname, +        } +    end) +    context.stopfoundexternalfigure()      return data  end diff --git a/tex/context/base/grph-u3d.lua b/tex/context/base/grph-u3d.lua index 3b1d8365d..f3bf17631 100644 --- a/tex/context/base/grph-u3d.lua +++ b/tex/context/base/grph-u3d.lua @@ -8,35 +8,38 @@ if not modules then modules = { } end modules ['grph-u3d'] = {  -- see lpdf-u3d.lua for comment -local format = string.format +local trace_inclusion = false  trackers.register("figures.inclusion",  function(v) trace_inclusion = v end) -local texsprint     = tex.sprint -local ctxcatcodes   = tex.ctxcatcodes -local pdfannotation = nodes.pdfannotation +local pdfannotation   = nodes.pdfannotation +local todimen         = string.todimen + +-- maybe todo: backends.codeinjections.insertu3d  function figures.checkers.u3d(data)      local dr, du, ds = data.request, data.used, data.status -    local width = (dr.width or figures.defaultwidth):todimen() -    local height = (dr.height or figures.defaultheight):todimen() +    local width = todimen(dr.width or figures.defaultwidth) +    local height = todimen(dr.height or figures.defaultheight)      local foundname = du.fullname      dr.width, dr.height = width, height      du.width, du.height, du.foundname = width, height, foundname -    texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}",width,height)) -    local annot, preview, ref = backends.pdf.helpers.insert3d { -        foundname = foundname, -        width     = width, -        height    = height, -        factor    = number.dimenfactors.bp, -        display   = dr.display, -        controls  = dr.controls, -        label     = dr.label, -    } - -- node.write(pdfannotation(width,-height,0,annot())) -    texsprint(ctxcatcodes,format("\\pdfannot width %ssp height %ssp {%s}",width,height,annot())) -- brrrr ---~     if ref then -- wrong ! a direct ref should work ---~         texsprint(ctxcatcodes,format("\\smash{\\pdfrefximage%s\\relax}",ref)) -- brrrr ---~     end -    texsprint(ctxcatcodes,"\\stopfoundexternalfigure") +    if trace_inclusion then +        logs.report("figures","including u3d '%s': width %s, height %s",foundname,width,height) +    end +    context.startfoundexternalfigure(width .. "sp",height .. "sp") +    context(function() +        local annotation, preview, ref = backends.pdf.helpers.insert3d { +            foundname = foundname, +            width     = width, +            height    = height, +            factor    = number.dimenfactors.bp, +            display   = dr.display, +            controls  = dr.controls, +            label     = dr.label, +        } +--~         print(annotation, preview, ref) +        node.write(pdfannotation(width,height,0,annotation())) +    end) +    context.stopfoundexternalfigure()      return data  end diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua index a8faa270b..b14a1fa54 100644 --- a/tex/context/base/l-dimen.lua +++ b/tex/context/base/l-dimen.lua @@ -128,9 +128,9 @@ capture takes place.</p>  local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0")  local unit   = R("az")^1 -local pattern = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new +local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new -lpeg.patterns.dimenpair = pattern +lpeg.patterns.dimenpair = dimenpair  --[[ldx--  <p>We use a metatable to intercept errors. When no key is found in @@ -149,7 +149,7 @@ function string:todimen()      if type(self) == "number" then          return self      else -        local value, unit = lpegmatch(pattern,self) +        local value, unit = lpegmatch(dimenpair,self)          return value/unit      end  end @@ -158,7 +158,7 @@ local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0  local unit   = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in")  +                 P("pc") + P("dd") + P("cc") + P("nd") + P("nc") -local pattern = amount * unit +local validdimen = amount * unit  lpeg.patterns.validdimen = pattern @@ -166,12 +166,12 @@ lpeg.patterns.validdimen = pattern  <p>This converter accepts calls like:</p>  <typing> -string.todimen("10")) -string.todimen(".10")) -string.todimen("10.0")) -string.todimen("10.0pt")) -string.todimen("10pt")) -string.todimen("10.0pt")) +string.todimen("10") +string.todimen(".10") +string.todimen("10.0") +string.todimen("10.0pt") +string.todimen("10pt") +string.todimen("10.0pt")  </typing>  <p>And of course the often more efficient:</p> @@ -371,7 +371,7 @@ function dimen(a)              if k then                  a = k              else -                local value, unit = lpegmatch(pattern,a) +                local value, unit = lpegmatch(dimenpair,a)                  if type(unit) == "function" then                      k = value/unit()                  else @@ -395,7 +395,7 @@ function string:todimen()      else          local k = known[self]          if not k then -            local value, unit = lpegmatch(pattern,self) +            local value, unit = lpegmatch(dimenpair,self)              if value and unit then                  k = value/unit              else diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index 3d5a9ba3c..61eceb168 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -483,6 +483,10 @@ end  function lpdf.finalizedocument()      if not environment.initex then          run(documentfinalizers,"document") +        function lpdf.finalizedocument() +            logs.report("backend","serious error: the document is finalized multiple times") +            function lpdf.finalizedocument() end +        end      end  end diff --git a/tex/context/base/math-lan.mkiv b/tex/context/base/math-lan.mkiv index bcf9cdc13..1d3132578 100644 --- a/tex/context/base/math-lan.mkiv +++ b/tex/context/base/math-lan.mkiv @@ -61,4 +61,7 @@  \setupmathlabeltext [\s!pl] [arctg=arc\,tg]  \setupmathlabeltext [\s!pl] [arcctg=arc\,ctg] +\setupmathlabeltext [\s!nl] [gcd=ggd] +\setupmathlabeltext [\s!nl] [lcm=kgv] +  \protect \endinput diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua index 372fd858d..1d1542ab7 100644 --- a/tex/context/base/mult-cld.lua +++ b/tex/context/base/mult-cld.lua @@ -59,52 +59,53 @@ trackers.register("context.flush",     function(v) if v then context.trace()  trackers.register("context.intercept", function(v) if v then context.trace(true) end end)  local function writer(k,...) -    flush(ctxcatcodes,k) -    local t = { ... } -    local nt = #t -    if nt > 0 then -        for i=1,nt do -            local ti = t[i] -            local typ = type(ti) -            if ti == nil then -                -- next -            elseif typ == "function" then -                flush(ctxcatcodes,"{\\mkivflush{" .. _store_(ti) .. "}}") -            elseif typ == "string" or typ == "number" then -                flush(ctxcatcodes,"{",ti,"}") -            elseif typ == "table" then -                local c = concat(ti,",") -                if c ~= "" then -                    flush(ctxcatcodes,"[",c,"]") -                else -                    flush(ctxcatcodes,"[") -                    local done = false -                    for k, v in next, ti do -                        if done then -                            flush(ctxcatcodes,",",k,'=',v) -                        else -                            flush(ctxcatcodes,k,'=',v) -                            done = true +    if k then +        flush(ctxcatcodes,k) +        local t = { ... } +        local nt = #t +        if nt > 0 then +            for i=1,nt do +                local ti = t[i] +                local typ = type(ti) +                if ti == nil then +                    -- next +                elseif typ == "function" then +                    flush(ctxcatcodes,"{\\mkivflush{" .. _store_(ti) .. "}}") +                elseif typ == "string" or typ == "number" then +                    flush(ctxcatcodes,"{",ti,"}") +                elseif typ == "table" then +                    local c = concat(ti,",") +                    if c ~= "" then +                        flush(ctxcatcodes,"[",c,"]") +                    else +                        flush(ctxcatcodes,"[") +                        local done = false +                        for k, v in next, ti do +                            if done then +                                flush(ctxcatcodes,",",k,'=',v) +                            else +                                flush(ctxcatcodes,k,'=',v) +                                done = true +                            end                          end +                        flush(ctxcatcodes,"]")                      end -                    flush(ctxcatcodes,"]") +            --  elseif typ == "boolean" then +            --      flush(ctxcatcodes,"\n") +                elseif ti == true then +                    flush(ctxcatcodes,"\n") +                elseif typ == false then +                --  if force == "direct" then +                    flush(ctxcatcodes,tostring(ti)) +                --  end +                else +                    logs.report("interfaces","error: %s gets a weird argument %s",k,tostring(ti))                  end -        --  elseif typ == "boolean" then -        --      flush(ctxcatcodes,"\n") -            elseif ti == true then -                flush(ctxcatcodes,"\n") -            elseif typ == false then -            --  if force == "direct" then -                flush(ctxcatcodes,tostring(ti)) -            --  end -            else -                logs.report("interfaces","error: %s gets a weird argument %s",k,tostring(ti))              end          end      end  end -  -- -- --  --~ local function indexer(t,k) @@ -131,6 +132,8 @@ end  local function caller(t,f,a,...)      if a then          flush(ctxcatcodes,format(f,a,...)) +    elseif type(f) == "function" then +        flush(ctxcatcodes,"{\\mkivflush{" .. _store_(f) .. "}}")      elseif f then          flush(ctxcatcodes,f)      else diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua index 2dbc974a1..20996a65e 100644 --- a/tex/context/base/node-aux.lua +++ b/tex/context/base/node-aux.lua @@ -67,7 +67,7 @@ end  --         or  id == mark_node  --         or  id == adjust_node  --         or  id == penalty_node ---         or (id == glue_node    and a.spec == 0) +--         or (id == glue_node    and a.spec.writable)  --         or (id == disc_node    and a.pre == nil and a.post == nil and a.replace == nil)  --         or (id == math_node    and a.surround == 0)  --         or (id == kern_node    and (a.kern == 0 or a.subtype == NORMAL)) @@ -112,3 +112,34 @@ end  --         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 +--         logs.error("parbuilder",'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 + diff --git a/tex/context/base/node-dir.lua b/tex/context/base/node-dir.lua new file mode 100644 index 000000000..225d2448a --- /dev/null +++ b/tex/context/base/node-dir.lua @@ -0,0 +1,308 @@ +if not modules then modules = { } end modules ['node-mir'] = { +    version   = 1.001, +    comment   = "companion to node-ini.mkiv", +    author    = "Taco Hoekwater and Hans Hagen", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +--[[ +<p>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. +]]-- + + +nodes = nodes or { } + +nodes.is_mirrored = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, +} + +nodes.is_rotated = { + -- TLT = false, + -- TRT = false, + -- LTL = false, +    RTT = true, ["+RTT"] = true, +} + +nodes.textdir_is_parallel = { +    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 = { +    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 = { +    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= { +    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 = { +    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_eq = { +    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_eq = { +    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_eq = { +    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_eq = { +    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 = { +    TLT = true, ["+TLT"] = true, + -- TRT = false, + -- LTL = false, + -- RTT = false, +} + +nodes.glyphdir_is_orthogonal = { +    TLT = true, ["+TLT"] = true, +    TRT = true, ["+TRT"] = true, +    LTL = true, ["+LTL"] = true, + -- RTT = false +} + +nodes.dir_is_pop = { +    ["-TRT"] = true, +    ["-TLT"] = true, +    ["-LTL"] = true, +    ["-RTT"] = true, +} + +nodes.dir_negation = { +    ["-TRT"] = "+TRT", +    ["-TLT"] = "+TLT", +    ["-LTL"] = "+LTL", +    ["-RTT"] = "+RTT", +    ["+TRT"] = "-TRT", +    ["+TLT"] = "-TLT", +    ["+LTL"] = "-LTL", +    ["+RTT"] = "-RTT", +} diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua index e21fc70e4..36e240238 100644 --- a/tex/context/base/node-ini.lua +++ b/tex/context/base/node-ini.lua @@ -108,10 +108,12 @@ local penalty = node.id('penalty')  local kern    = node.id('kern')  local whatsit = node.id('whatsit') -local traverse_id = node.traverse_id -local traverse    = node.traverse -local free_node   = node.free -local remove_node = node.remove +local traverse_id        = node.traverse_id +local traverse           = node.traverse +local free_node          = node.free +local remove_node        = node.remove +local insert_node_before = node.insert_before +local insert_node_after  = node.insert_after  function nodes.remove(head, current, free_too)     local t = current @@ -131,8 +133,8 @@ function nodes.delete(head,current)      return nodes.remove(head,current,true)  end -nodes.before = node.insert_before -nodes.after  = node.insert_after +nodes.before = insert_node_before +nodes.after  = insert_node_after  -- we need to test this, as it might be fixed now @@ -172,21 +174,31 @@ function nodes.after(h,c,n)      return n, n  end -function nodes.replace(head,current,new) -    if current and next then -        local p, n = current.prev, current.next -        new.prev, new.next = p, n -        if p then -            p.next = new -        else +-- local h, c = nodes.replace(head,current,new) +-- local c = nodes.replace(false,current,new) +-- local c = nodes.replace(current,new) + +function nodes.replace(head,current,new) -- no head returned if false +    if not new then +        head, current, new = false, head, current +    end +    local prev, next = current.prev, current.next +    if next then +        new.next, next.prev = next, new +    end +    if prev then +        new.prev, prev.next = prev, new +    end +    if head then +        if head == current then              head = new          end -        if n then -            n.prev = new -        end          free_node(current) +        return head, new +    else +        free_node(current) +        return new      end -    return head, current  end  -- will move diff --git a/tex/context/base/node-par.lua b/tex/context/base/node-par.lua index a8ad969fe..8c6ab2c34 100644 --- a/tex/context/base/node-par.lua +++ b/tex/context/base/node-par.lua @@ -45,7 +45,13 @@ function parbuilders.constructor(head,followed_by_display)          if attribute then              local constructor = names[attribute]              if constructor then -                return constructors[constructor](head,followed_by_display) +                local handler = constructor and constructors[constructor] +                if handler then +                    return handler(head,followed_by_display) +                else +                    logs.report("parbuilders","handler '%s' is not defined",tostring(constructor)) +                    return true -- let tex break +                end              end          end          return true -- let tex break diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 198a810ff..7128b1a6d 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -127,10 +127,10 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir)                      if prev and prev.id == glue and prev.subtype == 15 then                          width = dimensions(current,first,prev.prev) -- maybe not current as we already take care of it                      else -                        if moveright and first.spec then +                        if moveright and first.writable then                              width = width - first.spec.stretch*current.glue_set * current.glue_sign                          end -                        if last.spec then +                        if last.writable then                              width = width - last.spec.stretch*current.glue_set * current.glue_sign                          end                      end diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua index f30f6db1e..2657dfa1e 100644 --- a/tex/context/base/node-res.lua +++ b/tex/context/base/node-res.lua @@ -7,7 +7,10 @@ if not modules then modules = { } end modules ['node-res'] = {  }  local gmatch, format = string.gmatch, string.format -local copy_node, free_node, free_list, new_node = node.copy, node.free, node.flush_list, node.new +local copy_node, free_node, free_list, new_node, node_type, node_id = node.copy, node.free, node.flush_list, node.new, node.type, node.id +local tonumber, round = tonumber, math.round + +local glyph_node = node_id("glyph")  --[[ldx--  <p>The next function is not that much needed but in <l n='context'/> we use @@ -25,16 +28,21 @@ for k, v in pairs(node.whatsits()) do      whatsits[k], whatsits[v] = v, k -- two way  end -function nodes.register(n) +local function register_node(n)      reserved[#reserved+1] = n      return n  end +nodes.register = register_node +  function nodes.cleanup_reserved(nofboxes) -- todo      nodes.tracers.steppers.reset() -- todo: make a registration subsystem      local nr, nl = #reserved, 0      for i=1,nr do -        free_node(reserved[i]) +        local ri = reserved[i] +    --  if not (ri.id == glue_spec and not ri.is_writable) then +            free_node(reserved[i]) +    --  end      end      if nofboxes then          local tb = tex.box @@ -58,19 +66,37 @@ function nodes.usage()      return t  end -local disc       = nodes.register(new_node("disc")) -local kern       = nodes.register(new_node("kern",1)) -local penalty    = nodes.register(new_node("penalty")) -local glue       = nodes.register(new_node("glue")) -local glue_spec  = nodes.register(new_node("glue_spec")) -local glyph      = nodes.register(new_node("glyph",0)) -local textdir    = nodes.register(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) -local rule       = nodes.register(new_node("rule")) -local latelua    = nodes.register(new_node("whatsit",whatsits.late_lua)) -- 35 -local user_n     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 -local user_l     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 -local user_s     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 -local user_t     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local disc              = register_node(new_node("disc")) +local kern              = register_node(new_node("kern",1)) +local penalty           = register_node(new_node("penalty")) +local glue              = register_node(new_node("glue")) -- glue.spec = nil +local glue_spec         = register_node(new_node("glue_spec")) +local glyph             = register_node(new_node("glyph",0)) +local textdir           = register_node(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) +local rule              = register_node(new_node("rule")) +local latelua           = register_node(new_node("whatsit",whatsits.late_lua)) -- 35 +local user_n            = register_node(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 +local user_l            = register_node(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 +local user_s            = register_node(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 +local user_t            = register_node(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local left_margin_kern  = register_node(new_node("margin_kern",0)) +local right_margin_kern = register_node(new_node("margin_kern",1)) +local lineskip          = register_node(new_node("glue",1)) +local baselineskip      = register_node(new_node("glue",2)) +local leftskip          = register_node(new_node("glue",8)) +local rightskip         = register_node(new_node("glue",9)) +local temp              = register_node(new_node("temp",0)) + +function nodes.zeroglue(n) +    local s = n.spec +    return not writable or ( +                     s.width == 0 +         and       s.stretch == 0 +         and        s.shrink == 0 +         and s.stretch_order == 0 +         and  s.shrink_order == 0 +        ) +end  function nodes.glyph(fnt,chr)      local n = copy_node(glyph) @@ -78,48 +104,114 @@ function nodes.glyph(fnt,chr)      if chr then n.char = chr end      return n  end +  function nodes.penalty(p)      local n = copy_node(penalty)      n.penalty = p      return n  end +  function nodes.kern(k)      local n = copy_node(kern)      n.kern = k      return n  end -function nodes.glue(width,stretch,shrink) -    local n, s = copy_node(glue), copy_node(glue_spec) -    s.width, s.stretch, s.shrink = width, stretch, shrink -    n.spec = s -    return n -end +  function nodes.glue_spec(width,stretch,shrink)      local s = copy_node(glue_spec)      s.width, s.stretch, s.shrink = width, stretch, shrink      return s  end + +local function someskip(skip,width,stretch,shrink) +    local n = copy_node(skip) +    if not width then +        -- no spec +    elseif tonumber(width) then +        local s = copy_node(glue_spec) +        s.width, s.stretch, s.shrink = width, stretch, shrink +        n.spec = s +    else +        -- shared +        n.spec = copy_node(width) +    end +    return n +end + +function nodes.glue(width,stretch,shrink) +    return someskip(glue,width,stretch,shrink) +end +function nodes.leftskip(width,stretch,shrink) +    return someskip(leftskip,width,stretch,shrink) +end +function nodes.rightskip(width,stretch,shrink) +    return someskip(rightskip,width,stretch,shrink) +end +function nodes.lineskip(width,stretch,shrink) +    return someskip(lineskip,width,stretch,shrink) +end +function nodes.baselineskip(width,stretch,shrink) +    return someskip(baselineskip,width,stretch,shrink) +end +  function nodes.disc()      return copy_node(disc)  end +  function nodes.textdir(dir)      local t = copy_node(textdir)      t.dir = dir      return t  end -function nodes.rule(w,h,d) + +function nodes.rule(width,height,depth,dir)      local n = copy_node(rule) -    if w then n.width  = w end -    if h then n.height = h end -    if d then n.depth  = d end +    if width  then n.width  = width  end +    if height then n.height = height end +    if depth  then n.depth  = depth  end +    if dir    then n.dir    = dir    end      return n  end +  function nodes.latelua(code)      local n = copy_node(latelua)      n.data = code      return n  end +function nodes.leftmarginkern(glyph,width) +    local n = copy_node(left_margin_kern) +    if not glyph then +        logs.fatal("nodes","invalid pointer to left margin glyph node") +    elseif glyph.id ~= glyph_node then +        logs.fatal("nodes","invalid node type %s for left margin glyph node",node_type(glyph)) +    else +        n.glyph = glyph +    end +    if width then +        n.width = width +    end +    return n +end + +function nodes.rightmarginkern(glyph,width) +    local n = copy_node(right_margin_kern) +    if not glyph then +        logs.fatal("nodes","invalid pointer to right margin glyph node") +    elseif glyph.id ~= glyph_node then +        logs.fatal("nodes","invalid node type %s for right margin glyph node",node_type(p)) +    else +        n.glyph = glyph +    end +    if width then +        n.width = width +    end +    return n +end + +function nodes.temp() +    return copy_node(temp) +end  --[[  <p>At some point we ran into a problem that the glue specification  of the zeropoint dimension was overwritten when adapting a glue spec diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua index 17b7c7658..0ecb7107c 100644 --- a/tex/context/base/node-rul.lua +++ b/tex/context/base/node-rul.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['node-rul'] = {  }  -- this will go to an auxiliary module +-- beware: rules now have a dir field  local glyph = node.id("glyph")  local disc  = node.id("disc") @@ -85,7 +86,7 @@ local checkdir = true  -- we assume {glyphruns} and no funny extra kerning, ok, maybe we need  -- a dummy character as start and end; anyway we only collect glyphs -local function process_words(attribute,data,flush,head,parent) +local function process_words(attribute,data,flush,head,parent) -- we have hlistdir and local dir      local n = head      if n then          local f, l, a, d, i, level @@ -215,7 +216,9 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a              insert_after(head,r,k)          end          if trace_ruled then -            logs.report("ruled", "level: %s, width: %s, nodes: %s, text: %s",level,w,n_tostring(f,l),n_tosequence(f,l,true)) +            logs.report("ruled", "level: %s, width: %i, height: %i, depth: %i, nodes: %s, text: %s", +                level,w,ht,dp,n_tostring(f,l),n_tosequence(f,l,true)) +             -- level,r.width,r.height,r.depth,n_tostring(f,l),n_tosequence(f,l,true))          end      end      return head diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua index 1798da771..50b16efa5 100644 --- a/tex/context/base/node-shp.lua +++ b/tex/context/base/node-shp.lua @@ -20,7 +20,7 @@ local function cleanup_page(head) -- rough      local start = head      while start do          local id = start.id -        if id == disc or (id == glue and not start.spec) or (id == kern and start.kern == 0) or id == mark then +        if id == disc or (id == glue and not start.writable) or (id == kern and start.kern == 0) or id == mark then              head, start, tmp = remove_node(head,start)              free_node(tmp)          elseif id == hlist or id == vlist then diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 83340331b..d293fdeb1 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -31,6 +31,7 @@ local vlist   = node.id('vlist')  local disc    = node.id('disc')  local glue    = node.id('glue')  local kern    = node.id('kern') +local rule    = node.id('rule')  local whatsit = node.id('whatsit')  local copy_node_list  = node.copy_list @@ -347,6 +348,12 @@ function nodes.tosequence(start,stop,compact)                  end              elseif id == whatsit and start.subtype == 6 or start.subtype == 7 then                  t[#t+1] = "[" .. start.dir .. "]" +            elseif id == rule then +                if compact then +                    t[#t+1] = "|" +                else +                    t[#t+1] = node_type(id) +                end              else                  if compact then                      t[#t+1] = "[]" diff --git a/tex/context/base/node-tst.lua b/tex/context/base/node-tst.lua index b8154d9d6..d7ea96f26 100644 --- a/tex/context/base/node-tst.lua +++ b/tex/context/base/node-tst.lua @@ -17,12 +17,12 @@ local find_node_tail = node.tail or node.slide  local chardata = characters.data -function nodes.leftskip(n) +function nodes.the_left_margin(n) -- todo: three values      while n do          local id = n.id          if id == glue then              if n.subtype == 8 then -- 7 in c/web source -                return (n.spec and n.spec.width) or 0 +                return n.spec.width              else                  return 0              end @@ -37,14 +37,14 @@ function nodes.leftskip(n)      return 0  end -function nodes.rightskip(n) +function nodes.the_right_margin(n)      if n then          n = find_node_tail(n)          while n do              local id = n.id              if id == glue then                  if n.subtype == 9 then -- 8 in the c/web source -                    return (n.spec and n.spec.width) or 0 +                    return n.spec.width                  else                      return 0                  end diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua index 444210428..b090dd4a2 100644 --- a/tex/context/base/page-lin.lua +++ b/tex/context/base/page-lin.lua @@ -138,7 +138,7 @@ function nodes.lines.boxed.setup(n,configuration)      return n  end -local leftskip = nodes.leftskip +local the_left_margin = nodes.the_left_margin  local function check_number(n,a,skip) -- move inline      local d = data[a] @@ -147,7 +147,7 @@ local function check_number(n,a,skip) -- move inline          current_list[#current_list+1] = { n, s }          if not skip and s % d.step == 0 then              local tag = d.tag or "" -            texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}\\endgraf", tag, s, n.shift, n.width, leftskip(n.list))) +            texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}\\endgraf", tag, s, n.shift, n.width, the_left_margin(n.list)))              if trace_numbers then                  logs.report("numbers","making number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")              end diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua index e84c81397..ab04077e8 100644 --- a/tex/context/base/sort-lan.lua +++ b/tex/context/base/sort-lan.lua @@ -154,7 +154,7 @@ sorters.mappings['cz'] = {      ['w']        = 36, -- w      ['x']        = 37, -- x      ['y']        = 38, -- y -    ['z']        = 49, -- z +    ['z']        = 39, -- z      [uc(0x017E)] = 40, -- zcaron  } diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 5acfd7dbb..9d4b8ac18 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -242,14 +242,24 @@ local function snap_hlist(current,method,height,depth) -- method.strut is defaul      return h, d, ch, cd, (ch+cd)/snaphtdp  end +--~ local function snap_topskip(current,method) +--~     local spec = current.spec +--~     local w = spec.width +--~     local wd = w +--~     if spec then +--~         wd = 0 +--~         spec = writable_spec(current) +--~         spec.width = wd +--~     end +--~     return w, wd +--~ end +  local function snap_topskip(current,method)      local spec = current.spec      local w = spec.width      local wd = w -    if spec then -        wd = 0 -        spec = writable_spec(current) -        spec.width = wd +    if spec.writable then +        spec.width, wd = 0, 0      end      return w, wd  end @@ -397,23 +407,19 @@ local trace_list, tracing_info, before, after = { }, false, "", ""  local function glue_to_string(glue)      local spec = glue.spec -    if spec then -        local t = { } -        t[#t+1] = aux.strip_zeros(number.topoints(spec.width)) -        if spec.stretch_order and spec.stretch_order ~= 0 then -            t[#t+1] = format("plus -%sfi%s",spec.stretch/65536,string.rep("l",math.abs(spec.stretch_order)-1)) -        elseif spec.stretch and spec.stretch ~= 0 then -            t[#t+1] = format("plus %s",aux.strip_zeros(number.topoints(spec.stretch))) -        end -        if spec.shrink_order and spec.shrink_order ~= 0 then -            t[#t+1] = format("minus -%sfi%s",spec.shrink/65536,string.rep("l",math.abs(spec.shrink_order)-1)) -        elseif spec.shrink and spec.shrink ~= 0 then -            t[#t+1] = format("minus %s",aux.strip_zeros(number.topoints(spec.shrink))) -        end -        return concat(t," ") -    else -        return "[0pt]" +    local t = { } +    t[#t+1] = aux.strip_zeros(number.topoints(spec.width)) +    if spec.stretch_order and spec.stretch_order ~= 0 then +        t[#t+1] = format("plus -%sfi%s",spec.stretch/65536,string.rep("l",math.abs(spec.stretch_order)-1)) +    elseif spec.stretch and spec.stretch ~= 0 then +        t[#t+1] = format("plus %s",aux.strip_zeros(number.topoints(spec.stretch))) +    end +    if spec.shrink_order and spec.shrink_order ~= 0 then +        t[#t+1] = format("minus -%sfi%s",spec.shrink/65536,string.rep("l",math.abs(spec.shrink_order)-1)) +    elseif spec.shrink and spec.shrink ~= 0 then +        t[#t+1] = format("minus %s",aux.strip_zeros(number.topoints(spec.shrink)))      end +    return concat(t," ")  end  local function nodes_to_string(head) @@ -424,11 +430,7 @@ local function nodes_to_string(head)          if id == penalty then              t[#t+1] = format("%s:%s",ty,current.penalty)          elseif id == glue then -            if current.spec then -                t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width))) -            else -                t[#t+1] = format("%s:[0pt]",ty) -            end +            t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width)))          elseif id == kern then              t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.kern)))          else @@ -537,9 +539,10 @@ local skips = {  }  local free_glue_node = free_node -local free_glue_spec = free_node  local discard, largest, force, penalty, add, disable, nowhite, goback, together = 0, 1, 2, 3, 4, 5, 6, 7, 8 +--~ local function free_glue_node(n) free_node(n.spec) free_node(n) end +  function vspacing.snap_box(n,how)      local sv = snapmethods[how]      if sv then @@ -602,10 +605,9 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail          if glue_data then              if force_glue then                  if trace then trace_done("flushed due to " .. why,glue_data) end -                local spec = glue_data.spec -                head, _ = forced_skip(head,current,(spec and spec.width) or 0,"before",trace) +                head, _ = forced_skip(head,current,glue_data.spec.width,"before",trace)                  free_glue_node(glue_data) -            elseif glue_data.spec then +            elseif glue_data.spec.writable then                  if trace then trace_done("flushed due to " .. why,glue_data) end                  head, _ = insert_node_before(head,current,glue_data)              else @@ -693,12 +695,12 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail                      local previous = current.prev                      if previous and previous.id == glue and previous.subtype == 0 then                          local ps = previous.spec -                        if ps then +                        if ps.writable then                              local cs = current.spec -                            if cs and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then +                            if cs.writable and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then                                  local pw, pp, pm = ps.width, ps.stretch, ps.shrink                                  local cw, cp, cm = cs.width, cs.stretch, cs.shrink -                                ps = writable_spec(previous) +                                ps = writable_spec(previous) -- no writable needed here                                  ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm                                  if trace then trace_natural("removed",current) end                                  head, current = remove_node(head, current, true) @@ -749,8 +751,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail                  -- is now exclusive, maybe support goback as combi, else why a set                  if sc == largest then                      local cs, gs = current.spec, glue_data.spec -                    local cw = (cs and cs.width) or 0 -                    local gw = (gs and gs.width) or 0 +                    local cw, gw = cs.width, gs.width                      if cw > gw then                          if trace then trace_skip('largest',sc,so,sp,current) end                          free_glue_node(glue_data) -- also free spec @@ -800,9 +801,8 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail                  local s = has_attribute(current,snap_method)                  if s and s ~= 0 then                      set_attribute(current,snap_method,0) -                    local spec = current.spec -                    if spec then -                        spec = writable_spec(current) +                    if current.spec.writable then +                        local spec = writable_spec(current)                          spec.width = 0                          if trace_vsnapping then                              logs.report("snapper", "lineskip set to zero") @@ -822,8 +822,8 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail                  local s = has_attribute(current,snap_method)                  if s and s ~= 0 then                      set_attribute(current,snap_method,0) -                    local spec = current.spec -                    if spec then +                    if current.spec.writable then +                        local spec = writable_spec(current)                          spec.width = 0                          if trace_vsnapping then                              logs.report("snapper", "baselineskip set to zero") @@ -845,7 +845,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail                  head, current = remove_node(head, current, true)              elseif glue_data then                  local ps, gs = current.spec, glue_data.spec -                if ps and gs and ps.width > gs.width then +                if ps.writable and gs.writable and ps.width > gs.width then                      glue_data.spec = copy_node(ps)                      if trace then trace_natural("taking parskip",current) end                  else @@ -900,7 +900,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail              current = current.next              --          else -- other glue -            if snap and trace_vsnapping and current.spec and current.spec.width ~= 0 then +            if snap and trace_vsnapping and current.spec.writable and current.spec.width ~= 0 then                  logs.report("snapper", "%s of %s (kept)",skips[subtype],current.spec.width)              --~ current.spec.width = 0              end diff --git a/tex/context/base/tabl-ntb.mkii b/tex/context/base/tabl-ntb.mkii index 1f9a9d574..0bfcc20c6 100644 --- a/tex/context/base/tabl-ntb.mkii +++ b/tex/context/base/tabl-ntb.mkii @@ -1213,6 +1213,7 @@         \fi          \advance\xxrowTBL\plusone}%       % distribute overshoot equally +\ifdim\dimen2>\zeropoint % see natural-003       \ifdim\dimen4<\dimen0         \advance\dimen0 -\dimen4         \divide\dimen0 \!!countb @@ -1231,6 +1232,7 @@       \else\ifdim\dimen4>\dimen0         \settblhei\xrowTBL{\the\dimen2}%       \fi\fi +\fi     \fi}  \def\checktblheightsone diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index 796c09546..b2ac83aa5 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -1237,26 +1237,28 @@         \fi          \advance\xxrowTBL\plusone}%       % distribute overshoot equally -     \ifdim\dimen4<\dimen0 -       \advance\dimen0 -\dimen4 -       \divide\dimen0 \!!countb -       \xxrowTBL\xrowTBL -       \settblhei\xrowTBL{\the\dimen2}% -       \dorecurse\!!countb -         {\dorecurse\maximumcol -            {\ifnum\recurselevel=\xcolTBL\else -               \scratchdimen\dimexpr\gettblht\xxrowTBL\recurselevel+\dimen0\relax -               \settblht\xxrowTBL\recurselevel{\the\scratchdimen}% -               \ifdim\gettblhei\xxrowTBL<\scratchdimen -                 \settblhei\xxrowTBL{\the\scratchdimen}% -               \fi -             \fi}% -          \advance\xxrowTBL\plusone}% -     \else\ifdim\dimen4>\dimen0 -        \iftightTBLrowspan -          \settblhei\xrowTBL{\the\dimen2}% -        \fi -     \fi\fi +     \ifdim\dimen2>\zeropoint % new: test on natural-003 +       \ifdim\dimen4<\dimen0 +         \advance\dimen0 -\dimen4 +         \divide\dimen0 \!!countb +         \xxrowTBL\xrowTBL +         \settblhei\xrowTBL{\the\dimen2}% +         \dorecurse\!!countb +           {\dorecurse\maximumcol +              {\ifnum\recurselevel=\xcolTBL\else +                 \scratchdimen\dimexpr\gettblht\xxrowTBL\recurselevel+\dimen0\relax +                 \settblht\xxrowTBL\recurselevel{\the\scratchdimen}% +                 \ifdim\gettblhei\xxrowTBL<\scratchdimen +                   \settblhei\xxrowTBL{\the\scratchdimen}% +                 \fi +               \fi}% +            \advance\xxrowTBL\plusone}% +       \else\ifdim\dimen4>\dimen0 +         \iftightTBLrowspan +           \settblhei\xrowTBL{\the\dimen2}% +         \fi +       \fi\fi +     \fi     \fi}  \def\checktblheightsone diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua index 3de601911..6fe345953 100644 --- a/tex/context/base/typo-krn.lua +++ b/tex/context/base/typo-krn.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['typo-krn'] = {      license   = "see context related readme files"  } +-- todo: insertbefore etc +  local utf = unicode.utf8  local next, type = next, type diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 514a4e077..aac55170c 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@  -- merged file : luatex-fonts-merged.lua  -- parent file : luatex-fonts.lua --- merge date  : 03/20/10 22:59:11 +-- merge date  : 03/25/10 23:12:19  do -- begin closure to overcome local limits and interference @@ -2237,10 +2237,12 @@ local penalty = node.id('penalty')  local kern    = node.id('kern')  local whatsit = node.id('whatsit') -local traverse_id = node.traverse_id -local traverse    = node.traverse -local free_node   = node.free -local remove_node = node.remove +local traverse_id        = node.traverse_id +local traverse           = node.traverse +local free_node          = node.free +local remove_node        = node.remove +local insert_node_before = node.insert_before +local insert_node_after  = node.insert_after  function nodes.remove(head, current, free_too)     local t = current @@ -2260,8 +2262,8 @@ function nodes.delete(head,current)      return nodes.remove(head,current,true)  end -nodes.before = node.insert_before -nodes.after  = node.insert_after +nodes.before = insert_node_before +nodes.after  = insert_node_after  -- we need to test this, as it might be fixed now @@ -2301,21 +2303,31 @@ function nodes.after(h,c,n)      return n, n  end -function nodes.replace(head,current,new) -    if current and next then -        local p, n = current.prev, current.next -        new.prev, new.next = p, n -        if p then -            p.next = new -        else +-- local h, c = nodes.replace(head,current,new) +-- local c = nodes.replace(false,current,new) +-- local c = nodes.replace(current,new) + +function nodes.replace(head,current,new) -- no head returned if false +    if not new then +        head, current, new = false, head, current +    end +    local prev, next = current.prev, current.next +    if next then +        new.next, next.prev = next, new +    end +    if prev then +        new.prev, prev.next = prev, new +    end +    if head then +        if head == current then              head = new          end -        if n then -            n.prev = new -        end          free_node(current) +        return head, new +    else +        free_node(current) +        return new      end -    return head, current  end  -- will move @@ -2373,7 +2385,10 @@ if not modules then modules = { } end modules ['node-res'] = {  }  local gmatch, format = string.gmatch, string.format -local copy_node, free_node, free_list, new_node = node.copy, node.free, node.flush_list, node.new +local copy_node, free_node, free_list, new_node, node_type, node_id = node.copy, node.free, node.flush_list, node.new, node.type, node.id +local tonumber, round = tonumber, math.round + +local glyph_node = node_id("glyph")  --[[ldx--  <p>The next function is not that much needed but in <l n='context'/> we use @@ -2391,16 +2406,21 @@ for k, v in pairs(node.whatsits()) do      whatsits[k], whatsits[v] = v, k -- two way  end -function nodes.register(n) +local function register_node(n)      reserved[#reserved+1] = n      return n  end +nodes.register = register_node +  function nodes.cleanup_reserved(nofboxes) -- todo      nodes.tracers.steppers.reset() -- todo: make a registration subsystem      local nr, nl = #reserved, 0      for i=1,nr do -        free_node(reserved[i]) +        local ri = reserved[i] +    --  if not (ri.id == glue_spec and not ri.is_writable) then +            free_node(reserved[i]) +    --  end      end      if nofboxes then          local tb = tex.box @@ -2424,19 +2444,37 @@ function nodes.usage()      return t  end -local disc       = nodes.register(new_node("disc")) -local kern       = nodes.register(new_node("kern",1)) -local penalty    = nodes.register(new_node("penalty")) -local glue       = nodes.register(new_node("glue")) -local glue_spec  = nodes.register(new_node("glue_spec")) -local glyph      = nodes.register(new_node("glyph",0)) -local textdir    = nodes.register(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) -local rule       = nodes.register(new_node("rule")) -local latelua    = nodes.register(new_node("whatsit",whatsits.late_lua)) -- 35 -local user_n     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 -local user_l     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 -local user_s     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 -local user_t     = nodes.register(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local disc              = register_node(new_node("disc")) +local kern              = register_node(new_node("kern",1)) +local penalty           = register_node(new_node("penalty")) +local glue              = register_node(new_node("glue")) -- glue.spec = nil +local glue_spec         = register_node(new_node("glue_spec")) +local glyph             = register_node(new_node("glyph",0)) +local textdir           = register_node(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) +local rule              = register_node(new_node("rule")) +local latelua           = register_node(new_node("whatsit",whatsits.late_lua)) -- 35 +local user_n            = register_node(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 +local user_l            = register_node(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 +local user_s            = register_node(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 +local user_t            = register_node(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local left_margin_kern  = register_node(new_node("margin_kern",0)) +local right_margin_kern = register_node(new_node("margin_kern",1)) +local lineskip          = register_node(new_node("glue",1)) +local baselineskip      = register_node(new_node("glue",2)) +local leftskip          = register_node(new_node("glue",8)) +local rightskip         = register_node(new_node("glue",9)) +local temp              = register_node(new_node("temp",0)) + +function nodes.zeroglue(n) +    local s = n.spec +    return not writable or ( +                     s.width == 0 +         and       s.stretch == 0 +         and        s.shrink == 0 +         and s.stretch_order == 0 +         and  s.shrink_order == 0 +        ) +end  function nodes.glyph(fnt,chr)      local n = copy_node(glyph) @@ -2444,48 +2482,114 @@ function nodes.glyph(fnt,chr)      if chr then n.char = chr end      return n  end +  function nodes.penalty(p)      local n = copy_node(penalty)      n.penalty = p      return n  end +  function nodes.kern(k)      local n = copy_node(kern)      n.kern = k      return n  end -function nodes.glue(width,stretch,shrink) -    local n, s = copy_node(glue), copy_node(glue_spec) -    s.width, s.stretch, s.shrink = width, stretch, shrink -    n.spec = s -    return n -end +  function nodes.glue_spec(width,stretch,shrink)      local s = copy_node(glue_spec)      s.width, s.stretch, s.shrink = width, stretch, shrink      return s  end + +local function someskip(skip,width,stretch,shrink) +    local n = copy_node(skip) +    if not width then +        -- no spec +    elseif tonumber(width) then +        local s = copy_node(glue_spec) +        s.width, s.stretch, s.shrink = width, stretch, shrink +        n.spec = s +    else +        -- shared +        n.spec = copy_node(width) +    end +    return n +end + +function nodes.glue(width,stretch,shrink) +    return someskip(glue,width,stretch,shrink) +end +function nodes.leftskip(width,stretch,shrink) +    return someskip(leftskip,width,stretch,shrink) +end +function nodes.rightskip(width,stretch,shrink) +    return someskip(rightskip,width,stretch,shrink) +end +function nodes.lineskip(width,stretch,shrink) +    return someskip(lineskip,width,stretch,shrink) +end +function nodes.baselineskip(width,stretch,shrink) +    return someskip(baselineskip,width,stretch,shrink) +end +  function nodes.disc()      return copy_node(disc)  end +  function nodes.textdir(dir)      local t = copy_node(textdir)      t.dir = dir      return t  end -function nodes.rule(w,h,d) + +function nodes.rule(width,height,depth,dir)      local n = copy_node(rule) -    if w then n.width  = w end -    if h then n.height = h end -    if d then n.depth  = d end +    if width  then n.width  = width  end +    if height then n.height = height end +    if depth  then n.depth  = depth  end +    if dir    then n.dir    = dir    end      return n  end +  function nodes.latelua(code)      local n = copy_node(latelua)      n.data = code      return n  end +function nodes.leftmarginkern(glyph,width) +    local n = copy_node(left_margin_kern) +    if not glyph then +        logs.fatal("nodes","invalid pointer to left margin glyph node") +    elseif glyph.id ~= glyph_node then +        logs.fatal("nodes","invalid node type %s for left margin glyph node",node_type(glyph)) +    else +        n.glyph = glyph +    end +    if width then +        n.width = width +    end +    return n +end + +function nodes.rightmarginkern(glyph,width) +    local n = copy_node(right_margin_kern) +    if not glyph then +        logs.fatal("nodes","invalid pointer to right margin glyph node") +    elseif glyph.id ~= glyph_node then +        logs.fatal("nodes","invalid node type %s for right margin glyph node",node_type(p)) +    else +        n.glyph = glyph +    end +    if width then +        n.width = width +    end +    return n +end + +function nodes.temp() +    return copy_node(temp) +end  --[[  <p>At some point we ran into a problem that the glue specification  of the zeropoint dimension was overwritten when adapting a glue spec @@ -10501,6 +10605,8 @@ local insert_node_after  = node.insert_after  local insert_node_before = node.insert_before  local traverse_node_list = node.traverse +local new_glue_node      = nodes.glue +  local fontdata = fonts.ids  local state    = attributes.private('state') @@ -10762,11 +10868,12 @@ function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special ve      end      first, last = finish(first,last)      if removejoiners then +        -- is never head          for i=1,#joiners do -            head = delete_node(head,joiners[i]) +            delete_node(head,joiners[i])          end          for i=1,#nonjoiners do -            head = replace_node(head,nonjoiners[i],nodes.glue(0)) -- or maybe a kern +            replace_node(head,nonjoiners[i],new_glue_node(0)) -- or maybe a kern          end      end      return head, done  | 
