diff options
Diffstat (limited to 'tex')
| -rw-r--r-- | tex/context/base/cont-new.tex | 2 | ||||
| -rw-r--r-- | tex/context/base/context.tex | 2 | ||||
| -rw-r--r-- | tex/context/base/lxml-ini.lua | 13 | ||||
| -rw-r--r-- | tex/context/base/lxml-pth.lua | 283 | ||||
| -rw-r--r-- | tex/context/base/spac-ver.mkiv | 65 | ||||
| -rw-r--r-- | tex/generic/context/luatex-fonts-merged.lua | 2 | 
6 files changed, 253 insertions, 114 deletions
| diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index d4a1ca548..f32c851dc 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@  %C therefore copyrighted by \PRAGMA. See mreadme.pdf for  %C details. -\newcontextversion{2009.09.25 23:52} +\newcontextversion{2009.10.02 13:14}  %D This file is loaded at runtime, thereby providing an  %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 369ba7cf1..8354ede04 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@  %D your styles an modules.  \edef\contextformat {\jobname} -\edef\contextversion{2009.09.25 23:52} +\edef\contextversion{2009.10.02 13:14}  %D For those who want to use this: diff --git a/tex/context/base/lxml-ini.lua b/tex/context/base/lxml-ini.lua index c8c54ea16..cc4b953cd 100644 --- a/tex/context/base/lxml-ini.lua +++ b/tex/context/base/lxml-ini.lua @@ -467,13 +467,9 @@ function lxml.last(id,pattern)      xmlsprint(xmllast(get_id(id),pattern))  end  function lxml.all(id,pattern) - -- xmltprint(xmlcollect(get_id(id),pattern))      traverse(get_id(id), lpath(pattern), function(r,d,k) -        -- to be checked for root::          if d then              xmlsprint(d[k]) -        else -- new, maybe wrong ---~             xmlsprint(r)          end          return false      end) @@ -483,10 +479,6 @@ function lxml.nonspace(id,pattern) -- slow, todo loop      xmltprint(xmlcollect(get_id(id),pattern,true))  end ---~ function lxml.content(id) ---~     xmlsprint(xmlcontent(get_id(id)) or "") ---~ end -  function lxml.strip(id,pattern,nolines)      xml.strip(get_id(id),pattern,nolines)  end @@ -676,8 +668,10 @@ function lxml.serialize(root, command)                  lxml.addindex(rootname,false,true)                  ix = root.ix              end +--~ print(rootname,ix,command)              texsprint(ctxcatcodes,format("\\xmls{%s::%s}{%s}",rootname,ix,command))          else +--~ print(ix,command)              texsprint(ctxcatcodes,format("\\xmls{%s}{%s}",ix,command))          end      elseif tc == "function" then @@ -689,6 +683,7 @@ function lxml.serialize(root, command)      elseif command == false then          -- ignore      else +        -- texsprint("?")          -- fuzzy, so ignore too      end  end @@ -849,7 +844,7 @@ end  local rootname, thecmd  local function ndoit(r,d,k) -    local m = (d and d[k]) or r -- brrr this r, maybe away +    local m = (d and d[k]) or r      local ix = m.ix      if not ix then          lxml.addindex(rootname,false,true) diff --git a/tex/context/base/lxml-pth.lua b/tex/context/base/lxml-pth.lua index 8f7015de9..a1bebe017 100644 --- a/tex/context/base/lxml-pth.lua +++ b/tex/context/base/lxml-pth.lua @@ -15,6 +15,8 @@ local format, lower, gmatch, gsub, find, rep = string.format, string.lower, stri  which case it hooks into the tracker code. Therefore we provide a few  functions that set the tracers. Here we overload a previously defined  function.</p> +<p>If I can get in the mood I will make a variant that is XSLT compliant +but I wonder if it makes sense.</P>  --ldx]]--  local trace_lpath = false  if trackers then trackers.register("xml.lpath", function(v) trace_lpath = v end) end @@ -44,6 +46,10 @@ xml.expressions = xml.expressions or { }  local functions   = xml.functions  local expressions = xml.expressions +-- although we could remap all to expressions we prefer to have a few speed ups +-- like simple expressions as they happen to occur a lot and then we want to +-- avoid too many loops +  local actions = {      [10] = "stay",      [11] = "parent", @@ -58,6 +64,7 @@ local actions = {      [23] = "match and attribute ne",      [24] = "match one of and attribute eq",      [25] = "match one of and attribute ne", +    [26] = "has name",      [27] = "has attribute",      [28] = "has value",      [29] = "fast match", @@ -72,7 +79,11 @@ local P, S, R, C, V, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc  -- instead of using functions we just parse a few names which saves a call  -- later on +-- +-- we can use a metatable +local lp_space     = S(" \n\r\t") +local lp_any       = P(1)  local lp_position  = P("position()") / "ps"  local lp_index     = P("index()")    / "id"  local lp_text      = P("text()")     / "tx" @@ -81,7 +92,12 @@ local lp_tag       = P("tag()")      / "tg" -- (rt.tg or '')  local lp_ns        = P("ns()")       / "ns" -- (rt.ns or '')  local lp_noequal   = P("!=")         / "~=" + P("<=") + P(">=") + P("==")  local lp_doequal   = P("=")          / "==" -local lp_attribute = P("@")          / "" * Cc("(at['") * R("az","AZ","--","__")^1 * Cc("'] or '')") +--~ local lp_attribute = P("@")          / "" * Cc("(at['") * R("az","AZ","--","__")^1 * Cc("'] or '')") +local lp_attribute = P("@")          / "" * Cc("at['") * R("az","AZ","--","__")^1 * Cc("']") +local lp_or        = P("|")          / " or " +local lp_and       = P("&")          / " and " + +local lp_reserved  = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false")  local lp_lua_function  = C(R("az","AZ","--","__")^1 * (P(".") * R("az","AZ","--","__")^1)^1) * P("(") / function(t) -- todo: better . handling      return t .. "(" @@ -101,12 +117,19 @@ local noparent = 1 - (lparent+rparent)  local nested   = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}  local value    = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"} +local lp_child  = Cc("expressions.child(r,k,'") * R("az","AZ","--","__")^1 * Cc("')") +local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'") +local lp_content= Cc("tx==") * (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"')) + +  -- if we use a dedicated namespace then we don't need to pass rt and k -local lp_special = (C(P("name")+P("text")+P("tag"))) * value / function(t,s) +local converter, cleaner + +local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s)      if expressions[t] then          if s then -            return "expressions." .. t .. "(r,k," .. s ..")" +            return "expressions." .. t .. "(r,k," .. cleaner:match(s) ..")"          else              return "expressions." .. t .. "(r,k)"          end @@ -115,20 +138,34 @@ local lp_special = (C(P("name")+P("text")+P("tag"))) * value / function(t,s)      end  end -local converter = lpeg.Cs ( ( +local content =      lp_position +      lp_index +      lp_text + lp_name + -- fast one      lp_special +      lp_noequal + lp_doequal +      lp_attribute + +    lp_or + lp_and +      lp_lua_function +      lp_function + +    lp_reserved + +    lp_content + +    lp_child + +    lp_any + +converter = lpeg.Cs ( +    (lpeg.P { lparent * (lpeg.V(1))^0 * rparent + content } )^0 +) + +cleaner = lpeg.Cs ( ( +    lp_reserved + +    lp_string +  1 )^1 )  -- expressions,root,rootdt,k,e,edt,ns,tg,idx,hsh[tg] or 1  local template = [[ +    -- todo: locals for xml.functions      return function(expressions,r,d,k,e,dt,ns,tg,id,ps)          local at, tx = e.at or { }, dt[1] or ""          return %s @@ -136,12 +173,17 @@ local template = [[  ]]  local function make_expression(str) +--~ print(">>>",str)      str = converter:match(str) -    return str, loadstring(format(template,str))() +--~ print("<<<",str) +    local s = loadstring(format(template,str)) +    if s then +        return str, s() +    else +        return str, "" +    end  end -local map = { } -  local space                    = S(' \r\n\t')  local squote                   = S("'")  local dquote                   = S('"') @@ -173,71 +215,84 @@ local optionalspace            = space^0  local text                     = C(valid^0)  local value                    = (squote * C((1 - squote)^0) * squote) + (dquote * C((1 - dquote)^0) * dquote)  local empty                    = 1-slash +local nobracket                = 1-(lbracket+rbracket) + +-- this has to become a proper grammar instead of a substitution (which we started +-- with when we moved to lpeg) + +local is_eq                    = lbracket * atsign * name * eq * value * rbracket * #(1-lbracket) +local is_ne                    = lbracket * atsign * name * ne * value * rbracket * #(1-lbracket) +local is_attribute             = lbracket * atsign * name              * rbracket * #(1-lbracket) +local is_value                 = lbracket *          value             * rbracket * #(1-lbracket) +local is_number                = lbracket *          number            * rbracket * #(1-lbracket) +local is_name                  = lbracket *          name              * rbracket * #(1-lbracket) -local is_eq                    = lbracket * atsign * name * eq * value * rbracket -local is_ne                    = lbracket * atsign * name * ne * value * rbracket -local is_attribute             = lbracket * atsign * name              * rbracket -local is_value                 = lbracket *          value             * rbracket -local is_number                = lbracket *          number            * rbracket +--~ local is_expression            = lbracket * (C(nobracket^1))/make_expression * rbracket +--~ local is_expression            = is_expression * (Cc(" and ") * is_expression)^0 -local nobracket                = 1-(lbracket+rbracket)  -- must be improved -local is_expression            = lbracket * C(((C(nobracket^1))/make_expression)) * rbracket +--~ local is_expression            = (lbracket/"(") * C(nobracket^1) * (rbracket/")") +--~ local is_expression            = lpeg.Cs(is_expression * (Cc(" and ") * is_expression)^0) / make_expression -local is_expression            = lbracket * (C(nobracket^1))/make_expression * rbracket +local is_position = function(s) return " position()==" .. s .. " " end + +local is_expression            = (is_number/is_position) + (lbracket/"(") * (nobracket^1) * (rbracket/")") +local is_expression            = lpeg.Cs(is_expression * (Cc(" and ") * is_expression)^0) / make_expression  local is_one                   =          name  local is_none                  = exclam * name  local is_one_of                =          ((lparent * names * rparent) + morenames)  local is_none_of               = exclam * ((lparent * names * rparent) + morenames) +--~ local stay_action = { 11 }, beware, sometimes we adapt ! +  local stay                     = (period                ) -local parent                   = (period * period       ) / function(   ) map[#map+1] = { 11             } end -local subtreeroot              = (slash + hat           ) / function(   ) map[#map+1] = { 12             } end -local documentroot             = (hat * hat             ) / function(   ) map[#map+1] = { 13             } end -local any                      = (star                  ) / function(   ) map[#map+1] = { 14             } end -local many                     = (star * star           ) / function(   ) map[#map+1] = { 15             } end -local initial                  = (hat * hat * hat       ) / function(   ) map[#map+1] = { 16             } end - -local match                    = (is_one                ) / function(...) map[#map+1] = { 20, true , ... } end -local match_one_of             = (is_one_of             ) / function(...) map[#map+1] = { 21, true , ... } end -local dont_match               = (is_none               ) / function(...) map[#map+1] = { 20, false, ... } end -local dont_match_one_of        = (is_none_of            ) / function(...) map[#map+1] = { 21, false, ... } end - -local match_and_eq             = (is_one     * is_eq    ) / function(...) map[#map+1] = { 22, true , ... } end -local match_and_ne             = (is_one     * is_ne    ) / function(...) map[#map+1] = { 23, true , ... } end -local dont_match_and_eq        = (is_none    * is_eq    ) / function(...) map[#map+1] = { 22, false, ... } end -local dont_match_and_ne        = (is_none    * is_ne    ) / function(...) map[#map+1] = { 23, false, ... } end - -local match_one_of_and_eq      = (is_one_of  * is_eq    ) / function(...) map[#map+1] = { 24, true , ... } end -local match_one_of_and_ne      = (is_one_of  * is_ne    ) / function(...) map[#map+1] = { 25, true , ... } end -local dont_match_one_of_and_eq = (is_none_of * is_eq    ) / function(...) map[#map+1] = { 24, false, ... } end -local dont_match_one_of_and_ne = (is_none_of * is_ne    ) / function(...) map[#map+1] = { 25, false, ... } end - -local has_attribute            = (is_one  * is_attribute) / function(...) map[#map+1] = { 27, true , ... } end -local has_value                = (is_one  * is_value    ) / function(...) map[#map+1] = { 28, true , ... } end -local dont_has_attribute       = (is_none * is_attribute) / function(...) map[#map+1] = { 27, false, ... } end -local dont_has_value           = (is_none * is_value    ) / function(...) map[#map+1] = { 28, false, ... } end -local position                 = (is_one  * is_number   ) / function(...) map[#map+1] = { 30, true,  ... } end -local dont_position            = (is_none * is_number   ) / function(...) map[#map+1] = { 30, false, ... } end - -local expression               = (is_one  * is_expression)/ function(...) map[#map+1] = { 31, true,  ... } end -local dont_expression          = (is_none * is_expression)/ function(...) map[#map+1] = { 31, false, ... } end - -local self_expression          = (         is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end -                                                                          map[#map+1] = { 31, true,  "*", "*", ... } end -local dont_self_expression     = (exclam * is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end -                                                                          map[#map+1] = { 31, false, "*", "*", ... } end - -local instruction              = (instructiontag * text ) / function(...) map[#map+1] = { 40,        ... } end -local nothing                  = (empty                 ) / function(   ) map[#map+1] = { 15             } end -- 15 ? +local parent                   = (period * period       ) / function(   ) return { 11             } end +local subtreeroot              = (slash + hat           ) / function(   ) return { 12             } end +local documentroot             = (hat * hat             ) / function(   ) return { 13             } end +local any                      = (star                  ) / function(   ) return { 14             } end +local many                     = (star * star           ) / function(   ) return { 15             } end +local initial                  = (hat * hat * hat       ) / function(   ) return { 16             } end + +local match                    = (is_one                ) / function(...) return { 20, true , ... } end +local match_one_of             = (is_one_of             ) / function(...) return { 21, true , ... } end +local dont_match               = (is_none               ) / function(...) return { 20, false, ... } end +local dont_match_one_of        = (is_none_of            ) / function(...) return { 21, false, ... } end + +local match_and_eq             = (is_one     * is_eq    ) / function(...) return { 22, true , ... } end +local match_and_ne             = (is_one     * is_ne    ) / function(...) return { 23, true , ... } end +local dont_match_and_eq        = (is_none    * is_eq    ) / function(...) return { 22, false, ... } end +local dont_match_and_ne        = (is_none    * is_ne    ) / function(...) return { 23, false, ... } end + +local match_one_of_and_eq      = (is_one_of  * is_eq    ) / function(...) return { 24, true , ... } end +local match_one_of_and_ne      = (is_one_of  * is_ne    ) / function(...) return { 25, true , ... } end +local dont_match_one_of_and_eq = (is_none_of * is_eq    ) / function(...) return { 24, false, ... } end +local dont_match_one_of_and_ne = (is_none_of * is_ne    ) / function(...) return { 25, false, ... } end + +local has_name                 = (is_one  * is_name)      / function(...) return { 26, true , ... } end +local dont_has_name            = (is_none * is_name)      / function(...) return { 26, false, ... } end +local has_attribute            = (is_one  * is_attribute) / function(...) return { 27, true , ... } end +local dont_has_attribute       = (is_none * is_attribute) / function(...) return { 27, false, ... } end +local has_value                = (is_one  * is_value    ) / function(...) return { 28, true , ... } end +local dont_has_value           = (is_none * is_value    ) / function(...) return { 28, false, ... } end +local position                 = (is_one  * is_number   ) / function(...) return { 30, true,  ... } end +local dont_position            = (is_none * is_number   ) / function(...) return { 30, false, ... } end + +local expression               = (is_one  * is_expression)/ function(...) return { 31, true,  ... } end +local dont_expression          = (is_none * is_expression)/ function(...) return { 31, false, ... } end + +local self_expression          = (         is_expression) / function(...) return { 31, true,  "*", "*", ... } end +local dont_self_expression     = (exclam * is_expression) / function(...) return { 31, false, "*", "*", ... } end + +local instruction              = (instructiontag * text ) / function(...) return { 40,        ... } end +local nothing                  = (empty                 ) / function(   ) return { 15             } end -- 15 ?  local crap                     = (1-slash)^1  -- a few ugly goodies: -local docroottag               = P('^^')             / function(   ) map[#map+1] = { 12             } end -local subroottag               = P('^')              / function(   ) map[#map+1] = { 13             } end -local roottag                  = P('root::')         / function(   ) map[#map+1] = { 12             } end -local parenttag                = P('parent::')       / function(   ) map[#map+1] = { 11             } end +local docroottag               = P('^^')             / function() return { 12 } end +local subroottag               = P('^')              / function() return { 13 } end +local roottag                  = P('root::')         / function() return { 12 } end +local parenttag                = P('parent::')       / function() return { 11 } end  local childtag                 = P('child::')  local selftag                  = P('self::') @@ -247,21 +302,23 @@ local selector = (      instruction +  --  many + any + -- brrr, not here !      parent + stay + -    dont_position + position + +    dont_position + position + -- fast one +    dont_has_attribute + has_attribute + -- fast ones +    dont_has_name + has_name + -- fast ones +    dont_has_value + has_value + -- fast ones      dont_match_one_of_and_eq + dont_match_one_of_and_ne +      match_one_of_and_eq + match_one_of_and_ne +      dont_match_and_eq + dont_match_and_ne +      match_and_eq + match_and_ne +      dont_expression + expression +      dont_self_expression + self_expression + -    has_attribute + has_value +      dont_match_one_of + match_one_of +      dont_match + match +      many + any +      crap + empty  ) -local grammar = P { "startup", +local grammar = lpeg.Ct { "startup",      startup  = (initial + documentroot + subtreeroot + roottag + docroottag + subroottag)^0 * V("followup"),      followup = ((slash + parenttag + childtag + selftag)^0 * selector)^1,  } @@ -274,11 +331,14 @@ local function compose(str)          -- root          return false      else -        map = { } -        grammar:match(str) +        local map = grammar:match(str)          if #map == 0 then              return true          else +            if map[1][1] == 32 then +                -- lone expression +                insert(map, 1, { 11 }) +            end              local m = map[1][1]              if #map == 1 then                  if m == 14 or m == 15 then @@ -289,14 +349,12 @@ local function compose(str)                      return false                  end              elseif #map == 2 and m == 12 and map[2][1] == 20 then -            --  return { { 29, map[2][2], map[2][3], map[2][4], map[2][5] } }                  map[2][1] = 29                  return { map[2] }              end              if m ~= 11 and m ~= 12 and m ~= 13 and m ~= 14 and m ~= 15 and m ~= 16 then                  insert(map, 1, { 16 })              end -        --  print(gsub(table.serialize(map),"[ \n]+"," "))              return map          end      end @@ -304,7 +362,7 @@ end  local cache = { } -function xml.lpath(pattern,trace) +local function lpath(pattern,trace)      lpathcalls = lpathcalls + 1      if type(pattern) == "string" then          local result = cache[pattern] @@ -322,6 +380,8 @@ function xml.lpath(pattern,trace)      end  end +xml.lpath = lpath +  function xml.cached_patterns()      return cache  end @@ -333,7 +393,7 @@ end  function xml.lshow(pattern,report)  --      report = report or fallbackreport      report = report or (texio and texio.write) or io.write -    local lp = xml.lpath(pattern) +    local lp = lpath(pattern)      if lp == false then          report(" -: root\n")      elseif lp == true then @@ -414,13 +474,13 @@ expressions.error = function(str)  end  functions.text = function(root,k,n) -- unchecked, maybe one deeper -    local t = type(t) -    if t == "string" then -        return t -    else -- todo n +--~     local t = type(t) -- ? +--~     if t == "string" then +--~         return t +--~     else -- todo n          local rdt = root.dt          return (rdt and rdt[k]) or root[k] or "" -    end +--~     end  end  functions.name = function(d,k,n) -- ns + tg @@ -550,8 +610,10 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu              local ep = root.__p__ or parent              if index < #pattern then                  if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end -            elseif handle(root,rootdt,k) then +            elseif handle(ep) then -- wrong (others also)                  return false +            else +                -- ?              end          else              if (command == 16 or command == 12) and index == 1 then -- initial @@ -565,8 +627,10 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                  local ep = root.__p__ or parent                  if index < #pattern then                      if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end -                elseif handle(root,rootdt,k) then +                elseif handle(ep) then                      return false +                else +                    -- ?                  end              else                  local rootdt = root.dt @@ -579,8 +643,7 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                  elseif reverse and index == #pattern then                      start, stop, step = stop, start, -1                  end -                local idx = 0 -                local hsh = { } -- this will slooow down the lot +                local idx, hsh = 0, { } -- this hsh will slooow down the lot                  for k=start,stop,step do -- we used to have functions for all but a case is faster                      local e = rootdt[k]                      local ns, tg = e.rn or e.ns, e.tg @@ -676,6 +739,30 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                                  end                                  if not action[2] then matched = not matched end                                  matched = matched and e.at[action[#action-1]] ~= action[#action] +                            elseif command == 26 then -- has child +                                local ns_a, tg_a = action[3], action[4] +                                if tg == tg_a then +                                    matched = ns_a == "*" or ns == ns_a +                                elseif tg_a == '*' then +                                    matched, multiple = ns_a == "*" or ns == ns_a, true +                                else +                                    matched = false +                                end +                                if not action[2] then matched = not matched end +                                if matched then +                                    -- ok, we could have the whole sequence here ... but > 1 has become an expression +                                    local ns_a, tg_a, ok, edt = action[5], action[6], false, e.dt +                                    for k=1,#edt do +                                        local edk = edt[k] +                                        if type(edk) == "table" then +                                            if (ns_a == "*" or edk.ns == ns_a) and (edk.tg == tg_a) then +                                                ok = true +                                                break +                                            end +                                        end +                                    end +                                    matched = matched and ok +                                end                              elseif command == 27 then -- has attribute                                  local ns_a, tg_a = action[3], action[4]                                  if tg == tg_a then @@ -686,8 +773,8 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                                      matched = false                                  end                                  if not action[2] then matched = not matched end -                                matched = matched and e.at[action[5]] -                            elseif command == 28 then -- has value +                                matched = matched and e.at[action[6]] +                            elseif command == 28 then -- has value (text match)                                  local edt, ns_a, tg_a = e.dt, action[3], action[4]                                  if tg == tg_a then                                      matched = ns_a == "*" or ns == ns_a @@ -724,6 +811,7 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                                          end                                      end                                  else +                                    -- todo: [expr][expr]                                      if not traverse(e,pattern,handle,reverse,index+1,root) then return false end                                  end                              elseif command == 14 then -- any @@ -768,8 +856,10 @@ local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- mu                              local ep = e.__p__ or parent                              if index < #pattern then                                  if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end -                            elseif handle(root,rootdt,k) then +                            elseif handle(ep) then                                  return false +                            else +                                --                              end                              break -- else loop                          end @@ -783,6 +873,18 @@ end  xml.traverse = traverse +expressions.child = function(root,k,what) -- we could move the lpath converter to the scanner +    local ok = false +    traverse(root.dt[k],lpath(what),function(r,d,t) ok = true return true end) +    return ok +end + +expressions.count = function(root,k,what) -- we could move the lpath converter to the scanner +    local n = 0 +    traverse(root.dt[k],lpath(what),function(r,d,t) n = n + 1 return false end) +    return n +end +  --[[ldx--  <p>Next come all kind of locators and manipulators. The most generic function here  is <t>xml.filter(root,pattern)</t>. All registers functions in the filters namespace @@ -1570,6 +1672,29 @@ end  --~ xml.lshow("/../../../a/(b|c)[@d='e']/f")  --~ xml.lshow("/../../../a/!(b|c)[@d='e']/f")  --~ xml.lshow("/../../../a/!b[@d!='e']/f") +--~ xml.lshow("a[text()=='b']") +--~ xml.lshow("a['b']") +--~ xml.lshow("(x|y)[b]") +--~ xml.lshow("/aaa[bbb]") +--~ xml.lshow("aaa[bbb][ccc][ddd]") +--~ xml.lshow("aaa['xxx']") +--~ xml.lshow("a[b|c]") +--~ xml.lshow("whatever['crap']") +--~ xml.lshow("whatever[count(whocares) > 1 and oeps and 'oeps']") +--~ xml.lshow("whatever[whocares]") +--~ xml.lshow("whatever[@whocares]") +--~ xml.lshow("whatever[count(whocares) > 1]") +--~ xml.lshow("a(@b)") +--~ xml.lshow("a[b|c|d]") +--~ xml.lshow("a[b and @b]") +--~ xml.lshow("a[b]") +--~ xml.lshow("a[b and b]") +--~ xml.lshow("a[b][c]") +--~ xml.lshow("a[b][1]") +--~ xml.lshow("a[1]") +--~ xml.lshow("a[count(b)!=0][count(b)!=0]") +--~ xml.lshow("a[not(count(b))][not(count(b))]") +--~ xml.lshow("a[count(b)!=0][count(b)!=0]")  --~ x = xml.convert([[  --~     <a> diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index bce0fb826..229a49193 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -416,39 +416,35 @@  \newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}  \def\lastdoneparskip {0pt} -\def\startpacked +\newconditional\noblankinpacked +\newcount\packeddepth + +\unexpanded\def\startpacked    {\dosingleempty\dostartpacked}  \def\dostartpacked[#1]% nesting afvangen -  {\par -   \ifvmode +  {\global\advance\packeddepth\plusone +   \par +   \ifnum\packeddepth=\plusone \ifvmode       \bgroup       \whitespace % not combined -     \blank[\v!disable] -     \setupwhitespace[\v!none] -     \let\startpacked\nestedstartpacked -   \fi} +     \blank[\v!disable]% +     \doifelse{#1}\v!blank\setfalse\settrue\noblankinpacked +     \setupwhitespace[\v!none]% +   \fi \fi} -\def\stoppacked +\unexpanded\def\stoppacked    {\par -   \ifvmode +   \ifnum\packeddepth=\plusone \ifvmode       \egroup -   \fi} - -\def\nestedstartpacked -  {\par -   \bgroup -   \let\stoppacked\nestedstoppacked} - -\def\nestedstoppacked -  {\par -   \egroup} +   \fi \fi +   \global\advance\packeddepth\minusone} -\def\startunpacked +\unexpanded\def\startunpacked    {\blank     \bgroup} -\def\stopunpacked +\unexpanded\def\stopunpacked    {\egroup     \blank} @@ -1539,6 +1535,17 @@     \flushblankhandling}  \def\startblankhandling +  {\par +   \ifvmode +     \expandafter\dostartblankhandling +   \else +     \expandafter\nostartblankhandling +   \fi} + +\def\nostartblankhandling#1\stopblankhandling +  {} + +\def\dostartblankhandling    {\begingroup     \setfalse\someblankdone     \the\everybeforeblankhandling} @@ -1587,8 +1594,20 @@  \unexpanded\def\vspacing    {\dosingleempty\dovspacing} -\def\dovspacing[#1]% -  {\ctxlua{vspacing.analyse("\iffirstargument#1\else\s!default\fi")}} +\def\dovspacing % blank also has a \flushnotes +  {\ifinpagebody +     \expandafter\dovspacingyes +   \else\ifconditional\noblankinpacked % todo: better reset this conditional in pagebody +     \expandafter\expandafter\expandafter\dovspacingnop +   \else +     \expandafter\expandafter\expandafter\dovspacingyes +   \fi\fi} + +\def\dovspacingyes[#1]% +  {\ifmmode\else\ctxlua{vspacing.analyse("\iffirstargument#1\else\s!default\fi")}\fi} + +\def\dovspacingnop[#1]% +  {\ifmmode\else\par\fi}  % todo: check them and make them faster: diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 8d7f7b58b..d0e7f9ae9 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@  -- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua  -- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua --- merge date  : 09/25/09 23:59:10 +-- merge date  : 10/02/09 13:19:15  do -- begin closure to overcome local limits and interference | 
