diff options
26 files changed, 1213 insertions, 65 deletions
diff --git a/doc/context/documents/general/manuals/xml-mkiv.pdf b/doc/context/documents/general/manuals/xml-mkiv.pdf Binary files differindex c21944c72..174bc395b 100644 --- a/doc/context/documents/general/manuals/xml-mkiv.pdf +++ b/doc/context/documents/general/manuals/xml-mkiv.pdf diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf Binary files differindex 70173bef3..cfb258b76 100644 --- a/doc/context/documents/general/qrcs/setup-cs.pdf +++ b/doc/context/documents/general/qrcs/setup-cs.pdf diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf Binary files differindex c32ef8046..51f19d8ff 100644 --- a/doc/context/documents/general/qrcs/setup-de.pdf +++ b/doc/context/documents/general/qrcs/setup-de.pdf diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf Binary files differindex 0f76a4ac2..4fac278b4 100644 --- a/doc/context/documents/general/qrcs/setup-en.pdf +++ b/doc/context/documents/general/qrcs/setup-en.pdf diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf Binary files differindex 380ede7cc..a9eba7e97 100644 --- a/doc/context/documents/general/qrcs/setup-fr.pdf +++ b/doc/context/documents/general/qrcs/setup-fr.pdf diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf Binary files differindex 7b5a254ae..2b82f75bc 100644 --- a/doc/context/documents/general/qrcs/setup-it.pdf +++ b/doc/context/documents/general/qrcs/setup-it.pdf diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf Binary files differindex 0951d8e92..4a1dd5f33 100644 --- a/doc/context/documents/general/qrcs/setup-nl.pdf +++ b/doc/context/documents/general/qrcs/setup-nl.pdf diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf Binary files differindex 0439429da..65b67d67e 100644 --- a/doc/context/documents/general/qrcs/setup-ro.pdf +++ b/doc/context/documents/general/qrcs/setup-ro.pdf diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv.tex b/doc/context/sources/general/manuals/xml/xml-mkiv.tex index 3c189daf3..6e6deead0 100644 --- a/doc/context/sources/general/manuals/xml/xml-mkiv.tex +++ b/doc/context/sources/general/manuals/xml/xml-mkiv.tex @@ -38,7 +38,7 @@ \usemodule[set-11] -\loadsetups[i-en-xml.xml] +\loadsetups[i-context] % \definehspace[squad][1em plus .25em minus .25em] @@ -84,18 +84,21 @@ \starttexdefinition unexpanded section:chapter:number #1 \doifmode{*sectionnumber} { + \bf \llap{<\enspace}#1\enspace> } \stoptexdefinition \starttexdefinition unexpanded section:section:number #1 \doifmode{*sectionnumber} { + \bf \llap{<<\enspace}#1\enspace>> } \stoptexdefinition \starttexdefinition unexpanded section:subsection:number #1 \doifmode{*sectionnumber} { + \bf \llap{<<<\enspace}#1\enspace>>> } \stoptexdefinition @@ -1776,6 +1779,222 @@ In addition, \type {=} equals \type {==} and \type {!=} is the same as \type \stopsection + +\startsection[title={css selectors}] + +\startbuffer[selector-001] +<?xml version="1.0" ?> + +<a> + <b class="one">b.one</b> + <b class="two">b.two</b> + <b class="one two">b.one.two</b> + <b class="three">b.three</b> + <b id="first">b#first</b> + <c>c</c> + <d>d e</d> + <e>d e</e> + <e>d e e</e> + <d>d f</d> + <f foo="bar">@foo = bar</f> + <f bar="foo">@bar = foo</f> + <f bar="foo1">@bar = foo1</f> + <f bar="foo2">@bar = foo2</f> + <f bar="foo3">@bar = foo3</f> + <f bar="foo+4">@bar = foo+4</f> + <g>g</g> + <g><gg><d>g gg d</d></gg></g> + <g><gg><f>g gg f</f></gg></g> + <g><gg><f class="one">g gg f.one</f></gg></g> + <g>g</g> + <g><gg><f class="two">g gg f.two</f></gg></g> + <g><gg><f class="three">g gg f.three</f></gg></g> + <g><f class="one">g f.one</f></g> + <g><f class="three">g f.three</f></g> + <h whatever="four five six">@whatever = four five six</h> +</a> +\stopbuffer + +\xmlloadbuffer{selector-001}{selector-001} + +\startxmlsetups xml:selector:demo + \advance\scratchcounter\plusone + \inleftmargin{\the\scratchcounter}\ignorespaces\xmlverbatim{#1}\par +\stopxmlsetups + +\unexpanded\def\showCSSdemo#1#2% + {\blank + \textrule{\tttf#2} + \startlines + \dontcomplain + \tttf \obeyspaces + \scratchcounter\zerocount + \xmlcommand{#1}{#2}{xml:selector:demo} + \stoplines + \blank} + +The \CSS\ approach to filtering is a bit different from the path based one and is +supported too. In fact, you can combine both methods. Depending on what you +select, the \CSS\ one can be a little bit faster too. It has the advantage that +one can select more in one go but at the same time looks a bit less attractive. +This method was added just to show that it can be done but might be useful too. A +selector is gogen between curly braces (after all \CSS\ uses them and they have no +function yet in the parser. + +\starttyping +\xmlall{#1}{{foo bar .whatever, bar foo .whatever}} +\stoptyping + +The following methods are supported: + +\starttabulate[|T||] +\NC element \NC all tags element \NC \NR +\NC element-1 > element-2 \NC all tags element-2 with parent tag element-1 \NC \NR +\NC element-1 + element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR +\NC element-1 ~ element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR +\NC element-1 element-2 \NC all tags element-2 inside tag element-1 \NC \NR +\NC [attribute] \NC has attribute \NC \NR +\NC [attribute=value] \NC attribute equals value\NC \NR +\NC [attribute\lettertilde =value] \NC attribute contains value (space is separator) \NC \NR +\NC [attribute\letterhat ="value"] \NC attribute starts with value \NC \NR +\NC [attribute\letterdollar="value"] \NC attribute ends with value \NC \NR +\NC [attribute*="value"] \NC attribute contains value \NC \NR +\NC .class \NC has class \NC \NR +\NC \letterhash id \NC has id \NC \NR +\NC :nth-child(n) \NC the child at index n \NC \NR +\NC :nth-last-child(n) \NC the child at index n from the end \NC \NR +\NC :first-child \NC the first child \NC \NR +\NC :last-child \NC the last child \NC \NR +\NC :nth-of-type(n) \NC the match at index n \NC \NR +\NC :nth-last-of-type(n) \NC the match at index n from the end \NC \NR +\NC :first-of-type \NC the first match \NC \NR +\NC :last-of-type \NC the last match \NC \NR +\NC :only-of-type \NC the only match or nothing \NC \NR +\NC :only-child \NC the only child or nothing \NC \NR +\NC :empty \NC only when empty \NC \NR +\NC :root \NC the whole tree \NC \NR +\stoptabulate + +The next pages show some examples. For that we use the demo file: + +\typebuffer[selector-001] + +The class and id selectors often only make sense in \HTML\ like documents but they +are supported nevertheless. They are after all just shortcuts for filtering by +attribute. The class filtering is special in the sense that it checks for a class +in a list of classes given in an attribute. + +\showCSSdemo{selector-001}{{.one}} +\showCSSdemo{selector-001}{{.one, .two}} +\showCSSdemo{selector-001}{{.one, .two, \letterhash first}} + +Attributes can be filtered by presence, value, partial value and such. Quotes are +optional but we advice to use them. + +\showCSSdemo{selector-001}{{[foo], [bar=foo]}} +\showCSSdemo{selector-001}{{[bar\lettertilde=foo]}} +\showCSSdemo{selector-001}{{[bar\letterhat="foo"]}} +\showCSSdemo{selector-001}{{[whatever\lettertilde="five"]}} + +You can of course combine the methods as in: + +\showCSSdemo{selector-001}{{g f .one, g f .three}} +\showCSSdemo{selector-001}{{g > f .one, g > f .three}} +\showCSSdemo{selector-001}{{d + e}} +\showCSSdemo{selector-001}{{d ~ e}} +\showCSSdemo{selector-001}{{d ~ e, g f .one, g f .three}} + +You can also negate the result by using \type {:not} on a simple expression: + +\showCSSdemo{selector-001}{{:not([whatever\lettertilde="five"])}} +\showCSSdemo{selector-001}{{:not(d)}} + +The child and match selectors are also supported: + +\showCSSdemo{selector-001}{{a:nth-child(3)}} +\showCSSdemo{selector-001}{{a:nth-last-child(3)}} +\showCSSdemo{selector-001}{{g:nth-of-type(3)}} +\showCSSdemo{selector-001}{{g:nth-last-of-type(3)}} +\showCSSdemo{selector-001}{{a:first-child}} +\showCSSdemo{selector-001}{{a:last-child}} +\showCSSdemo{selector-001}{{e:first-of-type}} +\showCSSdemo{selector-001}{{gg d:only-of-type}} + +Instead of numbers you can also give the \type {an} and \type {an+b} formulas +as well as the \type {odd} and \type {even} keywords: + +\showCSSdemo{selector-001}{{a:nth-child(even)}} +\showCSSdemo{selector-001}{{a:nth-child(odd)}} +\showCSSdemo{selector-001}{{a:nth-child(3n+1)}} +\showCSSdemo{selector-001}{{a:nth-child(2n+3)}} + +There are a few special cases: + +\showCSSdemo{selector-001}{{g:empty}} +\showCSSdemo{selector-001}{{g:root}} +\showCSSdemo{selector-001}{{*}} + +Combining the \CSS\ methods with the regular ones is possible: + +\showCSSdemo{selector-001}{{g gg f .one}} +\showCSSdemo{selector-001}{g/gg/f[@class='one']} +\showCSSdemo{selector-001}{g/{gg f .one}} + +\startbuffer[selector-002] +<?xml version="1.0" ?> + +<document> + <title class="one" >title 1</title> + <title class="two" >title 2</title> + <title class="one" >title 3</title> + <title class="three">title 4</title> +</document> +\stopbuffer + +The next examples we use this file: + +\typebuffer[selector-002] + +\xmlloadbuffer{selector-002}{selector-002} + +When we filter from this (not too well structured) tree we can use both +methods to achieve the same: + +\showCSSdemo{selector-002}{{document title .one, document title .three}} + +\showCSSdemo{selector-002}{/document/title[(@class='one') or (@class='three')]} + +However, imagine this file: + +\startbuffer[selector-003] +<?xml version="1.0" ?> + +<document> + <title class="one">title 1</title> + <subtitle class="sub">title 1.1</subtitle> + <title class="two">title 2</title> + <subtitle class="sub">title 2.1</subtitle> + <title class="one">title 3</title> + <subtitle class="sub">title 3.1</subtitle> + <title class="two">title 4</title> + <subtitle class="sub">title 4.1</subtitle> +</document> +\stopbuffer + +\typebuffer[selector-003] + +\xmlloadbuffer{selector-003}{selector-003} + +The next filter in easier with the \CSS\ selector methods because these accumulate +independent (simple) expressions: + +\showCSSdemo{selector-003}{{document title .one + subtitle, document title .two + subtitle}} + +Watch how we get an output in the document order. Because we render a sequential document +a combined filter will trigger a sorting pass. + +\stopsection + \startsection[title={functions as filters}] At the \LUA\ end a whole \cmdinternal {cd:lpath} expression results in a (set of) node(s) @@ -3925,6 +4144,72 @@ Now we get: \ctxluabuffer +\startsection[title=Pure xml] + +One might wonder how a \TEX\ macro package would look like when backslashes, +dollars and percent signs would have no special meaning. In fact, it would be +rather useless as interpreting commands are triggered by such characters. Any +formatting or coding system needs such characters. Take \XML: angle brackets and +ampersands are really special. So, no matter what system we use, we do have to +deal with the (common) case where these characters need to be sees as they are. +Normally escaping is the solution. + +The \CONTEXT\ interface for \XML\ suffers from this as well. You really don't +want to know how many tricks are used for dealing with special characters and +entities: there are several ways these travel through the system and it is +possible to adapt and cheat. Especially roundtripped data (via tuc file) puts +some demands on the system because when ts \XML\ can become \TEX\ and vise versa. +The next example (derived from a mail on the list) demonstrates this: + +\starttyping +\startbuffer[demo] +<doc> + <pre><code>\ConTeXt\ is great</code></pre> + + <pre><code>but you need to know some tricks</code></pre> +</doc> +\stopbuffer + +\startxmlsetups xml:initialize + \xmlsetsetup{#1}{doc|p|code}{xml:*} + \xmlsetsetup{#1}{pre/code}{xml:pre:code} +\stopxmlsetups + +\xmlregistersetup{xml:initialize} + +\startxmlsetups xml:doc + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:pre:code + no solution + \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}} + \par + solution one \begingroup + \expandUx + \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}} + \endgroup + \par + solution two + \comment[symbol=Key, location=inmargin,color=yellow]{\xmlpure{#1}} + \par + \xmlprettyprint{#1}{tex} +\stopxmlsetups + +\xmlprocessbuffer{main}{demo}{} +\stoptyping + +The first comment (an interactive feature of \PDF\ comes out as: + +\starttyping +\Ux {5C}ConTeXt\Ux {5C} is great +\stoptyping + +The second and third comment are okay. It's one of the reasons why we have \type +{\xmlpure}. + +\stopsection + \stopchapter \stopbodymatter diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 4df664cee..30abf064a 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -10270,7 +10270,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 57426, stripped down to: 36192 +-- original size: 57611, stripped down to: 36283 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -10412,6 +10412,7 @@ local function add_empty(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=top } dt[nt]=t @@ -10433,6 +10434,7 @@ local function add_begin(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=stack[level] } setmetatable(top,mt) @@ -10459,6 +10461,7 @@ local function add_end(spacing,namespace,tag) end dt=top.dt nt=#dt+1 + toclose.ni=nt dt[nt]=toclose if toclose.at.xmlns then remove(xmlns) @@ -10504,7 +10507,13 @@ local function add_special(what,spacing,text) if strip and (what=="@cm@" or what=="@dt@") then else nt=nt+1 - dt[nt]={ special=true,ns="",tg=what,dt={ text } } + dt[nt]={ + special=true, + ns="", + tg=what, + ni=nt, + dt={ text }, + } end end local function set_message(txt) @@ -11605,7 +11614,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 53892, stripped down to: 32508 +-- original size: 54794, stripped down to: 33223 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -11696,7 +11705,6 @@ apply_axis['child']=function(list) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en end @@ -11715,7 +11723,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11741,7 +11748,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11987,6 +11993,14 @@ local function apply_expression(list,expression,order) end return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector=xml.applyselector + return apply_selector(list,specification) + else + return list + end +end local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb local spaces=S(" \n\r\t\f")^0 local lp_space=S(" \n\r\t\f") @@ -12110,6 +12124,9 @@ end local function register_nodes(nodetest,nodes) return { kind="nodes",nodetest=nodetest,nodes=nodes } end +local function register_selector(specification) + return { kind="selector",specification=specification } +end local function register_expression(expression) local converted=lpegmatch(converter,expression) local runner=load(format(template_e,converted)) @@ -12150,7 +12167,7 @@ local pathparser=Ct { "patterns", (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 ) ), protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"), - step=((V("shortcuts")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, + step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child), special=special_1+special_2+special_3, initial=(P("/")*spaces*Cc(register_initial_child))^-1, @@ -12178,6 +12195,7 @@ local pathparser=Ct { "patterns", preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling ), reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling ), last_match=P('last-match::')*Cc(register_last_match ), + selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector, nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes, expressions=expression/register_expression, letters=R("az")^1, @@ -12327,6 +12345,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) p.matched=p.matched+1 @@ -12368,6 +12388,9 @@ do elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -12399,6 +12422,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then return pi.finalizer(collected) end @@ -19058,8 +19083,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 808546 --- stripped bytes : 293656 +-- original bytes : 809633 +-- stripped bytes : 293937 -- end library merge diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 4df664cee..30abf064a 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -10270,7 +10270,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 57426, stripped down to: 36192 +-- original size: 57611, stripped down to: 36283 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -10412,6 +10412,7 @@ local function add_empty(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=top } dt[nt]=t @@ -10433,6 +10434,7 @@ local function add_begin(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=stack[level] } setmetatable(top,mt) @@ -10459,6 +10461,7 @@ local function add_end(spacing,namespace,tag) end dt=top.dt nt=#dt+1 + toclose.ni=nt dt[nt]=toclose if toclose.at.xmlns then remove(xmlns) @@ -10504,7 +10507,13 @@ local function add_special(what,spacing,text) if strip and (what=="@cm@" or what=="@dt@") then else nt=nt+1 - dt[nt]={ special=true,ns="",tg=what,dt={ text } } + dt[nt]={ + special=true, + ns="", + tg=what, + ni=nt, + dt={ text }, + } end end local function set_message(txt) @@ -11605,7 +11614,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 53892, stripped down to: 32508 +-- original size: 54794, stripped down to: 33223 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -11696,7 +11705,6 @@ apply_axis['child']=function(list) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en end @@ -11715,7 +11723,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11741,7 +11748,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11987,6 +11993,14 @@ local function apply_expression(list,expression,order) end return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector=xml.applyselector + return apply_selector(list,specification) + else + return list + end +end local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb local spaces=S(" \n\r\t\f")^0 local lp_space=S(" \n\r\t\f") @@ -12110,6 +12124,9 @@ end local function register_nodes(nodetest,nodes) return { kind="nodes",nodetest=nodetest,nodes=nodes } end +local function register_selector(specification) + return { kind="selector",specification=specification } +end local function register_expression(expression) local converted=lpegmatch(converter,expression) local runner=load(format(template_e,converted)) @@ -12150,7 +12167,7 @@ local pathparser=Ct { "patterns", (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 ) ), protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"), - step=((V("shortcuts")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, + step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child), special=special_1+special_2+special_3, initial=(P("/")*spaces*Cc(register_initial_child))^-1, @@ -12178,6 +12195,7 @@ local pathparser=Ct { "patterns", preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling ), reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling ), last_match=P('last-match::')*Cc(register_last_match ), + selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector, nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes, expressions=expression/register_expression, letters=R("az")^1, @@ -12327,6 +12345,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) p.matched=p.matched+1 @@ -12368,6 +12388,9 @@ do elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -12399,6 +12422,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then return pi.finalizer(collected) end @@ -19058,8 +19083,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 808546 --- stripped bytes : 293656 +-- original bytes : 809633 +-- stripped bytes : 293937 -- end library merge diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 4df664cee..30abf064a 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -10270,7 +10270,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 57426, stripped down to: 36192 +-- original size: 57611, stripped down to: 36283 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -10412,6 +10412,7 @@ local function add_empty(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=top } dt[nt]=t @@ -10433,6 +10434,7 @@ local function add_begin(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=stack[level] } setmetatable(top,mt) @@ -10459,6 +10461,7 @@ local function add_end(spacing,namespace,tag) end dt=top.dt nt=#dt+1 + toclose.ni=nt dt[nt]=toclose if toclose.at.xmlns then remove(xmlns) @@ -10504,7 +10507,13 @@ local function add_special(what,spacing,text) if strip and (what=="@cm@" or what=="@dt@") then else nt=nt+1 - dt[nt]={ special=true,ns="",tg=what,dt={ text } } + dt[nt]={ + special=true, + ns="", + tg=what, + ni=nt, + dt={ text }, + } end end local function set_message(txt) @@ -11605,7 +11614,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 53892, stripped down to: 32508 +-- original size: 54794, stripped down to: 33223 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -11696,7 +11705,6 @@ apply_axis['child']=function(list) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en end @@ -11715,7 +11723,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11741,7 +11748,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11987,6 +11993,14 @@ local function apply_expression(list,expression,order) end return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector=xml.applyselector + return apply_selector(list,specification) + else + return list + end +end local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb local spaces=S(" \n\r\t\f")^0 local lp_space=S(" \n\r\t\f") @@ -12110,6 +12124,9 @@ end local function register_nodes(nodetest,nodes) return { kind="nodes",nodetest=nodetest,nodes=nodes } end +local function register_selector(specification) + return { kind="selector",specification=specification } +end local function register_expression(expression) local converted=lpegmatch(converter,expression) local runner=load(format(template_e,converted)) @@ -12150,7 +12167,7 @@ local pathparser=Ct { "patterns", (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 ) ), protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"), - step=((V("shortcuts")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, + step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child), special=special_1+special_2+special_3, initial=(P("/")*spaces*Cc(register_initial_child))^-1, @@ -12178,6 +12195,7 @@ local pathparser=Ct { "patterns", preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling ), reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling ), last_match=P('last-match::')*Cc(register_last_match ), + selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector, nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes, expressions=expression/register_expression, letters=R("az")^1, @@ -12327,6 +12345,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) p.matched=p.matched+1 @@ -12368,6 +12388,9 @@ do elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -12399,6 +12422,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then return pi.finalizer(collected) end @@ -19058,8 +19083,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 808546 --- stripped bytes : 293656 +-- original bytes : 809633 +-- stripped bytes : 293937 -- end library merge diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua index 4df664cee..30abf064a 100644 --- a/scripts/context/stubs/win64/mtxrun.lua +++ b/scripts/context/stubs/win64/mtxrun.lua @@ -10270,7 +10270,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 57426, stripped down to: 36192 +-- original size: 57611, stripped down to: 36283 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -10412,6 +10412,7 @@ local function add_empty(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=top } dt[nt]=t @@ -10433,6 +10434,7 @@ local function add_begin(spacing,namespace,tag) tg=tag, at=at, dt={}, + ni=nt, __p__=stack[level] } setmetatable(top,mt) @@ -10459,6 +10461,7 @@ local function add_end(spacing,namespace,tag) end dt=top.dt nt=#dt+1 + toclose.ni=nt dt[nt]=toclose if toclose.at.xmlns then remove(xmlns) @@ -10504,7 +10507,13 @@ local function add_special(what,spacing,text) if strip and (what=="@cm@" or what=="@dt@") then else nt=nt+1 - dt[nt]={ special=true,ns="",tg=what,dt={ text } } + dt[nt]={ + special=true, + ns="", + tg=what, + ni=nt, + dt={ text }, + } end end local function set_message(txt) @@ -11605,7 +11614,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 53892, stripped down to: 32508 +-- original size: 54794, stripped down to: 33223 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -11696,7 +11705,6 @@ apply_axis['child']=function(list) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en end @@ -11715,7 +11723,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11741,7 +11748,6 @@ local function collect(list,collected,c) if dk.tg then c=c+1 collected[c]=dk - dk.ni=k en=en+1 dk.ei=en c=collect(dk,collected,c) @@ -11987,6 +11993,14 @@ local function apply_expression(list,expression,order) end return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector=xml.applyselector + return apply_selector(list,specification) + else + return list + end +end local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb local spaces=S(" \n\r\t\f")^0 local lp_space=S(" \n\r\t\f") @@ -12110,6 +12124,9 @@ end local function register_nodes(nodetest,nodes) return { kind="nodes",nodetest=nodetest,nodes=nodes } end +local function register_selector(specification) + return { kind="selector",specification=specification } +end local function register_expression(expression) local converted=lpegmatch(converter,expression) local runner=load(format(template_e,converted)) @@ -12150,7 +12167,7 @@ local pathparser=Ct { "patterns", (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 ) ), protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"), - step=((V("shortcuts")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, + step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0, axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child), special=special_1+special_2+special_3, initial=(P("/")*spaces*Cc(register_initial_child))^-1, @@ -12178,6 +12195,7 @@ local pathparser=Ct { "patterns", preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling ), reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling ), last_match=P('last-match::')*Cc(register_last_match ), + selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector, nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes, expressions=expression/register_expression, letters=R("az")^1, @@ -12327,6 +12345,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) p.matched=p.matched+1 @@ -12368,6 +12388,9 @@ do elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind=="finalizer" then collected=pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -12399,6 +12422,8 @@ do collected=apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind=="expression" then collected=apply_expression(collected,pi.evaluator,order) + elseif kind=="selector" then + collected=apply_selector(collected,pi.specification) elseif kind=="finalizer" then return pi.finalizer(collected) end @@ -19058,8 +19083,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 808546 --- stripped bytes : 293656 +-- original bytes : 809633 +-- stripped bytes : 293937 -- end library merge diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 53fe67bc2..353d27e9f 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.12.21 18:51} +\newcontextversion{2016.12.28 17:55} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index d022b1626..5e069a54d 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2016.12.21 18:51} +\edef\contextversion{2016.12.28 17:55} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index d31d880f7..9057defc3 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.12.21 18:51} +\newcontextversion{2016.12.28 17:55} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 86722cf34..1cab20d40 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.12.21 18:51} +\edef\contextversion{2016.12.28 17:55} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua index fa921b24f..b2198f341 100644 --- a/tex/context/base/mkiv/lxml-css.lua +++ b/tex/context/base/mkiv/lxml-css.lua @@ -6,10 +6,12 @@ if not modules then modules = { } end modules ['lxml-css'] = { license = "see context related readme files" } -local tonumber, rawset = tonumber, rawset -local lower, format = string.lower, string.format -local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf +local tonumber, rawset, type = tonumber, rawset, type +local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch +local topattern, is_empty = string.topattern, string.is_empty +local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local sort = table.sort xml.css = xml.css or { } local css = xml.css @@ -169,3 +171,716 @@ function css.colorspecification(str) local c = str and attributes.colors.values[tonumber(str)] return c and format("rgb(%s%%,%s%%,%s%%)",c[3]*100,c[4]*100,c[5]*100) end + +-- The following might be handy. It hooks into the normal parser as <selector> +-- and should work ok with the rest. It's sometimes even a bit faster but that might +-- change. It's somewhat optimized but not too aggressively. + +-- element-1 > element-2 : element-2 with parent element-1 + +local function s_element_a(list,collected,c,negate,str,dummy,dummy,n) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local ok = all or ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + if (not n or n > 1) and dt then + c = s_element_a(dt,collected,c,negate,str,dummy,dummy,n and n+1 or 1) + end + end + end + return c +end + +-- element-1 + element-2 : element-2 preceded by element-1 + +local function s_element_b(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dd = pp.dt + if dd then + local ni = ll.ni + local d = dd[ni+1] + local dt = d and d.dt + if not dt then + d = dd[ni+2] + dt = d and d.dt + end + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + return c +end + +-- element-1 ~ element-2 : element-2 preceded by element-1 -- ? + +local function s_element_c(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dt = pp.dt + if dt then + local ni = ll.ni + for i=ni+1,#dt do + local d = dt[i] + local dt = d.dt + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + end + return c +end + +-- element +-- element-1 element-2 : element-2 inside element-1 + +local function s_element_d(list,collected,c,negate,str) + if str == "*" then + if not negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + c = c + 1 + collected[c] = ll + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + local ok = ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + return c +end + +-- [attribute] +-- [attribute=value] equals +-- [attribute~=value] contains word +-- [attribute^="value"] starts with +-- [attribute$="value"] ends with +-- [attribute*="value"] contains + +-- .class (no need to optimize) +-- #id (no need to optimize) + +local function s_attribute(list,collected,c,negate,str,what,value) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local at = ll.at + if at then + local v = at[str] + local ok = negate + if v then + if not what then + ok = not negate + elseif what == 1 then + if v == value then + ok = not negate + end + elseif what == 2 then + -- todo: lpeg + if find(v,value) then + ok = not negate + end + elseif what == 3 then + -- todo: lpeg + if find(v," ") then + for s in gmatch(v,"[^ ]+") do + if s == value then + ok = not negate + break + end + end + elseif v == value then + ok = not negate + end + end + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_attribute(dt,collected,c,negate,str,what,value) + end + end + return c +end + +-- :nth-child(n) +-- :nth-last-child(n) +-- :first-child +-- :last-child + +local function filter_down(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + local m = a + while true do + if m > n then + break + end + if m > 0 then + t[m] = -t[m] -- sign signals match + end + m = m + b + end + if negate then + for i=n,1-1 do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=n,1,-1 do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function filter_up(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + if not b then + b = 0 + end + local m = n - a + while true do + if m < 1 then + break + end + if m < n then + t[m] = -t[m] -- sign signals match + end + m = m - b + end + if negate then + for i=1,n do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=1,n do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function just(collected,c,negate,dt,a,start,stop,step) + local m = 0 + for i=start,stop,step do + local d = dt[i] + if type(d) == "table" then + m = m + 1 + if negate then + if a ~= m then + c = c + 1 + collected[c] = d + end + else + if a == m then + c = c + 1 + collected[c] = d + break + end + end + end + end + return c +end + +local function s_nth_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_up(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,1,#dt,1) + end + end + end + return c +end + +local function s_nth_last_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_down(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,#dt,1,-1) + end + end + end + return c +end + +-- :nth-of-type(n) +-- :nth-last-of-type(n) +-- :first-of-type +-- :last-of-type + +local function s_nth_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_up(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,1,#list,1) + end +end + +local function s_nth_last_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_down(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,#list,1,-1) + end +end + +-- :only-of-type + +local function s_only_of_type(list,collected,c,negate) + if negate then + for i=1,#list do + c = c + 1 + collected[c] = list[i] + end + else + if #list == 1 then + c = c + 1 + collected[c] = list[1] + end + end + return c +end + +-- :only-child + +local function s_only_child(list,collected,c,negate) + if negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + for i=1,#dt do + local di = dt[i] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt and #dt == 1 then + local di = dt[1] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + return c +end + +-- :empty + +local function s_empty(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local dn = #dt + local ok = dn == 0 + if not ok and dn == 1 then + local d = dt[1] + if type(d) == "string" and is_empty(d) then + ok = true + end + end + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + end + return c +end + +-- :root + +local function s_root(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + if type(ll) == "table" then + local r = xml.root(ll) + if r then + if r.special and r.tg == "@rt@" then + r = r.dt[r.ri] + end + c = c + 1 + collected[c] = r + break + end + end + end + return c +end + +local P, R, S, C, Cs, Ct, Cc, Carg, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Carg, lpeg.match + +local whitespace = lpegpatterns.whitespace +local p_number = lpegpatterns.integer / tonumber +local p_space = whitespace^0 + +local p_key = C((R("az","AZ","09") + S("_-"))^1) +local p_left = S("#.[],:()") +local p_right = S("#.[],:() ") +local p_tag = C((1-p_left) * (1-p_right)^0) +local p_value = C((1-P("]"))^0) +local p_unquoted = (P('"')/"") * C((1-P('"'))^0) * (P('"')/"") + + (1-P("]"))^1 +local p_element = Ct( ( + P(">") * p_space * Cc(s_element_a) + + P("+") * p_space * Cc(s_element_b) + + P("~") * p_space * Cc(s_element_c) + + Cc(s_element_d) + ) * p_tag ) +local p_attribute = P("[") * Ct(Cc(s_attribute) * p_key * ( + P("=" ) * Cc(1) * Cs( p_unquoted) + + P("^=") * Cc(2) * Cs(Cc("^") * (p_unquoted / topattern)) + + P("$=") * Cc(2) * Cs( p_unquoted / topattern * Cc("$")) + + P("*=") * Cc(2) * Cs( p_unquoted / topattern) + + P("~=") * Cc(3) * Cs( p_unquoted) + )^0 * P("]")) + +local p_separator = p_space * P(",") * p_space + +local p_formula = p_space * P("(") + * p_space + * ( + p_number * p_space * (C("n") * p_space * (p_number + Cc(0)))^-1 + + P("even") * Cc(0) * Cc("n") * Cc(2) + + P("odd") * Cc(-1) * Cc("n") * Cc(2) + ) + * p_space + * P(")") + +local p_step = P(".") * Ct(Cc(s_attribute) * Cc("class") * Cc(3) * p_tag) + + P("#") * Ct(Cc(s_attribute) * Cc("id") * Cc(1) * p_tag) + + p_attribute + + p_element + + P(":nth-child") * Ct(Cc(s_nth_child) * p_formula) + + P(":nth-last-child") * Ct(Cc(s_nth_last_child) * p_formula) + + P(":first-child") * Ct(Cc(s_nth_child) * Cc(1)) + + P(":last-child") * Ct(Cc(s_nth_last_child) * Cc(1)) + + P(":only-child") * Ct(Cc(s_only_child) ) + + P(":nth-of-type") * Ct(Cc(s_nth_of_type) * p_formula) + + P(":nth-last-of-type") * Ct(Cc(s_nth_last_of_type) * p_formula) + + P(":first-of-type") * Ct(Cc(s_nth_of_type) * Cc(1)) + + P(":last-of-type") * Ct(Cc(s_nth_last_of_type) * Cc(1)) + + P(":only-of-type") * Ct(Cc(s_only_of_type) ) + + P(":empty") * Ct(Cc(s_empty) ) + + P(":root") * Ct(Cc(s_root) ) + +local p_not = P(":not") * Cc(true) * p_space * P("(") * p_space * p_step * p_space * P(")") +local p_yes = Cc(false) * p_space * p_step + +local p_stepper = Ct((p_space * (p_not+p_yes))^1) +local p_steps = Ct((p_stepper * p_separator^0)^1) * p_space * (P(-1) + function() print("error") end) + +local cache = table.setmetatableindex(function(t,k) + local v = lpegmatch(p_steps,k) or false + t[k] = v + return v +end) + +local function selector(root,s) + -- local steps = lpegmatch(p_steps,s) + local steps = cache[s] + if steps then + local done = { } + local collected = { } + local nofcollected = 0 + local nofsteps = #steps + for i=1,nofsteps do + local step = steps[i] + local n = #step + if n > 0 then + local r = root + local m = 0 + local c = { } + for i=1,n,2 do + local s = step[i+1] -- function + data + m = s[1](r,c,0,step[i],s[2],s[3],s[4]) + if m == 0 then + break + else + r = c + c = { } + end + end + if m > 0 then + if nofsteps > 1 then + for i=1,m do + local ri = r[i] + if done[ri] then + -- print("duplicate",i) + -- elseif ri.special then + -- done[ri] = true + else + nofcollected = nofcollected + 1 + collected[nofcollected] = ri + done[ri] = true + end + end + else + return r + end + end + end + end + if nofcollected > 1 then + -- local n = 0 + -- local function traverse(e) + -- if done[e] then + -- n = n + 1 + -- done[e] = n + -- end + -- local dt = e.dt + -- if dt then + -- for i=1,#dt do + -- local e = dt[i] + -- if type(e) == "table" then + -- traverse(e) + -- end + -- end + -- end + -- end + -- traverse(root[1]) + -- + local n = 0 + local function traverse(dt) + for i=1,#dt do + local e = dt[i] + if done[e] then + n = n + 1 + done[e] = n + if n == nofcollected then + return + end + end + local d = e.dt + if d then + traverse(d) + if n == nofcollected then + return + end + end + end + end + local r = root[1] + if done[r] then + n = n + 1 + done[r] = n + end + traverse(r.dt) + -- + sort(collected,function(a,b) return done[a] < done[b] end) + end + return collected + else + return { } + end +end + +xml.applyselector= selector + +-- local t = [[ +-- <?xml version="1.0" ?> +-- +-- <a> +-- <b class="one"> </b> +-- <b class="two"> </b> +-- <b class="one"> </b> +-- <b class="three"> </b> +-- <b id="first"> </b> +-- <c> </c> +-- <d> d e </d> +-- <e> d e </e> +-- <e> d e e </e> +-- <d> d f </d> +-- <f foo="bar"> </f> +-- <f bar="foo"> </f> +-- <f bar="foo1"> </f> +-- <f bar="foo2"> </f> +-- <f bar="foo3"> </f> +-- <f bar="foo+4"> </f> +-- <g> </g> +-- <?crap ?> +-- <!-- crap --> +-- <g> <gg> <d> </d> </gg> </g> +-- <g> <gg> <f> </f> </gg> </g> +-- <g> <gg> <f class="one"> g gg f </f> </gg> </g> +-- <g> </g> +-- <g> <gg> <f class="two"> g gg f </f> </gg> </g> +-- <g> <gg> <f class="three"> g gg f </f> </gg> </g> +-- <g> <f class="one"> g f </f> </g> +-- <g> <f class="three"> g f </f> </g> +-- <h whatever="four five six"> </h> +-- </a> +-- ]] +-- +-- local s = [[ .one ]] +-- local s = [[ .one, .two ]] +-- local s = [[ .one, .two, #first ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo] ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo], [bar~=foo] [bar^="foo"] ]] +-- local s = [[ [bar^="foo"] ]] +-- local s = [[ g f .one, g f .three ]] +-- local s = [[ g > f .one, g > f .three ]] +-- local s = [[ * ]] +-- local s = [[ d + e ]] +-- local s = [[ d ~ e ]] +-- local s = [[ d ~ e, g f .one, g f .three ]] +-- local s = [[ :not(d) ]] +-- local s = [[ [whatever~="five"] ]] +-- local s = [[ :not([whatever~="five"]) ]] +-- local s = [[ e ]] +-- local s = [[ :not ( e ) ]] +-- local s = [[ a:nth-child(3) ]] +-- local s = [[ a:nth-child(3n+1) ]] +-- local s = [[ a:nth-child(2n+8) ]] +-- local s = [[ g:nth-of-type(3) ]] +-- local s = [[ a:first-child ]] +-- local s = [[ a:last-child ]] +-- local s = [[ e:first-of-type ]] +-- local s = [[gg d:only-of-type ]] +-- local s = [[ a:nth-child(even) ]] +-- local s = [[ a:nth-child(odd) ]] +-- local s = [[ g:empty ]] +-- local s = [[ g:root ]] + +function css.applyselector(x,str) + -- the wrapping needs checking so this is a placeholder + return applyselector({ x },str) +end + +-- local c = css.applyselector(xml.convert(t),s) for i=1,#c do print(xml.tostring(c[i])) end + diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua index 7ee1db1d8..19d69076a 100644 --- a/tex/context/base/mkiv/lxml-lpt.lua +++ b/tex/context/base/mkiv/lxml-lpt.lua @@ -177,7 +177,7 @@ apply_axis['child'] = function(list) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en end @@ -197,7 +197,7 @@ local function collect(list,collected,c) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en c = collect(dk,collected,c) @@ -225,7 +225,7 @@ local function collect(list,collected,c) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en c = collect(dk,collected,c) @@ -518,6 +518,15 @@ local function apply_expression(list,expression,order) return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector = xml.applyselector + return apply_selector(list,specification) + else + return list + end +end + -- this one can be made faster but there are not that many conversions so it doesn't -- really pay of @@ -717,6 +726,10 @@ local function register_nodes(nodetest,nodes) return { kind = "nodes", nodetest = nodetest, nodes = nodes } end +local function register_selector(specification) + return { kind = "selector", specification = specification } +end + local function register_expression(expression) local converted = lpegmatch(converter,expression) local runner = load(format(template_e,converted)) @@ -775,7 +788,7 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p -- the / is needed for // as descendant or self is somewhat special -- -- step = (V("shortcuts") + V("axis") * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, - step = ((V("shortcuts") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, + step = ((V("shortcuts") + V("selector") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, axis = V("last_match") + V("descendant") @@ -838,6 +851,8 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p reverse_sibling = P('reverse-sibling::') * Cc(register_reverse_sibling ), last_match = P('last-match::') * Cc(register_last_match ), + selector = P("{") * C((1-P("}"))^1) * P("}") / register_selector, + nodes = (V("nodefunction") * spaces * P("(") * V("nodeset") * P(")") + V("nodetest") * V("nodeset")) / register_nodes, expressions = expression / register_expression, @@ -1026,6 +1041,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) -- no check on # here p.matched = p.matched + 1 @@ -1068,6 +1085,9 @@ do elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -1100,6 +1120,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then return pi.finalizer(collected) end diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua index 209dec7f9..64322e4d0 100644 --- a/tex/context/base/mkiv/lxml-tab.lua +++ b/tex/context/base/mkiv/lxml-tab.lua @@ -264,6 +264,7 @@ local function add_empty(spacing, namespace, tag) tg = tag, at = at, dt = { }, + ni = nt, __p__ = top } dt[nt] = t @@ -285,7 +286,8 @@ local function add_begin(spacing, namespace, tag) rn = resolved, tg = tag, at = at, - dt = {}, + dt = { }, + ni = nt, -- preset slot __p__ = stack[level] } setmetatable(top, mt) @@ -313,6 +315,7 @@ local function add_end(spacing, namespace, tag) end dt = top.dt nt = #dt + 1 + toclose.ni = nt dt[nt] = toclose -- dt[0] = top -- nasty circular reference when serializing table if toclose.at.xmlns then @@ -370,7 +373,13 @@ local function add_special(what, spacing, text) -- forget it else nt = nt + 1 - dt[nt] = { special=true, ns="", tg=what, dt={ text } } + dt[nt] = { + special = true, + ns = "", + tg = what, + ni = nt, + dt = { text }, + } end end diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua index f6650dd4d..f57efa9a1 100644 --- a/tex/context/base/mkiv/publ-dat.lua +++ b/tex/context/base/mkiv/publ-dat.lua @@ -43,9 +43,11 @@ local p_utf8character = lpegpatterns.utf8character local trace = false trackers.register("publications", function(v) trace = v end) local trace_duplicates = true trackers.register("publications.duplicates", function(v) trace = v end) +local trace_strings = false trackers.register("publications.strings", function(v) trace = v end) local report = logs.reporter("publications") local report_duplicates = logs.reporter("publications","duplicates") +local report_strings = logs.reporter("publications","strings") local allocate = utilities.storage.allocate @@ -537,8 +539,28 @@ do luadata[hashtag] = entries end + local f_invalid = formatters["<invalid: %s>"] + local function resolve(s,dataset) - return dataset.shortcuts[s] or defaultshortcuts[s] or s -- can be number + local e = dataset.shortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to %a",s,e) + end + return e + end + e = defaultshortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to default %a",s,e) + end + return e + end + if tonumber(s) then + return s + end + report("error in database, invalid value %a",s) + return f_invalid(s) end local pattern = p_whitespace^0 @@ -600,28 +622,23 @@ do local unbalanced = (left/"") * balanced * (right/"") * P(-1) - local reference = P("@") * C((R("az","AZ","09") + S("_:-"))^1) + local reference = C((R("az","AZ","09") + S("_:-"))^1) local b_value = p_left * balanced * p_right - -- local u_value = p_left * unbalanced * p_right -- get rid of outer { } - -- local s_value = (single/"") * (u_value + s_quoted) * (single/"") - -- local d_value = (double/"") * (u_value + d_quoted) * (double/"") local s_value = (single/"") * (unbalanced + s_quoted) * (single/"") local d_value = (double/"") * (unbalanced + d_quoted) * (double/"") - local r_value = reference * Carg(1) / resolve + local r_value = P("@") * reference * Carg(1) / resolve + + reference * Carg(1) / resolve + local n_value = C(R("09")^1) --- local e_value = (1-S(",}"))^0 / function(s) - local e_value = Cs((left * balanced * right + (1 - S(",}")))^0) / function(s) - report("error in database, invalid value %a",s) - return "[invalid: " .. s .. "]" + local e_value = Cs((left * balanced * right + (1 - S(",}")))^0) * Carg(1) / function(s,dataset) + return resolve(s,dataset) end - local somevalue = d_value + b_value + s_value + r_value + e_value + local somevalue = d_value + b_value + s_value + r_value + n_value + e_value local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0)) local stripper = lpegpatterns.stripper - value = value / function(s) - return lpegmatch(stripper,s) - end + value = value / function(s) return lpegmatch(stripper,s) end local forget = percent^1 * (1-lineending)^0 local spacing = spacing * forget^0 * spacing diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 0a9d95fef..d5f616baf 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex b7090d2a8..419d34320 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 0f76a4ac2..4fac278b4 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 5a55f45de..b284c4966 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index c503add27..f5339a3b7 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 12/21/16 18:51:59 +-- merge date : 12/28/16 17:55:48 do -- begin closure to overcome local limits and interference |