diff options
56 files changed, 1618 insertions, 350 deletions
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf Binary files differindex 1e567c32c..032c5b1b6 100644 --- a/doc/context/documents/general/manuals/luatex.pdf +++ b/doc/context/documents/general/manuals/luatex.pdf diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf Binary files differindex c56cd345f..02343be47 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 a4855a815..0b516d013 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 38cd62221..aa46a705e 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 cd8a5389a..d129d2ac8 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 b97b54303..4c881adce 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-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf Binary files differindex 57c0b85ac..a901f72f5 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf Binary files differindex 64624e151..ae003afed 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf Binary files differindex e8dc8fc57..fb3776d3a 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf Binary files differindex e413b5efe..d5ec100ab 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf Binary files differindex 870585eae..3a48e7b63 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf Binary files differindex 5b2e7e809..e103eb66a 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf Binary files differindex 8c92bf7da..a7be6b1b4 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf Binary files differindex 46b323eab..fec41eb5b 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 d9ffcff03..901c93588 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/about/about-metafun.tex b/doc/context/sources/general/manuals/about/about-metafun.tex index d289dd803..bc298e995 100644 --- a/doc/context/sources/general/manuals/about/about-metafun.tex +++ b/doc/context/sources/general/manuals/about/about-metafun.tex @@ -727,15 +727,15 @@ We load the data in datasets: \startbuffer \startMPcode - lua.mp.datasets.load("foo","foo.tmp") ; - lua.mp.datasets.load("bar","bar.tmp") ; + lua.mp.datasets("load","foo","foo.tmp") ; + lua.mp.datasets("load","bar","bar.tmp") ; fill area - lua.mp.datasets.foo.Line() + lua.mp.datasets("foo","line") xysized (HSize/2-EmWidth,10ExHeight) withpen pencircle scaled .25ExHeight withcolor green/2 ; fill area - lua.mp.datasets.bar.Line() + lua.mp.datasets("bar","line") xysized (HSize/2-EmWidth,10ExHeight) shifted (HSize/2+EmWidth,0) withpen pencircle scaled .25ExHeight @@ -755,8 +755,8 @@ following is valid: \starttyping \startMPcode - lua.mp.datasets.load("foo.tmp") ; - lua.mp.datasets.load("bar.tmp") ; + lua.mp.datasets("load","foo.tmp") ; + lua.mp.datasets("load","bar.tmp") ; \stopMPcode \stoptyping diff --git a/doc/context/sources/general/manuals/luatex/luatex-lua.tex b/doc/context/sources/general/manuals/luatex/luatex-lua.tex index bc06596db..e9007e964 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-lua.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-lua.tex @@ -345,17 +345,17 @@ returns the name. \stopsubsection -\startsubsection[title={Multibyte \type {string} functions}][library=string] - -\libindex{utfvalues} -\libindex{utfcharacters} -\libindex{characters} -\libindex{characterpairs} -\libindex{bytes} -\libindex{bytepairs} -\libindex{utfvalue} -\libindex{utfcharacter} -\libindex{utflength} +\startsubsection[title={Multibyte \type {string} functions}] + +\libidx{string}{utfvalues} +\libidx{string}{utfcharacters} +\libidx{string}{characters} +\libidx{string}{characterpairs} +\libidx{string}{bytes} +\libidx{string}{bytepairs} +\libidx{string}{utfvalue} +\libidx{string}{utfcharacter} +\libidx{string}{utflength} The \type {string} library has a few extra functions like \type {string.explode(s[,m])}. This function returns an array containing the string @@ -437,19 +437,19 @@ as building blocks for other helpers. So, eventually we can decide to drop the \stopsubsection -\startsubsection[title={Extra \type {os} library functions}][library=os] +\startsubsection[title={Extra \type {os} library functions}] -\libindex{selfdir} -\libindex{exec} -\libindex{spawn} -\libindex{setenv} -\libindex{env} -\libindex{gettimeofday} -\libindex{times} -\libindex{tmpdir} -\libindex{type} -\libindex{name} -\libindex{uname} +\libidx{os}{selfdir} +\libidx{os}{exec} +\libidx{os}{spawn} +\libidx{os}{setenv} +\libidx{os}{env} +\libidx{os}{gettimeofday} +\libidx{os}{times} +\libidx{os}{tmpdir} +\libidx{os}{type} +\libidx{os}{name} +\libidx{os}{uname} The \type {os} library has a few extra functions and variables: @@ -583,29 +583,29 @@ The \type {os} library has a few extra functions and variables: \stopsubsection -\startsubsection[title={Binary input from files with \type {fio}}][library=fio] - -\libindex{readcardinal1} -\libindex{readcardinal2} -\libindex{readcardinal3} -\libindex{readcardinal4} -\libindex{readcardinaltable} -\libindex{readinteger1} -\libindex{readinteger2} -\libindex{readinteger3} -\libindex{readinteger4} -\libindex{readintegertable} -\libindex{readfixed2} -\libindex{readfixed4} -\libindex{read2dot14} -\libindex{setposition} -\libindex{getposition} -\libindex{skipposition} -\libindex{readbytes} -\libindex{readbytetable} -%libindex{readline} -%libindex{recordfilename} -%libindex{checkpermission} +\startsubsection[title={Binary input from files with \type {fio}}] + +\libidx{fio}{readcardinal1} +\libidx{fio}{readcardinal2} +\libidx{fio}{readcardinal3} +\libidx{fio}{readcardinal4} +\libidx{fio}{readcardinaltable} +\libidx{fio}{readinteger1} +\libidx{fio}{readinteger2} +\libidx{fio}{readinteger3} +\libidx{fio}{readinteger4} +\libidx{fio}{readintegertable} +\libidx{fio}{readfixed2} +\libidx{fio}{readfixed4} +\libidx{fio}{read2dot14} +\libidx{fio}{setposition} +\libidx{fio}{getposition} +\libidx{fio}{skipposition} +\libidx{fio}{readbytes} +\libidx{fio}{readbytetable} +%libidx{fio}{readline} +%libidx{fio}{recordfilename} +%libidx{fio}{checkpermission} This library provides a set of functions for reading numbers from a file and in addition to the regular \type {io} library functions. @@ -633,37 +633,37 @@ in addition to the regular \type {io} library functions. \stopsubsection -\startsubsection[title={Binary input from strings with \type {sio}}][library=sio] - -\libindex{readcardinal1} -\libindex{readcardinal2} -\libindex{readcardinal3} -\libindex{readcardinal4} -\libindex{readcardinaltable} -\libindex{readinteger1} -\libindex{readinteger2} -\libindex{readinteger3} -\libindex{readinteger4} -\libindex{readintegertable} -\libindex{readfixed2} -\libindex{readfixed4} -\libindex{read2dot14} -\libindex{setposition} -\libindex{getposition} -\libindex{skipposition} -\libindex{readbytes} -\libindex{readbytetable} +\startsubsection[title={Binary input from strings with \type {sio}}] + +\libidx{sio}{readcardinal1} +\libidx{sio}{readcardinal2} +\libidx{sio}{readcardinal3} +\libidx{sio}{readcardinal4} +\libidx{sio}{readcardinaltable} +\libidx{sio}{readinteger1} +\libidx{sio}{readinteger2} +\libidx{sio}{readinteger3} +\libidx{sio}{readinteger4} +\libidx{sio}{readintegertable} +\libidx{sio}{readfixed2} +\libidx{sio}{readfixed4} +\libidx{sio}{read2dot14} +\libidx{sio}{setposition} +\libidx{sio}{getposition} +\libidx{sio}{skipposition} +\libidx{sio}{readbytes} +\libidx{sio}{readbytetable} A similar set of function as in the \type {fio} library is available in the \type {sio} library. Here the first argument is a string. \stopsubsection -\startsubsection[title={Hashes conform \type {sha2}}][library=sha2] +\startsubsection[title={Hashes conform \type {sha2}}] -\libindex{digest256} -\libindex{digest384} -\libindex{digest512} +\libidx{sha2}{digest256} +\libidx{sha2}{digest384} +\libidx{sha2}{digest512} This library is a side effect of the \type {pdfe} library that needs such helpers. The \type {digest256}, \type {digest384} and \type {digest512} functions diff --git a/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/doc/context/sources/general/manuals/metafun/metafun-lua.tex index da35cccde..0794fc879 100644 --- a/doc/context/sources/general/manuals/metafun/metafun-lua.tex +++ b/doc/context/sources/general/manuals/metafun/metafun-lua.tex @@ -263,7 +263,7 @@ There are several ways to deal with this table. I will show clumsy as well as better looking ways. \startbuffer -lua("MP = { } MP.data = table.load('demo-data.lua')") ; +lua("MP.data = table.load('demo-data.lua')") ; numeric n ; lua("mp.print('n := ',\#MP.data)") ; for i=1 upto n : @@ -524,17 +524,23 @@ The \type {mp} namespace provides the following helpers: \starttabulate[|l|l|] \HL -\NC \type {print(...)} \NC returns one or more values \NC \NR -\NC \type {pair(x,y)} - \type {pair(t)} \NC returns a proper pair \NC \NR -\NC \type {triplet(x,y,z)} - \type {triplet(t)} \NC returns an \RGB\ color \NC \NR -\NC \type {quadruple(w,x,y,z)} - \type {quadruple(t)} \NC returns an \CMYK\ color \NC \NR -\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR +\NC \type {print(...)} \NC returns one or more values \NC \NR +\NC \type {fprint(fmt,...)} \NC returns a formatted result \NC \NR +\NC \type {boolean(b)} \NC returns \type {true} or \type {false} \NC \NR +\NC \type {numeric(f)} \NC returns a floating point number \NC \NR +\NC \type {integer(i)} \NC returns a whole number \NC \NR +\NC \type {points(i)} \NC returns a floating point with unit \type {pt} \NC \NR +\NC \type {pair(x,y)|(t)} \NC returns a proper pair \NC \NR +\NC \type {pairpoints(x,y)|(t)} \NC returns a proper pair with unit \type {pt} \NC \NR +\NC \type {triplet(x,y,z)|(t)} \NC returns a \RGB\ color \NC \NR +\NC \type {tripletpoints(x,y,z)|(t)} \NC returns a \RGB\ color but with unit \type {pt} \NC \NR +\NC \type {quadruple(w,x,y,z)|(t)} \NC returns a \CMYK\ color \NC \NR +\NC \type {quadruplepoints(w,x,y,z)|(t)} \NC returns a \CMYK\ color but with unit \type {pt} \NC \NR +\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR \NC \type {quoted(fmt,...)} - \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR -\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR + \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR +\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR +\NC \type {pathpoints(t[,connect][,close])} \NC returns a connected (closed) path with units \type {pt} \NC \NR \HL \stoptabulate @@ -780,15 +786,15 @@ We load the data in datasets: \startbuffer \startMPcode - lua.mp.datasets.load("foo","foo.tmp") ; - lua.mp.datasets.load("bar","bar.tmp") ; + lua.mp.datasets("load","foo","foo.tmp") ; + lua.mp.datasets("load","bar","bar.tmp") ; fill area - lua.mp.datasets.foo.Line() + lua.mp.datasets("foo","line") xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight) withpen pencircle scaled .25ExHeight withcolor darkyellow ; fill area - lua.mp.datasets.bar.Line() + lua.mp.datasets("bar","line") xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight) shifted (HSize/2+EmWidth,0) withpen pencircle scaled .25ExHeight @@ -798,7 +804,7 @@ We load the data in datasets: \typebuffer -Because the datasets are stores by name we can use them without worrying about +Because the datasets are stored by name we can use them without worrying about them being forgotten: \startlinecorrection[blank] \getbuffer \stoplinecorrection @@ -808,8 +814,8 @@ valid: \starttyping \startMPcode - lua.mp.datasets.load("foo.tmp") ; - lua.mp.datasets.load("bar.tmp") ; + lua.mp.datasets("load","foo.tmp") ; + lua.mp.datasets("load","bar.tmp") ; \stopMPcode \stoptyping @@ -819,9 +825,9 @@ The following methods are defined for a dataset: \HL \NC \type {method} \NC usage \NC \NR \HL -\NC \type {Size} \NC the number of subsets in a dataset \NC \NR -\NC \type {Line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR -\NC \type {Data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR +\NC \type {size} \NC the number of subsets in a dataset \NC \NR +\NC \type {line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR +\NC \type {data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR \HL \stoptabulate @@ -847,7 +853,7 @@ passvariable("triplet",(1/1,1/2,1/3)) ; passvariable("quad",(1.1,2.2,3.3,4.4)) ; passvariable("boolean",false) ; passvariable("path",fullcircle scaled 1cm) ; -path p[] ; p[1] := fullcircle ; p[2] := fullsquare ; +save p ; path p[] ; p[1] := fullcircle ; p[2] := fullsquare ; passarrayvariable("list",p,1,2,1) ; % first last step \stopMPcalculation \stopbuffer @@ -943,6 +949,533 @@ serialization. \stopsection +\startsection[title={Interference}] + +In this section we will discuss a potential conflict with other mechanisms, +especially primitives and macros. A simple example of using the interface is: + +\startbuffer +\startluacode +function MP.AnExample(str) + mp.aux.quoted(string.reverse(str)) +end +\stopluacode + +\startMPcode +draw textext(lua.MP.AnExample("Hi there!")) + rotated 45 + ysized 2cm ; +\stopMPcode +\stopbuffer + +\typebuffer + +\startlinecorrection +\getbuffer +\stoplinecorrection + +The \type {mp} namespace is reserved for functionality provided by \CONTEXT\ +itself so you should not polute it with your own code. Instead use the \type {MP} +namespace and mix in some uppercase characters. + +Here you see a subnamespace \type {aux} which is where officially the helpers are +organized but they are also accessible directly (as shown in previous sections). +The reason for the \type {aux} namespace is, apart from propection aginst +redefinition, also that we have \type {get} and \type {set} namespaces and there +might be more in the future. At the \LUA\ end you can best use these namespaces +because they are less likely to be accidentally overwritten by user code. + +As mentioned, there can still be conflicts. For instance the following will not +work: + +\startbuffer +\startluacode +function MP.reverse(str) + mp.aux.quoted(string.reverse(str)) +end +\stopluacode + +\startMPcode +draw textext(lua.MP.reverse("Hi there!")) + rotated -45 + ysized 2cm ; +\stopMPcode +\stopbuffer + +\typebuffer + +% \startlinecorrection +% \getbuffer +% \stoplinecorrection + +The reason is that \type {reverse} gets expanded as part of parsing the macro +name and this command expects an expression. A way out of this is the following: + +\startbuffer +\startluacode +function MP.reverse(str) + mp.aux.quoted(string.reverse(str)) +end +\stopluacode + +\startMPcode +draw textext(lua.MP("reverse","Hi there!")) + rotated -45 + ysized 2cm ; +\stopMPcode +\stopbuffer + +\typebuffer + +\startlinecorrection +\getbuffer +\stoplinecorrection + +You can add litle bit of protection for your own code by using a prefix in the +name, like: + +\startbuffer +\startluacode +MP["mynamespace.reverse"] = function(str) + mp.aux.quoted(string.reverse(str)) +end +\stopluacode + +\startMPcode +draw textext(lua.MP("mynamespace.reverse","Hi there!")) + rotated -90 + ysized 2cm ; +\stopMPcode +\stopbuffer + +\typebuffer + +\startlinecorrection +\getbuffer +\stoplinecorrection + +\stopsection + +\startsection[title=Predefined properties] + +As mentioned, the \type {mp} namespace is reserved for commands that come +with the \CONTEXT|-|\METAFUN\ combination. For instance, a lot of layout +related calls are there:: + +\startcolumns[n=3] +\starttyping +BackSpace +BaseLineSkip +BodyFontSize +BottomDistance +BottomHeight +BottomSpace +CurrentColumn +CurrentHeight +CurrentWidth +CutSpace +EmWidth +ExHeight +FooterDistance +FooterHeight +HeaderDistance +HeaderHeight +InnerEdgeDistance +InnerEdgeWidth +InnerMarginDistance +InnerMarginWidth +LastPageNumber +LayoutColumnDistance +LayoutColumns +LayoutColumnWidth +LeftEdgeDistance +LeftEdgeWidth +LeftMarginDistance +LeftMarginWidth +LineHeight +MakeupHeight +MakeupWidth +NOfColumns +NOfPages +NOfPages +NOfSubPages +OuterEdgeDistance +OuterEdgeWidth +OuterMarginDistance +OuterMarginWidth +PageDepth +PageFraction +PageNumber +PageNumber +PageOffset +PaperBleed +PaperHeight +PaperWidth +PrintPaperHeight +PrintPaperWidth +RealPageNumber +RealPageNumber +RightEdgeDistance +RightEdgeWidth +RightMarginDistance +RightMarginWidth +SpineWidth +StrutDepth +StrutHeight +SubPageNumber +TextHeight +TextWidth +TopDistance +TopHeight +TopSkip +TopSpace +\stoptyping +\stopcolumns + +There all return dimensions, contrary to the next few that return a boolean: + +\startcolumns[n=3] +\starttyping +OnRightPage +OnOddPage +InPageBody +\stoptyping +\stopcolumns + +There are also calls related to backgrounds: + +\startcolumns[n=3] +\starttyping +OverlayWidth +OverlayHeight +OverlayDepth +OverlayLineWidth +OverlayOffset +\stoptyping +\stopcolumns + +And one related to color: + +\startcolumns[n=3] +\starttyping +NamedColor +\stoptyping +\stopcolumns + +In most cases such \type {lua.mp.command()} calls have a \METAPOST\ macro with +the same name defined. + +\stopsection + +\startsection[title=Large paths] + +The plugins (like those dealing with text) also use calls in the \type {mp} +namespace but they have sort of protected names, starting with \type {mf_}. These +are visible but not meant to be used by users. Not only can their name change, +their functionality can as well. + +The following are actually private as they have related macros but also have a +public alias: + +\startlines +lua.mp.pathlength(name) +lua.mp.pathpoint(i) +lua.mp.pathleft(i) +lua.mp.pathright(i) +lua.mp.pathreset() +\stoplines + +They are meant for special high|-|performance path access, for example: + +\startlinecorrection +\startMPcode + save p, q, r; + path p ; p := for i=1 upto 1000 : + (i,0) -- (i,4 + uniformdeviate 4) -- + endfor cycle ; + fill p xysized (TextWidth,20mm) withcolor red ; + + path q ; q := for i=1 upto lua.mp.pathlength("p") : + if (i mod 4) == 0 : lua.mp.pathpoint(i) -- fi + endfor cycle ; + fill q xysized (TextWidth,2cm) shifted (0,-45mm) withcolor green ; + + path r ; r := for i inpath p : + if not odd (i) : pointof i -- fi + endfor cycle ; + fill r xysized (TextWidth,2cm) shifted (0,-70mm) withcolor blue ; +\stopMPcode +\stoplinecorrection + +Because a lookup of a point in \METAPOST\ is a linear lookup over a linked list +for very large paths the gain is significant when using \LUA\ because there the +points are stored in an indexed table. The left and right points can be used +vebose like + +\starttyping +lua.mp.pathpoint(i) controls lua.mp.pathleft(i) and lua.mp.pathright(i) +\stoptyping + +or more terse: + +\starttyping +pointof i controls leftof i and rightof i +\stoptyping + +Beware: this kind of trickery is {\em only} needed when you have very large paths +that are to be manipulated and the. Otherwise it's overkill. + +\stopsection + +\startsection[title={Interfacing to \TEX}] + +The next bunch of calls is for accessing \TEX\ registers. You can set their +values and get them as well. + +\starttyping +lua.mp.getmacro(k) +lua.mp.getdimen(k) +lua.mp.getcount(k) +lua.mp.gettoks (k) + +lua.mp.setmacro(k,v) +lua.mp.setdimen(k,v) +lua.mp.setcount(k,v) +lua.mp.settoks (k,v) +\stoptyping + +When you mess around with variables and run into issues it might help to +report values on the console. The \type {report} function does this: + +\starttyping +lua.mp.report(a,b) +\stoptyping + +\startlinecorrection +\startMPcode +lua.mp.report("status","a circle") ; +fill fullcircle xyscaled (2cm,1cm) withcolor red ; +lua.mp.report("status","its boundingbox [@N,@N,@N,@N]", + xpart llcorner currentpicture, ypart llcorner currentpicture, + xpart urcorner currentpicture, ypart urcorner currentpicture +) ; +draw boundingbox currentpicture withcolor blue ; +report("status","the size: @Nbp x @Nbp", + bbwidth(currentpicture), bbheight(currentpicture) +) ; +message("done") ; +\stopMPcode +\stoplinecorrection + +The console shows: + +\starttyping +metapost > status : a circle +metapost > status : its boundingbox [-28.34645,-14.17323,28.34645,14.17323] +metapost > status : the size: 57.1929bp x 28.84647bp +metapost > message : done +\stoptyping + +There are two more getters. These can be used to access the specific graphic +related variables set at the \TEX\ end. + +\starttyping +mp.texvar(name) +mp.texstr(name) +\stoptyping + +If you have adaptive styles you might want to test for modes. + +\starttyping +if lua.mp.mode("screen") : % or processingmode + % some action only needed for screen documents +fi ; +if lua.mp.systemmode("first") : + % some action for the first run +fi ; +\stoptyping + +For convenience these are wrapped into macros: + +\starttyping +if texmode("screen") : + % some action only needed for screen documents +fi ; +if systemmode("first") : + % some action for the first run +fi ; +\stoptyping + +When you implement your own helpers you can fall back on some auxiliary functions +in the \type {mp} namespace. Actually these are collected in \type {mp.aux} and +thereby protected from being overwritten by mistake. Here they are: + +% mp.flush() +% mp.size(t) + +\stopsection + +\startsection[title={Interfacing to \METAPOST}] + +There is also experimental access to some of the \METAPOST\ internals. In order +to deal with (large) paths a few more iterator related helpers are provided too. + +% mp.set (numeric string path boolean) + +\starttyping +n = mp.getnumeric(name) +s = mp.getstring(name) +b = mp.getboolean(name) +p = mp.getpath(name) +\stoptyping + +A is path a table of tables that have six values: the coordinates and the +pre- and postcontrol. You can manipulate this table and feed it back into +\METAPOST. + +\startlinecorrection +\startMPcode +numeric n ; n := lua.mp.newhash() ; + +for i=1 upto 3 : + lua.mp.tohash(n,i) ; +endfor ; + +fill fullcircle scaled 10mm withcolor + if lua.mp.inhash(n,3) : green else : red fi ; + +fill fullcircle scaled 5mm withcolor + if lua.mp.inhash(n,4) : green else : red fi ; + +lua.mp.disposehash(n) +\stopMPcode +\stoplinecorrection + +You can also store values with keys and access them later: + +\startlinecorrection +\startMPcode +numeric n ; n := lua.mp.newhash() ; + +for i=1 upto 3 : + lua.mp.tohash(n,i,decimal sqrt(i)) ; +endfor ; + +draw textext(lua.mp.fromhash(n,3)) + ysized 1cm + withcolor blue ; + +lua.mp.disposehash(n) +\stopMPcode +\stoplinecorrection + +You can also name your own hash: + +\startlinecorrection +\startMPcode +lua.mp.newhash("foo") ; + +for i=1 upto 3 : + lua.mp.tohash("foo",i,decimal sqrt(i)) ; +endfor ; + +draw textext(lua.mp.fromhash("foo",2)) + ysized 1cm + withcolor green ; + +lua.mp.disposehash("foo") +\stopMPcode +\stoplinecorrection + +Although it might look like \METAPOST\ supports arrays the reality is that it +doesn't really. There is a concept of suffixes but internally these are just a +way to compose macros. The following test is one that is used in one of the +\METAFUN\ modules written by Alan Braslau. + +\startlinecorrection +\startMPcode +path p, q[] ; + +if lua.mp.isarray(str q[1]) : + fill fullcircle scaled 1cm withcolor red ; + draw textext(lua.mp.prefix(str q[1])) withcolor white; +else : + fill fullsquare scaled 1cm withcolor blue ; +fi ; + +currentpicture := currentpicture shifted (-2cm,0) ; + +if lua.mp.isarray(str p) : + fill fullcircle scaled 1cm withcolor red ; +else : + fill fullsquare scaled 1cm withcolor blue ; +fi ; +\stopMPcode +\stoplinecorrection + +Another helper relates to extensions that \METAFUN\ adds to \METAPOST. When you +iterate over a picture you can recognize these as objects. The next code shows +the \LUA\ call as well as the more convenient macro call. So, \type {textext} +clearly is a foreign object. + +\startlinecorrection +\startMPcode +picture p ; p := image ( + fill fullcircle scaled 1cm withcolor red ; + draw textext("ok") withcolor white ; +) ; + +for i within p : + if not picture i : + draw i ysized 4cm ; + elseif isobject i : + draw i xsized 3cm ; + else : + draw i ysized 4cm ; + fi ; +endfor ; + +currentpicture := currentpicture shifted (-6cm,0) ; + +for i within p : + if isobject(i) : + draw i xsized 5cm ; + else : + draw i ysized 3cm withcolor blue; + fi ; +endfor ; +\stopMPcode +\stoplinecorrection + +% not yet, still experimental: +% +% mp.dataset(str) +% mp.n(t) + +% not for users: +% +% mp.defaultcolormodel() + +% rather specialized: +% +% mp.positionpath(name) +% mp.positioncurve(name) +% mp.positionbox(name) +% mp.positionxy(name) +% mp.positionpage(name) +% mp.positionregion(name) +% mp.positionwhd(name) +% mp.positionpxy(name) +% mp.positionanchor() + + +% mp.cleaned +% mp.format(fmt,str) +% mp.formatted(fmt,...) +% mp.graphformat(fmt,num) + +\stopsection + \stopchapter % \startMPcode{doublefun} @@ -1055,6 +1588,4 @@ serialization. % % \ctxcommand{mprunvar("x")} -\stoptext - - +\stopcomponent diff --git a/scripts/context/lua/mtx-pdf.lua b/scripts/context/lua/mtx-pdf.lua index a6364cfc9..ad115637b 100644 --- a/scripts/context/lua/mtx-pdf.lua +++ b/scripts/context/lua/mtx-pdf.lua @@ -179,7 +179,7 @@ local function getunicodes(font) end for s in gmatch(cid,"beginbfchar%s*(.-)%s*endbfchar") do for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do - indices[old] = true + indices[tonumber(old,16)] = true for n in gmatch(new,"....") do local c = tonumber(n,16) counts[c] = counts[c] + 1 diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index b3af30ada..9517e6bb4 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{2018.07.13 09:47} +\newcontextversion{2018.07.17 17:25} %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 d0b75b26e..f95afa0af 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{2018.07.13 09:47} +\edef\contextversion{2018.07.17 17:25} %D For those who want to use this: diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua index 94f33791f..d993b6da0 100644 --- a/tex/context/base/mkiv/back-exp.lua +++ b/tex/context/base/mkiv/back-exp.lua @@ -67,6 +67,7 @@ local attributes = attributes local variables = interfaces.variables local v_yes = variables.yes local v_no = variables.no +local v_xml = variables.xml local v_hidden = variables.hidden local implement = interfaces.implement @@ -568,6 +569,7 @@ do implement { name = "ignoretagsinexport", + arguments = "string", actions = function(list) for tag in string.gmatch(list,"[a-z]+") do if ignoredelements then @@ -577,13 +579,56 @@ do end end end, - arguments = "string" } end do + local marginanchors = { } + local margincontent = { } + + implement { + name = "settagmargintext", + arguments = "integer", + actions = function(n) + marginanchors[locatedtag("margintext")] = n + end + } + + implement { + name = "settagmarginanchor", + arguments = "integer", + actions = function(n) + marginanchors[locatedtag("marginanchor")] = n + end + } + + function checks.margintext(di) + local i = marginanchors[di.fulltag] + margincontent[i] = di + end + + function checks.marginanchor(di) + local i = marginanchors[di.fulltag] + local d = margincontent[i] + -- + di.attribute = d.attribute + di.data = d.data + di.detail = d.detail + di.element = d.element + di.fulltag = d.fulltag + di.nature = d.nature + di.samepar = true + di.tg = d.tg + -- + d.skip = "ignore" + end + +end + +do + local symbols = { } function structurestags.settagdelimitedsymbol(symbol) @@ -1758,6 +1803,25 @@ end do + local registered = { } + + function structurestags.setformulacontent(n) + registered[locatedtag("formulacontent")] = { + n = n, + } + end + + function extras.formulacontent(di,element,n,fulltag) + local r = registered[fulltag] + if r then + setattribute(di,"n",r.n) + end + end + +end + +do + local registered = structures.sections.registered local function resolve(di,element,n,fulltag) @@ -1859,7 +1923,7 @@ do end end - local function ignorebreaks(di,element,n,fulltag) + function extras.registerpages(di,element,n,fulltag) -- ignorebreaks local data = di.data for i=1,#data do local d = data[i] @@ -1869,7 +1933,7 @@ do end end - local function ignorespaces(di,element,n,fulltag) + function extras.registerseparator(di,element,n,fulltag) -- ignorespaces local data = di.data for i=1,#data do local d = data[i] @@ -1880,9 +1944,6 @@ do end end - extras.registerpages = ignorebreaks - extras.registerseparator = ignorespaces - end do @@ -2060,7 +2121,7 @@ do local depth = 0 local inline = 0 - local function emptytag(result,embedded,element,nature,di) -- currently only break but at some point + local function emptytag(result,element,nature,di) -- currently only break but at some point local a = di.attributes -- we might add detail etc if a then -- happens seldom if nature == "display" then @@ -2109,7 +2170,7 @@ do end end - local function begintag(result,embedded,element,nature,di,skip) + local function begintag(result,element,nature,di,skip) local index = di.n local fulltag = di.fulltag local specification = specifications[fulltag] or { } -- we can have a dummy @@ -2133,12 +2194,6 @@ do -- ignore else - -- if embedded then - -- if element == "math" then - -- embedded[f_tagid(element,index)] = #result+1 - -- end - -- end - local n = 0 local r = { } -- delay this if detail then @@ -2158,6 +2213,7 @@ do n = n + 1 r[n] = f_index(index) end + -- local extra = extras[element] if extra then extra(di,element,index,fulltag) @@ -2247,7 +2303,7 @@ do end end - local function endtag(result,embedded,element,nature,di,skip) + local function endtag(result,element,nature,di,skip) if skip == "comment" then if show_comment then if nature == "display" and (inline == 0 or inline == 1) then @@ -2278,18 +2334,10 @@ do inline = inline - 1 result[#result+1] = f_end_inline(namespaced[element]) end - - -- if embedded then - -- if element == "math" then - -- local id = f_tagid(element,di.n) -- index) - -- local tx = concat(result,"",embedded[id],#result) - -- embedded[id] = "<?xml version='1.0' standalone='yes'?>" .. "\n" .. tx - -- end - -- end end end - local function flushtree(result,embedded,data,nature) + local function flushtree(result,data,nature) local nofdata = #data for i=1,nofdata do local di = data[i] @@ -2321,23 +2369,23 @@ do if not element then -- skip elseif element == "break" then -- or element == "pagebreak" - emptytag(result,embedded,element,nature,di) + emptytag(result,element,nature,di) elseif element == "" or di.skip == "ignore" then -- skip else if di.before then - flushtree(result,embedded,di.before,nature) + flushtree(result,di.before,nature) end local natu = di.nature local skip = di.skip if di.breaknode then - emptytag(result,embedded,"break","display",di) + emptytag(result,"break","display",di) end - begintag(result,embedded,element,natu,di,skip) - flushtree(result,embedded,di.data,natu) - endtag(result,embedded,element,natu,di,skip) + begintag(result,element,natu,di,skip) + flushtree(result,di.data,natu) + endtag(result,element,natu,di,skip) if di.after then - flushtree(result,embedded,di.after,nature) + flushtree(result,di.after,nature) end end end @@ -2358,19 +2406,25 @@ do local di = data[i] if not di then -- skip + elseif di.skip == "ignore" then + -- skip (new) elseif di.content then - local parnumber = di.parnumber - if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then - nofnewdata = nofnewdata + 1 - if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber } - else - newdata[nofnewdata] = makebreaknode() + if di.samepar then + prevparnumber = false + else + local parnumber = di.parnumber + if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then + nofnewdata = nofnewdata + 1 + if trace_spacing then + newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber } + else + newdata[nofnewdata] = makebreaknode() + end end + prevelement = nil + prevparnumber = parnumber end - prevelement = nil prevnature = "inline" - prevparnumber = parnumber nofnewdata = nofnewdata + 1 newdata[nofnewdata] = di elseif not di.collapsed then @@ -2381,39 +2435,51 @@ do end prevelement = element prevnature = "display" + nofnewdata = nofnewdata + 1 + newdata[nofnewdata] = di elseif element == "" or di.skip == "ignore" then -- skip else + if di.samepar then + prevnature = "inline" + prevparnumber = false + else + local nature = di.nature + local parnumber = di.parnumber + if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then + nofnewdata = nofnewdata + 1 + if trace_spacing then + newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber } + else + newdata[nofnewdata] = makebreaknode() + end + end + prevnature = nature + prevparnumber = parnumber + end + prevelement = element + breaktree(di,tree,element) + nofnewdata = nofnewdata + 1 + newdata[nofnewdata] = di + end + else + if di.samepar then + prevnature = "inline" + prevparnumber = false + else local nature = di.nature local parnumber = di.parnumber if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then nofnewdata = nofnewdata + 1 if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber } + newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber } else newdata[nofnewdata] = makebreaknode() end end prevnature = nature prevparnumber = parnumber - prevelement = element - breaktree(di,tree,element) - end - nofnewdata = nofnewdata + 1 - newdata[nofnewdata] = di - else - local nature = di.nature - local parnumber = di.parnumber - if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then - nofnewdata = nofnewdata + 1 - if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber } - else - newdata[nofnewdata] = makebreaknode() - end end - prevnature = nature - prevparnumber = parnumber nofnewdata = nofnewdata + 1 newdata[nofnewdata] = di end @@ -2445,6 +2511,8 @@ do local cd = currentdata[j] if not cd or cd == "" then -- skip +elseif cd.skip == "ignore" then + -- skip elseif cd.content then if not currentpar then -- add space ? @@ -2749,6 +2817,7 @@ local collectresults do -- too many locals otherwise local nodecodes = nodes.nodecodes local skipcodes = nodes.skipcodes local listcodes = nodes.listcodes + local whatsitcodes = nodes.whatsitcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist @@ -2756,6 +2825,7 @@ local collectresults do -- too many locals otherwise local glue_code = nodecodes.glue local kern_code = nodecodes.kern local disc_code = nodecodes.disc + local whatsit_code = nodecodes.whatsit local userskip_code = skipcodes.userskip local rightskip_code = skipcodes.rightskip @@ -2765,6 +2835,8 @@ local collectresults do -- too many locals otherwise local line_code = listcodes.line + local userdefined_code = whatsitcodes.userdefined + local privateattribute = attributes.private local a_image = privateattribute('image') local a_reference = privateattribute('reference') @@ -2775,6 +2847,8 @@ local collectresults do -- too many locals otherwise local a_taggedpar = privateattribute("taggedpar") local a_textblock = privateattribute("textblock") + local inline_mark = nodes.pool.userids["margins.inline"] + local nuts = nodes.nuts local getnext = nuts.getnext @@ -2790,13 +2864,18 @@ local collectresults do -- too many locals otherwise local isglyph = nuts.isglyph local getkern = nuts.getkern local getwidth = nuts.getwidth + local getfield = nuts.getfield local nexthlist = nuts.traversers.hlist local nextnode = nuts.traversers.node local function collectresults(head,list,pat,pap) -- is last used (we also have currentattribute) local p - for n, id in nextnode, head do + for n, id, subtype in nextnode, head do +-- can go : +if not subtype then + subtype = getsubtype(n) +end if id == glyph_code then local c = getchar(n) local at = getattr(n,a_tagged) or pat @@ -2958,48 +3037,75 @@ local collectresults do -- too many locals otherwise nofcurrentcontent = nofcurrentcontent + 1 currentcontent[nofcurrentcontent] = c end - else - local subtype = getsubtype(n) - if subtype == userskip_code then - if getwidth(n) > threshold then - if last and not somespace[currentcontent[nofcurrentcontent]] then - local a = getattr(n,a_tagged) or pat - if a == last then - if trace_export then - report_export("%w<!-- injecting spacing 5a -->",currentdepth) - end - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = " " - elseif a then - -- e.g LOGO<space>LOGO - if trace_export then - report_export("%w<!-- processing glue > threshold tagged %s becomes %s -->",currentdepth,last,a) - end - pushcontent() - if trace_export then - report_export("%w<!-- injecting spacing 5b -->",currentdepth) - end - last = a - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = " " - currentnesting = taglist[last] - pushentry(currentnesting) - currentattribute = last + elseif subtype == userskip_code then + if getwidth(n) > threshold then + if last and not somespace[currentcontent[nofcurrentcontent]] then + local a = getattr(n,a_tagged) or pat + if a == last then + if trace_export then + report_export("%w<!-- injecting spacing 5a -->",currentdepth) + end + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = " " + elseif a then + -- e.g LOGO<space>LOGO + if trace_export then + report_export("%w<!-- processing glue > threshold tagged %s becomes %s -->",currentdepth,last,a) + end + pushcontent() + if trace_export then + report_export("%w<!-- injecting spacing 5b -->",currentdepth) end + last = a + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = " " + currentnesting = taglist[last] + pushentry(currentnesting) + currentattribute = last + end + end + end + elseif subtype == spaceskip_code or subtype == xspaceskip_code then + if not somespace[currentcontent[nofcurrentcontent]] then + local a = getattr(n,a_tagged) or pat + if a == last then + if trace_export then + report_export("%w<!-- injecting spacing 7 (stay in element) -->",currentdepth) + end + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = " " + else + if trace_export then + report_export("%w<!-- injecting spacing 7 (end of element) -->",currentdepth) end + last = a + pushcontent() + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = " " + currentnesting = taglist[last] + pushentry(currentnesting) + currentattribute = last end - elseif subtype == spaceskip_code or subtype == xspaceskip_code then - if not somespace[currentcontent[nofcurrentcontent]] then + end + elseif subtype == rightskip_code then + -- a line + if nofcurrentcontent > 0 then + local r = currentcontent[nofcurrentcontent] + if r == hyphen then + if not keephyphens then + nofcurrentcontent = nofcurrentcontent - 1 + end + elseif not somespace[r] then local a = getattr(n,a_tagged) or pat if a == last then if trace_export then - report_export("%w<!-- injecting spacing 7 (stay in element) -->",currentdepth) + report_export("%w<!-- injecting spacing 1 (end of line, stay in element) -->",currentdepth) end nofcurrentcontent = nofcurrentcontent + 1 currentcontent[nofcurrentcontent] = " " else if trace_export then - report_export("%w<!-- injecting spacing 7 (end of element) -->",currentdepth) + report_export("%w<!-- injecting spacing 1 (end of line, end of element) -->",currentdepth) end last = a pushcontent() @@ -3010,41 +3116,11 @@ local collectresults do -- too many locals otherwise currentattribute = last end end - elseif subtype == rightskip_code then - -- a line - if nofcurrentcontent > 0 then - local r = currentcontent[nofcurrentcontent] - if r == hyphen then - if not keephyphens then - nofcurrentcontent = nofcurrentcontent - 1 - end - elseif not somespace[r] then - local a = getattr(n,a_tagged) or pat - if a == last then - if trace_export then - report_export("%w<!-- injecting spacing 1 (end of line, stay in element) -->",currentdepth) - end - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = " " - else - if trace_export then - report_export("%w<!-- injecting spacing 1 (end of line, end of element) -->",currentdepth) - end - last = a - pushcontent() - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = " " - currentnesting = taglist[last] - pushentry(currentnesting) - currentattribute = last - end - end - end - elseif subtype == parfillskip_code then - -- deal with paragaph endings (crossings) elsewhere and we quit here - -- as we don't want the rightskip space addition - return end + elseif subtype == parfillskip_code then + -- deal with paragaph endings (crossings) elsewhere and we quit here + -- as we don't want the rightskip space addition + return end elseif id == hlist_code or id == vlist_code then local ai = getattr(n,a_image) @@ -3105,6 +3181,21 @@ local collectresults do -- too many locals otherwise end end end + elseif id == whatsit_code then + if subtype == userdefined_code then + -- similar to images, see above + local at = getattr(n,a_tagged) + if nofcurrentcontent > 0 then + pushcontent() + pushentry(currentnesting) -- ?? + end + pushentry(taglist[at]) + if trace_export then + report_export("%w<!-- processing anchor tagged %a",currentdepth,last) + end + last = nil + currentparagraph = nil + end end p = n end @@ -3308,13 +3399,12 @@ local htmltemplate = [[ local function allcontent(tree,embed) local result = { } - local embedded = embed and { } - flushtree(result,embedded,tree.data,"display") -- we need to collect images + flushtree(result,tree.data,"display") -- we need to collect images result = concat(result) -- no need to lpeg .. fast enough result = gsub(result,"\n *\n","\n") result = gsub(result,"\n +([^< ])","\n%1") - return result, embedded + return result end -- local xhtmlpreamble = [[ @@ -3569,7 +3659,6 @@ local htmltemplate = [[ local basename = file.basename local embedfile = false directives.register("export.embed",function(v) embedfile = v end) - local embedmath = false function structurestags.finishexport() @@ -3579,12 +3668,18 @@ local htmltemplate = [[ return end + local onlyxml = finetuning.export == v_xml + starttiming(treehash) -- finishexport() -- report_export("") - report_export("exporting xml, xhtml and html files") + if onlyxml then + report_export("exporting xml, no other files") + else + report_export("exporting xml, xhtml, html and css files") + end report_export("") -- wrapups.collapsetree(tree) @@ -3612,7 +3707,7 @@ local htmltemplate = [[ -- ./jobname-export/styles/jobname-images.css -- ./jobname-export/styles/jobname-templates.css - if type(askedname) ~= "string" or askedname == v_yes or askedname == "" then + if type(askedname) ~= "string" or askedname == "" then askedname = tex.jobname end @@ -3680,6 +3775,55 @@ local htmltemplate = [[ stylefilebase, } + local cssextra = cssfile and table.unique(settings_to_array(cssfile)) or { } + + -- at this point we're ready for the content; the collector also does some + -- housekeeping and data collecting; at this point we still have an xml + -- representation that uses verbose element names and carries information in + -- attributes + + local data = tree.data + for i=1,#data do + if data[i].tg ~= "document" then + data[i] = { } + end + end + + local result = allcontent(tree,embedmath) -- embedfile is for testing + + if onlyxml then + + os.remove(defaultfilename) + os.remove(imagefilename) + os.remove(stylefilename) + os.remove(templatefilename) + + for i=1,#cssextra do + os.remove(joinfile(stylepath,basename(source))) + end + + -- os.remove(xmlfilename) + + os.remove(imagefilename) + os.remove(stylefilename) + os.remove(templatefilename) + os.remove(xhtmlfilename) + os.remove(specificationfilename) + os.remove(htmlfilename) + + result = concat { + wholepreamble(true), + "<!-- This export file is used for filtering runtime only! -->\n", + result, + } + + report_export("saving xml data in %a",xmlfilename) + io.savedata(xmlfilename,result) + + return + + end + local examplefilename = resolvers.find_file("export-example.css") if examplefilename then local data = io.loaddata(examplefilename) @@ -3692,9 +3836,8 @@ local htmltemplate = [[ end if cssfile then - local list = table.unique(settings_to_array(cssfile)) - for i=1,#list do - local source = addsuffix(list[i],"css") + for i=1,#cssextra do + local source = addsuffix(cssextra[i],"css") local target = joinfile(stylepath,basename(source)) cssfiles[#cssfiles+1] = source if not lfs.isfile(source) then @@ -3709,21 +3852,6 @@ local htmltemplate = [[ local x_styles, h_styles = allusedstylesheets(cssfiles,files,"styles") - -- at this point we're ready for the content; the collector also does some - -- housekeeping and data collecting; at this point we still have an xml - -- representation that uses verbose element names and carries information in - -- attributes - - - local data = tree.data - for i=1,#data do - if data[i].tg ~= "document" then - data[i] = { } - end - end - - local result, embedded = allcontent(tree,embedmath) -- embedfile is for testing - local attach = backends.nodeinjections.attachfile if embedfile and attach then @@ -3737,22 +3865,6 @@ local htmltemplate = [[ mimetype = "application/mathml+xml", } end - -- if embedmath and attach then - -- local refs = { } - -- for k, v in sortedhash(embedded) do - -- attach { - -- data = v, - -- file = basename(k), - -- name = addsuffix(k,"xml"), - -- registered = k, - -- reference = k, - -- title = "xml export snippet: " .. k, - -- method = v_hidden, - -- mimetype = "application/mathml+xml", - -- } - -- refs[k] = 0 - -- end - -- end result = concat { wholepreamble(true), @@ -3782,14 +3894,14 @@ local htmltemplate = [[ local xmltree = cleanxhtmltree(xml.convert(result)) --- local xmltree = xml.convert(result) --- for c in xml.collected(xmltree,"m:mtext[lastindex()=1]/m:mrow") do --- print(c) --- end --- for c in xml.collected(xmltree,"mtext/mrow") do --- print(c) --- end --- local xmltree = cleanxhtmltree(xmltree) + -- local xmltree = xml.convert(result) + -- for c in xml.collected(xmltree,"m:mtext[lastindex()=1]/m:mrow") do + -- print(c) + -- end + -- for c in xml.collected(xmltree,"mtext/mrow") do + -- print(c) + -- end + -- local xmltree = cleanxhtmltree(xmltree) xml.save(xmltree,xhtmlfilename) @@ -3912,6 +4024,7 @@ implement { { "svgstyle" }, { "cssfile" }, { "file" }, + { "export" }, } } } @@ -3945,6 +4058,12 @@ implement { } implement { + name = "settagformulacontent", + actions = structurestags.setformulacontent, + arguments = "integer", +} + +implement { name = "settagdelimitedsymbol", actions = structurestags.settagdelimitedsymbol, arguments = "string" diff --git a/tex/context/base/mkiv/back-exp.mkiv b/tex/context/base/mkiv/back-exp.mkiv index ad5ba8371..c4610f854 100644 --- a/tex/context/base/mkiv/back-exp.mkiv +++ b/tex/context/base/mkiv/back-exp.mkiv @@ -241,6 +241,20 @@ \let\specialcontrolspace \explicitcontrolspace \to \everyenableelements +\appendtoks + \unexpanded\def\dotagregisterformula#1% + {\iftrialtypesetting\else + \clf_settagformulacontent#1\relax + \fi}% +\to \everyenableelements + +\appendtoks + \unexpanded\def\dotagmarginanchor#1% + {\iftrialtypesetting\else\clf_settagmarginanchor#1\relax\fi}% + \unexpanded\def\dotagmargintext#1% + {\iftrialtypesetting\else\clf_settagmargintext#1\relax\fi}% +\to \everyenableelements + % The action: \setupbackend[export=yes] % or filename % maybe xhtml css settings will move to setupexport @@ -261,18 +275,18 @@ \c!author={\directinteractionparameter\c!author}, % \c!firstpage=, % imagename % \c!lastpage=, % imagename - \c!alternative=, % html, div \c!properties=\v!no, % no: ignore, yes: as attribute, otherwise: use as prefix \c!hyphen=\v!no, \c!svgstyle=, \c!cssfile=, - \c!file={\backendparameter\c!export}] % downward compatibility + \c!file=] \resetsystemmode\v!export \unexpanded\def\doinitializeexport {\edef\p_export{\backendparameter\c!export}% \ifx\p_export\empty \else + % yes | xml \setuptagging[\c!state=\v!start]% \clf_initializeexport \setsystemmode\v!export @@ -300,6 +314,7 @@ svgstyle {\exportparameter\c!svgstyle}% cssfile {\exportparameter\c!cssfile}% file {\exportparameter\c!file}% + export {\backendparameter\c!export}% \relax} \unexpanded\def\dostopexport diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index 6d2cb4c7a..07de652b6 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -32,13 +32,19 @@ \registerctxluafile{lpdf-swf}{} % this will become a module \registerctxluafile{lpdf-tag}{} \registerctxluafile{lpdf-fmt}{} + \ifnum\texenginefunctionality<6802 \registerctxluafile{lpdf-epd}{} \else \registerctxluafile{lpdf-pde}{} \fi + \registerctxluafile{lpdf-epa}{} +\ifnum\texenginefunctionality>6856 + \registerctxluafile{lpdf-fnt}{} +\fi + \registerctxluafile{back-pdf}{} % some code will move to lpdf-* \loadmarkfile{back-u3d} % this will become a module diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 4f62413f8..ef8c995df 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{2018.07.13 09:47} +\newcontextversion{2018.07.17 17:25} %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 bbc3aa669..b8b306c6c 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,7 +42,7 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.07.13 09:47} +\edef\contextversion{2018.07.17 17:25} \edef\contextkind {beta} %D For those who want to use this: @@ -571,6 +571,9 @@ \loadmarkfile{meta-blb} \loadmarkfile{grph-epd} +\loadmarkfile{math-inc} % an experiment +\loadmarkfile{publ-inc} % an experiment + \loadmarkfile{task-ini} \loadmarkfile{cont-run} % the main runner (used in cont-yes.mkiv) diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua index 03bbf2ea3..b1da56747 100644 --- a/tex/context/base/mkiv/font-chk.lua +++ b/tex/context/base/mkiv/font-chk.lua @@ -506,3 +506,31 @@ local dummies_specification = { registerotffeature(dummies_specification) registerafmfeature(dummies_specification) + +-- + +local function addvisualspace(tfmdata) + local spacechar = tfmdata.characters[32] + if spacechar and not spacechar.commands then + local w = spacechar.width + local h = tfmdata.parameters.xheight + local c = { + width = w, + commands = { { "rule", h, w } } + } + local u = addprivate(tfmdata, "visualspace", c) + end +end + +local visualspace_specification = { + name = "visualspace", + description = "visual space", + default = true, + manipulators = { + base = addvisualspace, + node = addvisualspace, + } +} + +registerotffeature(visualspace_specification) +registerafmfeature(visualspace_specification) diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index f24686106..ff9d75060 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -1990,13 +1990,17 @@ local function descriptiontoslot(name) end end -local function indextoslot(index) - local r = resources[true] +local function indextoslot(font,index) + if not index then + index = font + font = true + end + local r = resources[font] if r then local indices = r.indices if not indices then indices = { } - local c = characters[true] + local c = characters[font] for unicode, data in next, c do local di = data.index if di then diff --git a/tex/context/base/mkiv/font-prv.lua b/tex/context/base/mkiv/font-prv.lua index 4c4948edc..914e9ccdf 100644 --- a/tex/context/base/mkiv/font-prv.lua +++ b/tex/context/base/mkiv/font-prv.lua @@ -72,3 +72,7 @@ function helpers.hasprivate(tfmdata,name) local privates = properties and properties.privates return privates and privates[name] or false end + +function helpers.privateslot(name) + return rawget(sharedprivates,name) +end diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index dd57c9dfa..c28764856 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -579,6 +579,7 @@ function figures.initialize(request) request.cache = request.cache ~= "" and request.cache request.prefix = request.prefix ~= "" and request.prefix request.format = request.format ~= "" and request.format + request.compact = request.compact == v_yes table.merge(figuredata.request,request) end return figuredata @@ -1988,6 +1989,7 @@ implement { { "arguments" }, { "repeat" }, { "transform" }, + { "compact" }, { "width", "dimen" }, { "height", "dimen" }, { "userpassword" }, @@ -2114,7 +2116,7 @@ local function pdf_checker(data) end request.copyimage = function(t) if pdfdoc then - local result = copypage(pdfdoc,request.page) + local result = copypage(pdfdoc,request.page,nil,request.compact) pdfdoc.nofcopiedpages = pdfdoc.nofcopiedpages + 1 if pdfdoc.nofcopiedpages >= pdfdoc.nofpages then closepdf(pdfdoc) diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index 2bcac8539..97a28d2c5 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -107,6 +107,7 @@ \c!transform =\v!auto, \c!userpassword =, \c!ownerpassword =, + \c!compact =, ] %D Defining figures. @@ -340,6 +341,7 @@ arguments {\externalfigureparameter\c!arguments}% used for converters repeat {\externalfigureparameter\c!repeat}% transform {\externalfigureparameter\c!transform}% + compact {\externalfigureparameter\c!compact}% experiment, share fonts userpassword {\externalfigureparameter\c!userpassword}% ownerpassword{\externalfigureparameter\c!ownerpassword}% \ifx\p_width\empty \else diff --git a/tex/context/base/mkiv/lpdf-fld.lua b/tex/context/base/mkiv/lpdf-fld.lua index 73de5eaf6..1c39b8876 100644 --- a/tex/context/base/mkiv/lpdf-fld.lua +++ b/tex/context/base/mkiv/lpdf-fld.lua @@ -360,6 +360,8 @@ local function fieldsurrounding(specification) return tostring(stream) end +-- Can we use any font? + codeinjections.fieldsurrounding = fieldsurrounding local function registerfonts() diff --git a/tex/context/base/mkiv/lpdf-fnt.lua b/tex/context/base/mkiv/lpdf-fnt.lua new file mode 100644 index 000000000..601e20de3 --- /dev/null +++ b/tex/context/base/mkiv/lpdf-fnt.lua @@ -0,0 +1,196 @@ +if not modules then modules = { } end modules ['lpdf-fnt'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is experimental code. + +local match, gmatch = string.match, string.gmatch +local tonumber = tonumber + +local pdfreserveobject = lpdf.reserveobject +local pdfincludechar = lpdf.includechar +local pdfincludefont = lpdf.includefont +local pdfreference = lpdf.reference + +local pdfe = lpdf.epdf + +local tobemerged = { } +local trace_merge = false trackers.register("graphics.fonts",function(v) trace_merge = v end) +local report_merge = logs.reporter("graphics","fonts") + +local function register(usedname,cleanname) + local cleanname = cleanname or fonts.names.cleanname(usedname) + local fontid = fonts.definers.internal { name = cleanname } + if fontid then + local objref = pdfreserveobject() + pdfincludefont(fontid) + if trace_merge then + report_merge("registering %a with name %a, id %a and object %a",usedname,cleanname,fontid,objref) + end + return { + id = fontid, + reference = objref, + indices = { }, + cleanname = cleanname, + } + end + return false +end + +function lpdf.registerfont(usedname,cleanname) + local v = register(usedname,cleanname) + tobemerged[usedname] = v + return v +end + +table.setmetatableindex(tobemerged,function(t,k) + return lpdf.registerfont(k) +end) + +local function finalizefont(v) + local indextoslot = fonts.helpers.indextoslot + if v then + local id = v.id + local n = 0 + for i in next, v.indices do + local u = indextoslot(id,i) + pdfincludechar(id,u) + n = n + 1 + end + v.n = n + end +end + +statistics.register("merged fonts", function() + if next(tobemerged) then + local t = { } + for k, v in table.sortedhash(tobemerged) do + t[#t+1] = string.formatters["%s (+%i)"](k,v.n) + end + return table.concat(t," ") + end +end) + +function lpdf.finalizefonts() + for k, v in next, tobemerged do + finalizefont(v) + end +end + +callback.register("font_descriptor_objnum_provider",function(name) + local m = rawget(tobemerged,name) + if m then + -- finalizefont(m) + local r = m.reference or 0 + if trace_merge then + report_merge("using object %a for font descriptor of %a",r,name) + end + return r + end + return 0 +end) + +local function getunicodes1(str,indices) + for s in gmatch(str,"beginbfrange%s*(.-)%s*endbfrange") do + for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do + for i=tonumber(first,16),tonumber(last,16) do + indices[i] = true + end + end + end + for s in gmatch(str,"beginbfchar%s*(.-)%s*endbfchar") do + for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do + indices[tonumber(old,16)] = true + end + end +end + +local function getunicodes2(widths,indices) + for i=1,#widths,2 do + local start = widths[i] + local count = #widths[i+1] + if start and count then + for i=start,start+count-1 do + indices[i] = true + end + end + end +end + +local function checkedfonts(pdfdoc,xref,copied,page) + local list = page.Resources.Font + local done = { } + for k, somefont in pdfe.expanded(list) do + if somefont.Subtype == "Type0" and somefont.Encoding == "Identity-H" then + local descendants = somefont.DescendantFonts + if descendants then + for i=1,#descendants do + local d = descendants[i] + if d then + local subtype = d.Subtype + if subtype == "CIDFontType0" or subtype == "CIDFontType2" then + local basefont = somefont.BaseFont + if basefont then + local fontname = match(basefont,"^[A-Z]+%+(.+)$") + local fontdata = tobemerged[fontname] + if fontdata then + local descriptor = d.FontDescriptor + if descriptor then + local okay = false + local widths = d.W + if widths then + getunicodes2(widths,fontdata.indices) + okay = true + else + local tounicode = somefont.ToUnicode + if tounicode then + getunicodes1(tounicode(),fontdata.indices) + okay = true + end + end + if okay then + local r = xref[descriptor] + done[r] = fontdata.reference + end + end + end + end + end + end + end + end + end + end + return next(done) and done +end + +if pdfincludefont then + + function lpdf.epdf.plugin(pdfdoc,xref,copied,page) + local done = checkedfonts(pdfdoc,xref,copied,page) + if done then + return { + FontDescriptor = function(xref,copied,object,key,value,copyobject) + local r = value[3] + local d = done[r] + if d then + return pdfreference(d) + else + return copyobject(xref,copied,object,key,value) + end + end + } + end + end + +else + + function lpdf.epdf.plugin() end + +end + +lpdf.registerdocumentfinalizer(lpdf.finalizefonts) diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index 3b5aeda84..6392125ca 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -1502,3 +1502,6 @@ function lpdf.copystring(v) return pdfstring(v) end end + +lpdf.includechar = pdf.includechar +lpdf.includefont = pdf.includefont diff --git a/tex/context/base/mkiv/lpdf-pde.lua b/tex/context/base/mkiv/lpdf-pde.lua index bc252b87c..790e8e7ff 100644 --- a/tex/context/base/mkiv/lpdf-pde.lua +++ b/tex/context/base/mkiv/lpdf-pde.lua @@ -872,11 +872,22 @@ if img then do return target end + local plugins = nil + copydictionary = function (xref,copied,object) local target = pdfdictionary() local source = object.__raw__ for key, value in next, source do - target[key] = copyobject(xref,copied,object,key,value) + if plugins then + local p = plugins[key] + if p then + target[key] = p(xref,copied,object,key,value,copyobject) -- maybe a table of methods + else + target[key] = copyobject(xref,copied,object,key,value) + end + else + target[key] = copyobject(xref,copied,object,key,value) + end end return target end @@ -941,7 +952,7 @@ if img then do end end - local function copypage(pdfdoc,pagenumber,attributes) + local function copypage(pdfdoc,pagenumber,attributes,compact) if pdfdoc then local root = pdfdoc.Catalog local page = pdfdoc.pages[pagenumber or 1] @@ -949,6 +960,9 @@ if img then do local contents = page.Contents local xref = pdfdoc.__xrefs__ local copied = pdfdoc.__copied__ + if compact and lpdf_epdf.plugin then + plugins = lpdf_epdf.plugin(pdfdoc,xref,copied,page) + end local xobject = pdfdictionary { Group = copyobject(xref,copied,page,"Group"), LastModified = copyobject(xref,copied,page,"LastModified"), @@ -990,6 +1004,7 @@ if img then do content = concat(content," ") end -- still not nice: we double wrap now + plugins = nil return newimage { bbox = pageinfo.boundingbox, nolength = nolength, diff --git a/tex/context/base/mkiv/lpdf-xmp.lua b/tex/context/base/mkiv/lpdf-xmp.lua index eb15a3582..ac07e4a3d 100644 --- a/tex/context/base/mkiv/lpdf-xmp.lua +++ b/tex/context/base/mkiv/lpdf-xmp.lua @@ -46,7 +46,7 @@ local mapping = { ["ConTeXt.Url"] = { "context", "rdf:Description/pdfx:ConTeXt.Url" }, ["ConTeXt.Support"] = { "context", "rdf:Description/pdfx:ConTeXt.Support" }, ["ConTeXt.Version"] = { "context", "rdf:Description/pdfx:ConTeXt.Version" }, - ["TeX.Support"] = { "metadata", "rdf:Description/pdfx:TeX.Support" }, + ["TeX.Support"] = { "metadata","rdf:Description/pdfx:TeX.Support" }, ["LuaTeX.Version"] = { "metadata","rdf:Description/pdfx:LuaTeX.Version" }, ["LuaTeX.Functionality"] = { "metadata","rdf:Description/pdfx:LuaTeX.Functionality" }, ["LuaTeX.LuaVersion"] = { "metadata","rdf:Description/pdfx:LuaTeX.LuaVersion" }, diff --git a/tex/context/base/mkiv/math-inc.lua b/tex/context/base/mkiv/math-inc.lua new file mode 100644 index 000000000..010d29a35 --- /dev/null +++ b/tex/context/base/mkiv/math-inc.lua @@ -0,0 +1,87 @@ +if not modules then modules = { } end modules ['back-inc'] = { + version = 1.001, + comment = "companion to back-exp.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is an experiment. If it's really useful then I'll make a more efficient +-- local export facility. + +local tonumber, next = tonumber, next +local utfbyte, utfchar, utfsplit = utf.byte, utf.char, utf.split +local match, gsub = string.match, string.gsub +local nspaces = string.nspaces +local concat = table.concat +local xmltext = xml.text +local undent = buffers.undent + +local f_entity = string.formatters["&x%X;"] +local f_blob = string.formatters['<?xml version="2.0"?>\n\n<!-- formula %i -->\n\n%s'] + +local all = nil +local back = nil + +local function unmath(s) + local t = utfsplit(s) + for i=1,#t do + local ti = t[i] + local bi = utfbyte(ti) + if bi > 0xFFFF then + local ch = back[bi] + t[i] = ch and utfchar(ch) or f_entity(bi) + end + end + s = concat(t) + return s +end + +local function beautify(s) + local b = match(s,"^( *)<m:math") + local e = match(s,"( *)</m:math>%s*$") + if b and e then + b = #b + e = #e + if e > b then + s = undent(nspaces[e-b] .. s) + elseif e < b then + s = undent((gsub(s,"^( *)",nspaces[b-e]))) + end + end + return s +end + +local function getblob(n) + if all == nil then + local name = file.nameonly(tex.jobname) + local full = name .. "-export/" .. name .. "-raw.xml" + if lfs.isfile(full) then + all = { } + back = { } + local root = xml.load(full) + for c in xml.collected(root,"formulacontent") do + local index = tonumber(c.at.n) + all[index] = f_blob(index,beautify(xmltext(c,"math") or "")) + end + local it = mathematics.alphabets.regular.it + for k, v in next, it.digits do back[v] = k end + for k, v in next, it.ucletters do back[v] = k end + for k, v in next, it.lcletters do back[v] = k end + else + all = false + end + end + if all == false then + return "" + end + return unmath(all[n] or "") +end + +interfaces.implement { + name = "xmlformulatobuffer", + arguments = { "integer", "string" }, + actions = function(n,target) + buffers.assign(target,getblob(n)) + end +} diff --git a/tex/context/base/mkiv/math-inc.mkiv b/tex/context/base/mkiv/math-inc.mkiv new file mode 100644 index 000000000..2821580cb --- /dev/null +++ b/tex/context/base/mkiv/math-inc.mkiv @@ -0,0 +1,69 @@ +%D \module +%D [ file=math-inc, +%D version=2018.06.23, +%D title=\CONTEXT\ Math Macros, +%D subtitle=XML inclusion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Math Macros / XML inclusion} + +\registerctxluafile{math-inc}{} + +%D I had some doubt about including this in \CONTEXT\ but it might serve some users +%D anyway. It's always the question to what extent one can be really roundtrip. I +%D might improve it when I need it. + +% Talking about creating from a source ... June Lee's transcription of +% Close to You by Jacob Collier is an amazing example: +% +% https://www.youtube.com/watch?v=hdBVN-HMuqI + +\unprotect + +\definesymbol[mmlattachment][{\infofont\darkred mml}] +\definesymbol[mmlcomment] [{\infofont\darkblue mml}] + +\unexpanded\def\lxml_add_mml_blob#1#2% + {\relax + \clf_xmlformulatobuffer\number\c_strc_formulas_n{temp-xml-export}% + #2% + [\c!symbol=#1,% + \c!space=\v!yes,% + \c!buffer=temp-xml-export,% + \c!name={formula-\number\c_strc_formulas_n.xml}]% + \relax} + +\unexpanded\def\xmlattachmml + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \lxml_add_mml_blob{mmlattachment}\attachment + \dostoptagged + \fi \fi \fi} + +\unexpanded\def\xmlcommentmml + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \lxml_add_mml_blob{mmlcomment}\comment + \dostoptagged + \fi \fi \fi} + +%D This kind of feature creep is not yet configurable, nor documented. + +\unexpanded\def\xmladdmmlsource + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \inleftmargin{% + \lxml_add_mml_blob{mmlattachment}\attachment + \quad + \lxml_add_mml_blob{mmlcomment}\comment + }% + \dostoptagged + \fi \fi \fi} + +\protect \endinput diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index 1c7b069cd..9a6a284d8 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -495,8 +495,8 @@ do -- experiment: names can change - local mppath = aux.mppath - local mpsize = aux.mpsize + local mppath = aux.path + local mpsize = aux.size local whitespace = lpegpatterns.whitespace local newline = lpegpatterns.newline @@ -522,12 +522,27 @@ do end local data = lpegmatch(pattern,io.loaddata(filename) or "") datasets[tag] = { - Data = data, - Line = function(n) mppath(data[n or 1]) end, - Size = function() mpsize(data) end, + data = data, + line = function(n) mppath(data[n or 1]) end, + size = function() mpsize(data) end, } end + table.setmetatablecall(datasets,function(t,k,f,...) + local d = datasets[k] + local t = type(d) + if t == "table" then + d = d[f] + if type(d) == "function" then + d(...) + else + mpvprint(...) + end + elseif t == "function" then + d(f,...) + end + end) + end -- \startluacode diff --git a/tex/context/base/mkiv/node-acc.lua b/tex/context/base/mkiv/node-acc.lua index 8d9acaf9b..f5cf6a2a1 100644 --- a/tex/context/base/mkiv/node-acc.lua +++ b/tex/context/base/mkiv/node-acc.lua @@ -8,7 +8,6 @@ if not modules then modules = { } end modules ['node-acc'] = { local nodes, node = nodes, node -local nodecodes = nodes.nodecodes local tasks = nodes.tasks local nuts = nodes.nuts @@ -16,6 +15,7 @@ local tonut = nodes.tonut local tonode = nodes.tonode local getid = nuts.getid +local getsubtype = nuts.getsubtype local getattr = nuts.getattr local getlist = nuts.getlist local getchar = nuts.getchar @@ -35,15 +35,21 @@ local nextnode = nuts.traversers.node local insert_after = nuts.insert_after local copy_no_components = nuts.copy_no_components +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes + local glue_code = nodecodes.glue ----- kern_code = nodecodes.kern local glyph_code = nodecodes.glyph local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local userskip_code = skipcodes.user +local spaceskip_code = skipcodes.spaceskip +local xspaceskip_code = skipcodes.xspaceskip + local a_characters = attributes.private("characters") -local threshold = 65536 -- not used local nofreplaced = 0 -- todo: nbsp etc @@ -51,6 +57,9 @@ local nofreplaced = 0 -- todo: maybe cache as we now create many nodes -- todo: check for subtype related to spacing (13/14 but most seems to be user anyway) +local trace = false trackers.register("backend.spaces", function(v) trace = v end) +local slot = nil + local function injectspaces(head) local p, p_id local n = head @@ -58,21 +67,25 @@ local function injectspaces(head) local id = getid(n) if id == glue_code then if p and getid(p) == glyph_code then - -- unless we don't care about the little bit of overhead - -- we can just: local g = copy_node(g) - local g = copy_no_components(p) - local a = getattr(n,a_characters) - setchar(g,32) - setlink(p,g,n) - setwidth(n,getwidth(n) - getwidth(g)) - if a then - setattr(g,a_characters,a) + local s = getsubtype(n) + if s == spaceskip_code or s == xspaceskip_code then + -- unless we don't care about the little bit of overhead + -- we can just: local g = copy_node(g) + local g = copy_no_components(p) + local a = getattr(n,a_characters) + setchar(g,slot) + setlink(p,g,n) + setwidth(n,getwidth(n) - getwidth(g)) + -- setsubtype(n,userskip_code) + if a then + setattr(g,a_characters,a) + end + setattr(n,a_characters,0) + nofreplaced = nofreplaced + 1 end - setattr(n,a_characters,0) - nofreplaced = nofreplaced + 1 end elseif id == hlist_code or id == vlist_code then - injectspaces(getlist(n),attribute) + injectspaces(getlist(n),slot) end p_id = id p = n @@ -82,7 +95,14 @@ local function injectspaces(head) end nodes.handlers.accessibility = function(head) - return injectspaces(head) + if trace then + if not slot then + slot = fonts.helpers.privateslot("visualspace") + end + else + slot = 32 + end + return injectspaces(head,slot) end statistics.register("inserted spaces in output",function() diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua index b82a3c4f8..f2e57618b 100644 --- a/tex/context/base/mkiv/publ-dat.lua +++ b/tex/context/base/mkiv/publ-dat.lua @@ -1209,21 +1209,6 @@ do } } - implement { - name = "btxentrytobuffer", - arguments = "3 strings", - actions = function(dataset,tag,target) - local d = publications.datasets[dataset] - if d then - d = d.luadata[tag] - end - if d then - d = string.fullstrip(savers.bib(dataset,false,{ [tag] = d })) - end - buffers.assign(target,d or "") - end - } - end end diff --git a/tex/context/base/mkiv/publ-imp-apa.mkvi b/tex/context/base/mkiv/publ-imp-apa.mkvi index 6963ab2ce..160cc4522 100644 --- a/tex/context/base/mkiv/publ-imp-apa.mkvi +++ b/tex/context/base/mkiv/publ-imp-apa.mkvi @@ -443,13 +443,40 @@ [apa:\s!cite:subbooktitle] [apa:\s!cite:booktitle] +% Will these get used? + +\definebtx + [apa:\s!cite:title:inbook] + [apa:\s!cite:title] + [\c!style=] % not italic + +\definebtx + [apa:\s!cite:title:incollection] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:title:inproceedings] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:subtitle:inbook] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:subtitle:incollection] + [apa:\s!cite:title:incollection] + +\definebtx + [apa:\s!cite:subtitle:inproceedings] + [apa:\s!cite:title:inproceedings] + + \definebtx [apa:\s!cite:tag] [apa:\s!cite] [\c!left={[}, \c!right={]}] - \definebtx [apa:\s!cite:index] [apa:\s!cite] @@ -687,6 +714,50 @@ \fastsetup{\s!btx:\s!cite:author:years} \stopsetups +% these setups need to be explicitly defined in order to get cite rendering + +\startsetups \s!btx:apa:\s!cite:organization + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:booktitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subbooktitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +% are these needed? + +\startsetups \s!btx:apa:\s!cite:title:inbook + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:title:incollection + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:title:inproceedings + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:inbook + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:incollection + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:inproceedings + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + % used in publ-imp-page.mkvi \startsetups btx:apa:list:page-or-pages diff --git a/tex/context/base/mkiv/publ-imp-cite.mkvi b/tex/context/base/mkiv/publ-imp-cite.mkvi index 998c45f00..56af83a1b 100644 --- a/tex/context/base/mkiv/publ-imp-cite.mkvi +++ b/tex/context/base/mkiv/publ-imp-cite.mkvi @@ -229,21 +229,9 @@ \startsetups \s!btx:\s!cite:title \fastsetup{\s!btx:\s!cite:normal} \stopsetups -\startsetups \s!btx:\s!cite:subtitle - \fastsetup{\s!btx:\s!cite:normal} -\stopsetups -\startsetups \s!btx:\s!cite:booktitle - \fastsetup{\s!btx:\s!cite:normal} -\stopsetups -\startsetups \s!btx:\s!cite:subbooktitle - \fastsetup{\s!btx:\s!cite:normal} -\stopsetups \startsetups \s!btx:\s!cite:pages \fastsetup{\s!btx:\s!cite:range} \stopsetups -\startsetups \s!btx:\s!cite:organization - \fastsetup{\s!btx:\s!cite:range} -\stopsetups % is the next one used? % Yes, bibtex is a mess and one can have pages or sometimes page diff --git a/tex/context/base/mkiv/publ-inc.lua b/tex/context/base/mkiv/publ-inc.lua new file mode 100644 index 000000000..9231be3c1 --- /dev/null +++ b/tex/context/base/mkiv/publ-inc.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['publ-inc'] = { + version = 1.001, + comment = "this module part of publication support", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local fullstrip = string.fullstrip +local datasets, savers = publications.datasets, publications.savers +local assignbuffer = buffers.assign + +interfaces.implement { + name = "btxentrytobuffer", + arguments = "3 strings", + actions = function(dataset,tag,target) + local d = datasets[dataset] + if d then + d = d.luadata[tag] + end + if d then + d = fullstrip(savers.bib(dataset,false,{ [tag] = d })) + end + assignbuffer(target,d or "") + end +} diff --git a/tex/context/base/mkiv/publ-inc.mkiv b/tex/context/base/mkiv/publ-inc.mkiv new file mode 100644 index 000000000..c1728f44a --- /dev/null +++ b/tex/context/base/mkiv/publ-inc.mkiv @@ -0,0 +1,63 @@ +%D \module +%D [ file=publ-inc, +%D version=2018.06.23, +%D title=\CONTEXT\ Publication Macros, +%D subtitle=XML inclusion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Publication Macros / XML inclusion} + +\registerctxluafile{publ-inc}{} + +%D A teaser for Alan. + +\unprotect + +\definesymbol[btxattachment][{\infofont\darkred btx}] +\definesymbol[btxcomment] [{\infofont\darkblue btx}] + +\unexpanded\def\btx_add_blob#1#2% + {\relax + \clf_btxentrytobuffer{\currentbtxdataset}{\currentbtxtag}{temp-btx-export}% + #2% + [\c!symbol=#1,% + \c!space=\v!yes, + \c!buffer=temp-btx-export,% + \c!name={\currentbtxtag.bib}]% + \relax} + +\unexpanded\def\btxattach + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \btx_add_blob{btxattachment}\attachment + \dostoptagged + \fi \fi \fi} + +\unexpanded\def\btxcomment + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \btx_add_blob{btxcomment}\comment + \dostoptagged + \fi \fi \fi} + +%D This kind of feature creep is not yet configurable, nor documented. + +\unexpanded\def\btxaddsource + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \llap{% + \btx_add_blob{btxattachment}\attachment + \quad + \btx_add_blob{btxcomment}\comment + \hskip\leftmargindistance + }% + \dostoptagged + \fi \fi \fi} + +\protect \endinput diff --git a/tex/context/base/mkiv/publ-ini.mkiv b/tex/context/base/mkiv/publ-ini.mkiv index a3f345360..39e9308e9 100644 --- a/tex/context/base/mkiv/publ-ini.mkiv +++ b/tex/context/base/mkiv/publ-ini.mkiv @@ -2013,17 +2013,4 @@ \def\publ_shortcut[#1]#2% {\clf_btxshortcut{\iffirstargument#1\else\s!default\fi}{#2}} -%D Let's see when Alan finds out about this one: - -\definesymbol[btxattachment][{\infofont bib}] - -\unexpanded\def\btxattachrecord - {\iflocation - \clf_btxentrytobuffer{\currentbtxdataset}{\currentbtxtag}{temp-bib-export}% - \attachment - [\c!symbol=btxattachment,% - \c!buffer=temp-bib-export,% - \c!name={\currentbtxtag.bib}]% - \fi} - \protect diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex ae21b5fcf..e9de48e49 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 0e739a4e4..a3627d2c6 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 775d2aca1..e04a0cb64 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -880,6 +880,9 @@ \par \fi \bgroup % HERE + \iftrialtypesetting\else + \global\advance\c_strc_formulas_n\plusone + \fi \def\currentformula{#1}% \strc_math_set_split \dostarttaggedchained\t!formula\currentformula\??formula @@ -922,10 +925,15 @@ % tagging of formulanumbers is not ok (we get two display maths blobs) +\newcount\c_strc_formulas_n + +\ifdefined\dotagregisterformula \else \let\dotagregisterformula\gobbleoneargument \fi + \unexpanded\def\strc_formulas_stop_formula {\strc_formulas_place_number % in case it hasn't happened yet \strc_formulas_flush_number % in case we are in native mode \dostarttagged\t!formulacontent\empty + \dotagregisterformula\c_strc_formulas_n \csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname \dostoptagged \dostoptagged diff --git a/tex/context/base/mkiv/strc-tag.lua b/tex/context/base/mkiv/strc-tag.lua index e5b1403ae..889ed4608 100644 --- a/tex/context/base/mkiv/strc-tag.lua +++ b/tex/context/base/mkiv/strc-tag.lua @@ -161,6 +161,7 @@ local properties = allocate { -- todo: more "record = true" to improve forma margintextblock = { pdf = "Span", nature = "inline" }, margintext = { pdf = "Span", nature = "inline" }, + marginanchor = { pdf = "Span", nature = "inline" }, math = { pdf = "Div", nature = "inline" }, -- no display mn = { pdf = "Span", nature = "mixed" }, diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv index 737cb4aea..c9a82f0ac 100644 --- a/tex/context/base/mkiv/strc-tag.mkiv +++ b/tex/context/base/mkiv/strc-tag.mkiv @@ -140,6 +140,7 @@ \def\t!margintext {margintext} % Span \def\t!margintextblock {margintextblock} % Div +\def\t!marginanchor {marginanchor} % Span % we might opt for verbose variants so this is experimental: diff --git a/tex/context/base/mkiv/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua index 813993a99..4254d7604 100644 --- a/tex/context/base/mkiv/typo-mar.lua +++ b/tex/context/base/mkiv/typo-mar.lua @@ -84,6 +84,9 @@ local getwidth = nuts.getwidth local setwidth = nuts.setwidth local getheight = nuts.getheight +local currentattr = nuts.current_attr +local setattrlist = nuts.setattrlist + local getbox = nuts.getbox local takebox = nuts.takebox @@ -298,7 +301,9 @@ function margins.save(t) -- -- t.realpageno = texgetcount("realpageno") if inline then - context(tonode(new_usernumber(inline_mark,nofsaved))) -- or use a normal node + local n = new_usernumber(inline_mark,nofsaved) + setattrlist(n,currentattr()) + context(tonode(n)) -- or use a normal node store[nofsaved] = t -- no insert nofinlined = nofinlined + 1 else @@ -984,6 +989,7 @@ interfaces.implement { { "align" }, { "option" }, { "line", "integer" }, + { "index", "integer" }, { "stackname" }, { "stack" }, } diff --git a/tex/context/base/mkiv/typo-mar.mkiv b/tex/context/base/mkiv/typo-mar.mkiv index 10a47e705..921f1f230 100644 --- a/tex/context/base/mkiv/typo-mar.mkiv +++ b/tex/context/base/mkiv/typo-mar.mkiv @@ -201,11 +201,17 @@ \let\margindatahbox\naturalhbox % \hbox +\newcount\c_typo_margins_n + +\ifdefined\dotagmarginanchor \else \let\dotagmarginanchor\gobbleoneargument \fi +\ifdefined\dotagmargintext \else \let\dotagmargintext \gobbleoneargument \fi + \unexpanded\def\typo_margins_data_yes_indeed[#dataparameters][#textparameters]#content% {\iffirstargument \setupcurrentmargindata[#dataparameters]% \fi \doifelsenothing{#content}\donefalse\donetrue + \global\advance\c_typo_margins_n\plusone \ifdone \edef\currentmarginreference{\margindataparameter\c!reference}% \ifx\currentmarginreference\empty \else @@ -213,6 +219,7 @@ \fi \edef\currentmargindatastrut{\margindataparameter\c!strut}% \dostarttaggedchained\t!margintext\currentmargindata\??margindata + \dotagmargintext\c_typo_margins_n \ifcsname\currentmarginframedhash\s!parent\endcsname \setbox\nextbox\margindatahbox \currentmarginreference \bgroup \the\everymargindatacontent @@ -272,6 +279,8 @@ \ifdone \edef\p_anchor{\margindataparameter\c!anchor}% \anch_positions_initialize % we use positions at the lua end + \dostarttagged\t!marginanchor\empty + \dotagmarginanchor\c_typo_margins_n \clf_savemargindata location {\margindataparameter\c!location}% method {\margindataparameter\c!method}% @@ -307,7 +316,9 @@ line \numexpr\margindataparameter\c!line\relax stackname {\margindataparameter\c!stackname}% stack {\margindataparameter\c!stack}% + index \c_typo_margins_n \relax + \dostoptagged \else \clf_savemargindata location {\margindataparameter\c!location}% diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 38cd62221..aa46a705e 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 cb75e439d..49e97c2b7 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 6871f37b3..536e4f7ee 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 : 07/13/18 09:48:00 +-- merge date : 07/17/18 17:25:02 do -- begin closure to overcome local limits and interference |