summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/documents/general/manuals/ecmascript-mkiv.pdfbin0 -> 41363 bytes
-rw-r--r--doc/context/documents/general/manuals/libraries-mkiv.pdfbin44682 -> 44532 bytes
-rw-r--r--doc/context/documents/general/manuals/luametatex.pdfbin1186001 -> 1183590 bytes
-rw-r--r--doc/context/documents/general/manuals/sql-mkiv.pdfbin94186 -> 53962 bytes
-rw-r--r--doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex420
-rw-r--r--doc/context/sources/general/manuals/libraries/libraries-mkiv.tex5
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex20
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-differences.tex4
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex44
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex79
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex5
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-languages.tex46
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-math.tex8
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex26
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex30
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex2
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex-tex.tex9
-rw-r--r--doc/context/sources/general/manuals/sql/sql-mkiv.tex4
-rw-r--r--doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua11
-rw-r--r--scripts/context/lua/mtx-fonts.lua2
-rw-r--r--scripts/context/lua/mtx-unicode.lua7
-rw-r--r--scripts/context/lua/mtxrun.lua708
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua708
-rw-r--r--scripts/context/stubs/unix/mtxrun708
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua708
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/char-emj.lua375
-rw-r--r--tex/context/base/mkiv/cont-fil.mkiv269
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkxl2
-rw-r--r--tex/context/base/mkiv/data-tmp.lua2
-rw-r--r--tex/context/base/mkiv/driv-shp.lua6
-rw-r--r--tex/context/base/mkiv/file-job.lua2
-rw-r--r--tex/context/base/mkiv/font-con.lua1
-rw-r--r--tex/context/base/mkiv/font-ctx.lua65
-rw-r--r--tex/context/base/mkiv/font-dsp.lua57
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-ocl.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua5
-rw-r--r--tex/context/base/mkiv/l-os.lua8
-rw-r--r--tex/context/base/mkiv/l-table.lua106
-rw-r--r--tex/context/base/mkiv/libs-imp-mujs.lua126
-rw-r--r--tex/context/base/mkiv/libs-imp-mujs.mkxl121
-rw-r--r--tex/context/base/mkiv/libs-imp-mysql.lua36
-rw-r--r--tex/context/base/mkiv/libs-imp-postgress.lua6
-rw-r--r--tex/context/base/mkiv/libs-imp-sqlite.lua4
-rw-r--r--tex/context/base/mkiv/libs-imp-zint.lua15
-rw-r--r--tex/context/base/mkiv/libs-imp-zint.mkxl5
-rw-r--r--tex/context/base/mkiv/libs-ini.lua17
-rw-r--r--tex/context/base/mkiv/lpdf-emb.lua48
-rw-r--r--tex/context/base/mkiv/lpdf-lmt.lua170
-rw-r--r--tex/context/base/mkiv/lpdf-wid.lua16
-rw-r--r--tex/context/base/mkiv/luat-cod.lua4
-rw-r--r--tex/context/base/mkiv/luat-ini.lua2
-rw-r--r--tex/context/base/mkiv/luat-lib.mkiv6
-rw-r--r--tex/context/base/mkiv/m-gnuplot.mkxl97
-rw-r--r--tex/context/base/mkiv/m-zint.mkxl7
-rw-r--r--tex/context/base/mkiv/meta-imp-threesix.mkxl253
-rw-r--r--tex/context/base/mkiv/meta-tex.mkiv3
-rw-r--r--tex/context/base/mkiv/mlib-svg.lua280
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26743 -> 26747 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin269677 -> 269549 bytes
-rw-r--r--tex/context/base/mkiv/tabl-xtb.lua32
-rw-r--r--tex/context/base/mkiv/util-pck.lua10
-rw-r--r--tex/context/base/mkiv/util-sql.lua6
-rw-r--r--tex/context/base/mkiv/util-str.lua6
-rw-r--r--tex/context/base/mkiv/util-tab.lua255
-rw-r--r--tex/context/modules/common/s-abbreviations-logos.tex1
-rw-r--r--tex/context/modules/mkiv/m-zint.mkiv112
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua95
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua4
-rw-r--r--web2c/contextcnf.lua2
74 files changed, 3653 insertions, 2550 deletions
diff --git a/doc/context/documents/general/manuals/ecmascript-mkiv.pdf b/doc/context/documents/general/manuals/ecmascript-mkiv.pdf
new file mode 100644
index 000000000..308dfda78
--- /dev/null
+++ b/doc/context/documents/general/manuals/ecmascript-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/libraries-mkiv.pdf b/doc/context/documents/general/manuals/libraries-mkiv.pdf
index 9b13d7414..aa18726e3 100644
--- a/doc/context/documents/general/manuals/libraries-mkiv.pdf
+++ b/doc/context/documents/general/manuals/libraries-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index b128ed767..766e9a709 100644
--- a/doc/context/documents/general/manuals/luametatex.pdf
+++ b/doc/context/documents/general/manuals/luametatex.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/sql-mkiv.pdf b/doc/context/documents/general/manuals/sql-mkiv.pdf
index 09e63bcc8..57f6a9dc0 100644
--- a/doc/context/documents/general/manuals/sql-mkiv.pdf
+++ b/doc/context/documents/general/manuals/sql-mkiv.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex b/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex
new file mode 100644
index 000000000..70350142c
--- /dev/null
+++ b/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex
@@ -0,0 +1,420 @@
+% language=us
+
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
+% Group journal or otherwise. Thanks to the editors for corrections. Also thanks
+% to users for testing, feedback and corrections.
+
+% for now:
+
+\usemodule[article-basic]
+\usemodule[abbreviations-smallcaps]
+\usemodule[scite]
+\usemodule[ecmascript]
+
+\definecolor
+ [maincolor]
+ [r=.4]
+
+\definecolor
+ [extracolor]
+ [g=.4]
+
+\setupbodyfont
+ [11pt]
+
+\setuptype
+ [color=maincolor]
+
+% \setuptyping
+% [color=maincolor]
+
+\definefontsynonym
+ [TitlePageMono]
+ [file:lmmonoproplt10-bold*default]
+
+\setuphead
+ [color=maincolor]
+
+\usesymbols
+ [cc]
+
+\setupinteraction
+ [hidden]
+
+\loadfontgoodies[lm]
+
+\startdocument
+ [metadata:author=Hans Hagen,
+ metadata:title=ecmascript in context lmtx,
+ author=Hans Hagen,
+ affiliation=PRAGMA ADE,
+ location=Hasselt NL,
+ title=\ECNASCRIPT\ in \CONTEXT\ \LMTX,
+ support=www.contextgarden.net,
+ website=www.pragma-ade.nl]
+
+\starttext
+
+\startMPpage
+ StartPage;
+
+ fill Page withcolor "darkgreen";
+
+ draw textext.lrt("\tttf ECMA")
+ xsized .75PaperWidth
+ shifted ulcorner (Page enlarged -15mm )
+ withcolor "white" ;
+
+ draw textext.llft("\tttf SCRIPT")
+ xsized .50PaperWidth
+ shifted urcorner (Page enlarged -15mm topenlarged -70mm)
+ withcolor "white" ;
+
+ draw textext.llft("\tttf in context lmtx")
+ xsized .50PaperWidth
+ shifted urcorner (Page enlarged -15mm topenlarged -110mm)
+ withcolor "white" ;
+
+ draw textext.llft("\tttf using the optional mujs library")
+ xsized .50PaperWidth
+ shifted lrcorner (Page enlarged -15mm bottomenlarged -10mm)
+ withcolor "white" ;
+
+ StopPage;
+\stopMPpage
+
+\dontcomplain
+
+% \startsubject[title=Contents]
+%
+% \placelist[section][alternative=a]
+%
+% \stopsubject
+
+\startsection[title=Introduction]
+
+When you use \CONTEXT\ there is no way around noticing that the \LUA\ scripting
+language is an important component. When we progressed from \LUATEX\ to
+\LUAMETATEX\ did didn't change. I like that language a lot! Among the reasons are
+that it reminds me of \PASCAL, that it's clean, fast and well maintained. There
+is no huge infrastructure involved, nor lots of libraries and therefore
+dependencies.
+
+So why bother about another scripting language? One can argue that because of the
+World Wide Web one should use \JAVASCRIPT\ instead. It might make sense from a
+commercial point of view, or for some promotional reason. But that all makes
+little sense in the perspective of \CONTEXT. But, when I was playing with
+optional libraries in \LUAMETATEX,
+
+On and off I wonder if I should spend some time on adding \LUA\ annotation
+support to the open source mupdf viewer. After all, it has some basic
+\JAVASCRIPT\ support (but currently not enough, for instance it lacks control
+over widgets and layers and such.) However, then I noticed that the related
+\JAVASCRIPT\ code was actually an independent library and looking at the header
+files it looked quite a bit like the \LUA\ interface. So, just for the fun of it I
+gave it a try, and when doing so, I realized that having support for \JAVASCRIPT,
+or actually \ECMASCRIPT, because that is what it is, could make users who are
+afraid of \LUA\ willing to play with simple scripting in \CONTEXT. Of course,
+after a while they will figure out that \LUA\ is the real deal.
+
+Therefore, instead of sticking to an experiment, I decided to make support for
+the \type {mujs} library an option. After all, every now and they we need
+something new to play with. But be warned: it's an optional thing. The
+interpreter is not embedded in the binary and is loaded on demand (when present).
+In spite of that performance is quite okay.
+
+\stopsection
+
+\startsection[title=A few examples]
+
+Because the provided interface is pretty limited, a few simple examples will do.
+There are plenty of tutorials on the Internet. The main thing to keep in mind is
+that an \ECMASCRIPT\ interpreter is normally pretty limited when it comes to
+communicating with its environment. For instance, the main application provides
+way to print something (to a console) or read from files. So, commands that
+relate to this are specific for \LUAMETATEX. Before anything can be done you need
+to load the (\type {mujs}) library, which is done with:
+
+\starttyping
+\usemodule[ecmascript]
+\stoptyping
+
+You can write a message to the log (or an output pane or console) with the \type
+{console} function, one that normally is present in a \JAVASCRIPT\ (\ECMASCRIPT)
+environment:
+
+\starttyping
+\ecmacode {console("Example Three!")}
+\stoptyping
+
+Printing something to the \TEX\ engine is done with this command:
+
+\startbuffer
+\ecmacode {texprint("Just a {\\bf short} sentence.")}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This produces:
+
+\getbuffer
+
+and is comparable with the \type {tex.print} (which prints lines) function at the
+\LUA\ end. This means that there is also \type {texsprint} (which accumulates
+parts into lines). In practice one will probably always use that one.
+
+When there are two arguments, the first argument has to be a number and sets the
+so called catcode table to be used.
+
+\startbuffer
+\ecmacode {texprint(catcodes.vrb,"Just a {\\bf short} sentence.")}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This results in a verbatim print: {\tttf \inlinebuffer} The backslash is just that,
+a backslash and not a trigger for a \TEX\ command.
+
+You can do pretty much everything with these print commands. Take for instance the
+following example:
+
+\startbuffer
+\startecmacode
+ console("We're doing some MetaPost!");
+ texsprint(
+ "\\startMPcode "
+ + 'fill fullsquare xyscaled (6cm,1cm) withcolor "darkred";'
+ + 'fill fullsquare xyscaled (4cm,1cm) withcolor "darkgreen";'
+ + 'fill fullsquare xyscaled (2cm,1cm) withcolor "darkblue";'
+ + "\\stopMPcode "
+ );
+\stopecmacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This produces:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+in \LUA\ we can do this:
+
+\startbuffer
+\startluacode
+ context.startMPcode()
+ context('fill fullsquare xyscaled (6cm,1cm) withcolor "middlecyan";')
+ context('fill fullsquare xyscaled (4cm,1cm) withcolor "middlemagenta";')
+ context('fill fullsquare xyscaled (2cm,1cm) withcolor "middleyellow";')
+ context.stopMPcode()
+\stopluacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The result is the same but the code to produce it looks more like \CONTEXT, if
+only because way more built in features are provided. It makes no sense to do
+the same with another scripting language.
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+As mentioned, reading from files is to be provided by the main program and indeed
+we do have some basic interface. Actually we delegate all to the \LUA\ end by
+using a callback mechanism but users won't see these details. It suffices to know
+that file lookups are done the same way as in the main program because we use the
+same resolvers. One can (in the spirit of \ECMASCRIPT) open a file by creating a
+new file object. After that one can read from the file and, when done, close it.
+
+\startbuffer
+\startecmacode
+ var f = File("ecmascript-mkiv.tex","r");
+ var l = f.read("*a");
+ f.close();
+ texprint(
+ "This file has "
+ + l.length // or: l.length.toString()
+ + " bytes!"
+ )
+\stopecmacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Which reports that: \quotation {\inlinebuffer} The arguments to the \type {read}
+method are the same as in \LUA, so for instance \type {*a} reads the whole file,
+\type {*l} a single line, and a number will read that many bytes. There is
+currently no support for writing as I see no need for it (yet).
+
+You can load an external file too.
+
+\startluacode
+io.savedata("ecmascript-demo-001.js",[[
+function filesize(name) {
+ var f = File(name,"r");
+ if (f != undefined) {
+ var l = f.read("*a");
+ f.close();
+ return l.length;
+ } else {
+ return 0;
+ }
+}
+]])
+\stopluacode
+
+\startbuffer
+\ecmafile{ecmascript-demo-001.js}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+This file defines a function:
+
+\typefile{ecmascript-demo-001.js}
+
+We use this as follows:
+
+\startbuffer
+\startecmacode
+ texsprint(
+ "This file has "
+ + filesize("ecmascript-mkiv.tex")
+ + " bytes!"
+ )
+\stopecmacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The result is the same as before: \quotation {\inlinebuffer} but by using a
+predefined function we save ourselves some typing. Actually, a more efficient
+variant is this:
+
+\starttyping
+function filesize(name) {
+ var f = File(name,"r");
+ if (f != undefined) {
+ var l = f.seek("end");
+ f.close();
+ return l;
+ } else {
+ return 0;
+ }
+}
+\stoptyping
+
+As with the \type {read} method, the \type {seek} method behaves the same as
+its \LUA\ counterpart, which is a good reason to have a look at the \LUA\
+manual.
+
+If you want you want also access the \ECMASCRIPT\ interpreter from the \LUA\ end,
+not that it makes much sense, but maybe you have a lot of complex code that you
+don't want to rewrite. Here is an example:
+
+\startbuffer
+\startluacode
+ optional.loaded.mujs.execute [[
+ var MyMax = 10; // an example of persistence
+ ]]
+
+ optional.loaded.mujs.execute [[
+ texsprint("\\startpacked");
+ for (var i = 1; i <= MyMax; i++) {
+ texprint(
+ "Here is some rather dumb math test: "
+ + Math.sqrt(i/MyMax)
+ + "!\\par"
+ );
+ }
+ texsprint("\\stoppacked");
+ ]]
+\stopluacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This assumes that you have loaded the module \type {ecmascript} which does the
+necessary preparations. Watch the different ways to add comment and also watch
+how we need to escape the \CONTEXT\ commands. Of course the syntax of both
+languages is different too.
+
+\getbuffer
+
+For now there is not much more to tell. I might add a few features (and more
+examples). And the low level optional interface is not yet declared stable but as
+we wrap it in higher level commands no one will notice changes at that end.
+
+\stopsection
+
+\startsection[title=Extensions]
+
+To summarize, for printing to \TEX\ we have:
+
+\starttyping
+texsprint([catcodetableid,]string|number)
+\stoptyping
+
+and
+
+\starttyping
+texprint(catcodetableid,]string|number)
+\stoptyping
+
+and for printing to the console:
+
+\starttyping
+console(string|number)
+\stoptyping
+
+A file is opened with:
+
+\starttyping
+var f = File.new(filename[,mode])
+\stoptyping
+
+and the returned file object has the methods:
+
+\starttyping
+var str = f:read([string|number])
+var pos = f:seek(whence[,offset])
+\stoptyping
+
+There is a predefined table \type {catcodes} with sybolic entries
+for:
+
+\starttabulate
+\NC \type {tex} \NC regular \TEX\ catcode regime \NC \NR
+\NC \type {ctx} \NC standard \CONTEXT\ catcode regime \NC \NR
+\NC \type {vrb} \NC verbatim catcode regime \NC \NR
+\NC \type {prt} \NC protected \CONTEXT\ catcode regime \NC \NR
+\stoptabulate
+
+\stopsection
+
+\startsection[title=Colofon]
+
+\starttabulate[|B|p|]
+\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC version \NC \currentdate \NC \NR
+\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\stoptabulate
+
+\stopsection
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex b/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
index 6a322c771..f1801efc0 100644
--- a/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
+++ b/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
@@ -61,7 +61,7 @@
support=www.contextgarden.net,
website=www.pragma-ade.nl]
-\startluasetups[swiglib]
+\startluasetups[libraries]
context.nohyphens()
for i=1,640 do
context.definedfont { string.formatters["TitlePageMono at %p"](65536*(10+math.random(5))) }
@@ -76,7 +76,7 @@ StartPage ;
fill Page enlarged 1cm withcolor \MPcolor{extracolor} ;
- draw textext("\framed[loffset=2pt,roffset=2pt,frame=off,width=\paperwidth,align={normal,paragraph,verytolerant,stretch}]{\luasetup{swiglib}}")
+ draw textext("\framed[loffset=2pt,roffset=2pt,frame=off,width=\paperwidth,align={normal,paragraph,verytolerant,stretch}]{\luasetup{libraries}}")
xysized (PaperWidth,PaperHeight)
shifted center Page
withcolor .8white ;
@@ -247,6 +247,7 @@ There are some optional libraries present, like:
\NC libs-imp-sqlite \NC sqlite \NC sqlite3 \NC sqlite3 \NC \NR
%NC libs-imp-postgress \NC libpg \NC libpg \NC libpg \NC \NR % untested
\NC libs-imp-zint \NC libzint \NC libzint \NC libzint \NC \NR
+\NC libs-imp-mujs \NC libmujs \NC libmujs \NC libmujs \NC \NR
\NC libs-imp-ghostscript \NC ghostscript \NC gswin64 \NC libgs \NC \NR
\NC libs-imp-graphicsmagick \NC graphicsmagick \NC several \NC unknown \NC \NR
%NC font-phb-imp-internal \NC hb \NC libharfbuzz \NC libharfbuzz \NC \NR % maybe, for idris, testing uniscribe
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex b/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
index e713d13c3..e3e2a91e1 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
@@ -13,6 +13,7 @@
\libindex{register}
\libindex{list}
\libindex{find}
+\libindex{known}
This library has functions that register, find and list callbacks. Callbacks are
\LUA\ functions that are called in well defined places. There are two kind of
@@ -28,18 +29,14 @@ but in the end might not give the user the expected outcome.
The first thing you need to do is registering a callback:
\startfunctioncall
-id, error =
- callback.register(<string> callback_name, <function> func)
-id, error =
- callback.register(<string> callback_name, nil)
-id, error =
- callback.register(<string> callback_name, false)
+id = callback.register(<string> callback_name, <function> func)
+id = callback.register(<string> callback_name, nil)
+id = callback.register(<string> callback_name, false)
\stopfunctioncall
Here the \syntax {callback_name} is a predefined callback name, see below. The
function returns the internal \type {id} of the callback or \type {nil}, if the
-callback could not be registered. In the latter case, \type {error} contains an
-error message, otherwise it is \type {nil}.
+callback could not be registered.
\LUATEX\ internalizes the callback function in such a way that it does not matter
if you redefine a function accidentally.
@@ -65,7 +62,12 @@ The keys in the table are the known callback names, the value is a boolean where
<function> f = callback.find(callback_name)
\stopfunctioncall
-If the callback is not set, \type {find} returns \type {nil}.
+If the callback is not set, \type {find} returns \type {nil}. The \type {known}
+function can be used to check if a callback is supported.
+
+\startfunctioncall
+if callback.known("foo") then ... end
+\stopfunctioncall
\stopsection
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex b/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
index 19a4078c1..4ec846b38 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
@@ -15,6 +15,8 @@ what is gone. We start with the primitives that were dropped.
\type {\expandglyphsinfont}
\type {\ignoreligaturesinfont}
\type {\tagcode}
+ \type {\leftghost}
+ \type {\rightghost}
\NC \NR
\NC backend \NC \type {\dviextension}
\type {\dvivariable }
@@ -151,6 +153,8 @@ show_whatsit
Being the core of extensibility, the typesetting callbacks of course stayed. This
is what we ended up with:
+% \ctxlua{inspect(table.sortedkeys(callbacks.list))}
+
\starttyping
find_log_file, find_data_file, find_format_file, open_data_file, read_data_file,
process_jobname, start_run, stop_run, define_font, pre_output_filter,
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
index 06e0ce327..d70b8f2c0 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
@@ -14,7 +14,7 @@ From day one, \LUATEX\ has offered extra features compared to the superset of
\PDFTEX, which includes \ETEX, and \ALEPH. This has not been limited to the
possibility to execute \LUA\ code via \prm {directlua}, but \LUATEX\ also adds
functionality via new \TEX|-|side primitives or extensions to existing ones. The
-same is true fir \LUAMETATEX. Some primitives have \type {luatex} in their name
+same is true for \LUAMETATEX. Some primitives have \type {luatex} in their name
and there will be no \type {luametatex} variants. This is because we consider
\LUAMETATEX\ to be \LUATEX 2\high{+}.
@@ -40,14 +40,10 @@ it may be needed to put these assignments before the above line:
\stoptyping
More fine|-|grained primitives control is possible and you can look up the
-details in \in {section} [luaprimitives]. For simplicity's sake, this manual
-assumes that you have executed the \prm {directlua} command as given above.
-
-The startup behaviour documented above is considered stable in the sense that
-there will not be backward|-|incompatible changes any more. We have promoted some
-rather generic \PDFTEX\ primitives to core \LUATEX\ ones, and a few that we
-inherited from \ALEPH\ (\OMEGA) are also promoted. Effectively this means that we
-now only have the \type {tex}, \type {etex} and \type {luatex} sets left.
+details in \in {section} [luaprimitives]. There are only three kinds of
+primitives: \type {tex}, \type {etex} and \type {luatex} but a future version
+might drop this and no longer make that distinction as it no longer serves
+a purpose.
\stopsubsection
@@ -225,7 +221,7 @@ commands are:
Fonts are loaded via \LUA\ and a minimal amount of information is kept at the
\TEX\ end. Sharing resources is up to the loaders. The engine doesn't really care
-about what a character (or glyph) number represents (an \UNICODE\ or index) as it
+about what a character (or glyph) number represents (a \UNICODE\ or index) as it
only is interested in dimensions.
\stopsubsection
@@ -246,7 +242,7 @@ nodes that have for instance a \type {font} and \type {char} property and \typ
{\kern 10pt} becomes a \nod {kern} node with a \type {width} property. Spaces are
alien to \TEX\ as they are turned into \nod {glue} nodes. So, a simple paragraph
is mostly a mix of sequences of \nod {glyph} nodes (words) and \nod {glue} nodes
-(spaces). A node can have a subtype to that it can be recognized as for instance
+(spaces). A node can have a subtype so that it can be recognized as for instance
a space related glue.
The sequences of characters at some point are extended with \nod {disc} nodes
@@ -271,7 +267,7 @@ and carry only the minimal amount of information needed. In traditional \TEX\ a
character node only held the font and slot number, in \LUATEX\ we also store some
language related information, the expansion factor, etc. Now that we have access
to these nodes from \LUA\ it makes sense to be able to carry more information
-with an node and this is where attributes kick in.
+with a node and this is where attributes kick in.
\stopsubsection
@@ -379,7 +375,7 @@ code:
Later we will see that you can access properties of a node. The boxes here are so
called \nod {hlist} nodes that have a field \type {list} that points to the
content. Because the attributes are a list themselves you can access them by
-indexing the node (here we do that with \type {[a]}. Running this snippet gives:
+indexing the node (here we do that with \type {[a]}). Running this snippet gives:
\start
\getbuffer[tex]
@@ -597,7 +593,7 @@ function calls is that they are stored in the format (but without upvalues).
Catcode tables are a new feature that allows you to switch to a predefined
catcode regime in a single statement. You can have lots of different tables, but
-if you need a dozen you might wonder what you're doing. . This subsystem is
+if you need a dozen you might wonder what you're doing. This subsystem is
backward compatible: if you never use the following commands, your document will
not notice any difference in behaviour compared to traditional \TEX. The contents
of each catcode table is independent from any other catcode table, and its
@@ -795,10 +791,10 @@ but faster (only measurable with millions of calls) and probably more convenient
\topicindex {expansion}
-The \lpr {expanded} primitive takes a token list and expands it content which can
+The \lpr {expanded} primitive takes a token list and expands its content which can
come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
You can compare it with what happens inside the body of an \prm {edef}. But this
-kind of expansion it still doesn't expand some primitive operations.
+kind of expansion still doesn't expand some primitive operations.
\startbuffer
\newcount\NumberOfCalls
@@ -890,14 +886,14 @@ so called prefixed commands (except box assignments).
\startsubsection[title={\lpr {ignorepars}}]
-This primitives is like \prm {ignorespaces} but also skips paragraph ending
+This primitive is like \prm {ignorespaces} but also skips paragraph ending
commands (normally \prm {par} and empty lines).
\stopsubsection
\startsubsection[title={\lpr {futureexpand}, \lpr {futureexpandis}, \lpr {futureexpandisap}}]
-These commands are use as:
+These commands are used as:
\starttyping
\futureexpand\sometoken\whenfound\whennotfound
@@ -1152,7 +1148,7 @@ measurable when you runs tens of millions of complex tests and in that case it i
very likely to drown in the real action. It's a convenience mechanism, in the
sense that it can make your code look a bit easier to follow.
-There is an nice side effect of this mechanism. When you define:
+There is a nice side effect of this mechanism. When you define:
\starttyping
\def\quitcondition{\orelse\iffalse}
@@ -1244,7 +1240,7 @@ the backend to include an image. The wrapping is needed because a special itself
is a whatsit and as such has no dimensions.
In \PDFTEX\ a special whatsit for images was introduced and that one {\em has}
-dimensions. As a consequence, in several places where the engine to deal with the
+dimensions. As a consequence, in several places where the engine deals with the
dimensions of nodes, it now has to check the details of whatsits. By inheriting
code from \PDFTEX, the \LUATEX\ engine also had that property. However, at some
point this approach was abandoned and a more natural trick was used: images (and
@@ -1254,7 +1250,7 @@ dimensions, the code could be simplified.
When direction nodes and localpar nodes also became first class nodes, whatsits
again became just that: nodes representing whatever you want, but without
dimensions, and therefore they could again be ignored when dimensions mattered.
-And, because images were disguised as rules, as mentioned ,their dimensions
+And, because images were disguised as rules, as mentioned, their dimensions
automatically were taken into account. This seperation between front and backend
cleaned up the code base already quite a bit.
@@ -1263,7 +1259,7 @@ engine never looks at subtypes of rules. That was up to the backend. This means
that image support is not present in \LUAMETATEX. When an image specification was
parsed the special properties, like the filename, or additional attributes, were
stored in the backend and all that \LUATEX\ does is registering a reference to an
-image s specification in the rule node. But, having no backend means nothing is
+image's specification in the rule node. But, having no backend means nothing is
stored, which in turn would make the image inclusion primitives kind of weird.
Therefore you need to realize that contrary to \LUATEX, {\em in \LUAMETATEX\
@@ -1286,7 +1282,7 @@ of course be implemented in \LUA.
\LL
\stoptabulate
-An implementation probably should accepts the usual optional dimension parameters
+An implementation probably should accept the usual optional dimension parameters
for \type {\use...resource} in the same format as for rules. With images, these
dimensions are then used instead of the ones given to \lpr {useimageresource} but
the original dimensions are not overwritten, so that a \lpr {useimageresource}
@@ -1494,7 +1490,7 @@ The approach is that we try to make node lists balanced but also try to avoid
some side effects. What happens is quite intuitive if we forget about spaces
(turned into glue) but even there what happens makes sense if you look at it in
detail. However that logic makes in|-|group switching kind of useless when no
-proper nested grouping is used: switching from right to left several times
+properly nested grouping is used: switching from right to left several times
nested, results in spacing ending up after each other due to nested mirroring. Of
course a sane macro package will manage this for the user but here we are
discussing the low level injection of directional information.
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex b/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
index 077d9e51e..917ebfeb8 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
@@ -9,7 +9,7 @@
\startsection[title={Introduction}]
Only traditional font support is built in, anything more needs to be implemented
-in \LUA. This is conform the \LUATEX\ philosophy. When you pass a font to the
+in \LUA. This conforms to the \LUATEX\ philosophy. When you pass a font to the
frontend only the dimensions matter, as these are used in typesetting, and
optionally ligatures and kerns when you rely on the built|-|in font handler. For
math some extra data is needed, like information about extensibles and next in
@@ -79,37 +79,14 @@ The names and their internal remapping are:
\LL
\stoptabulate
-The \type {characters} table is a list of character hashes indexed by an integer
-number. The number is the \quote {internal code} \TEX\ knows this character by.
-For proper paragraph building and math rendering the following fields can be
-present in en entry in the \type {characters} table. You can of course add all
-kind of extra fields. The engine only uses those that it needs for typesetting
-a paragraph or formula.
-
-Each character hash itself is a hash. For example, here is the character \quote
-{f} (decimal 102) in the font \type {cmr10 at 10pt}. The numbers that represent
-dimensions are in scaled points.
-
-\starttyping
-[102] = {
- ["width"] = 200250,
- ["height"] = 455111,
- ["depth"] = 0,
- ["italic"] = 50973,
- ["kerns"] = {
- [63] = 50973,
- [93] = 50973,
- [39] = 50973,
- [33] = 50973,
- [41] = 50973
- },
- ["ligatures"] = {
- [102] = { ["char"] = 11, ["type"] = 0 },
- [108] = { ["char"] = 13, ["type"] = 0 },
- [105] = { ["char"] = 12, ["type"] = 0 }
- }
-}
-\stoptyping
+The \type {characters} table is a \LUA\ hash table where the keys are integers.
+When a character in the input is turned into a glyph node, it gets a character
+code that normally refers to an entry in that table. For proper paragraph
+building and math rendering the following fields can be present in an entry in
+the \type {characters} table. You can of course add all kind of extra fields. The
+engine only uses those that it needs for typesetting a paragraph or formula. The
+subtables that define ligatures and kerns are also hashes with integer keys, and
+these indices should point to entries in the main characters table.
Providing ligatures and kerns this way permits \TEX\ to construct ligatures and
add inter|-|character kerning. However, normally you will use an \OPENTYPE\ font
@@ -139,6 +116,31 @@ has no ligatures and kerns and is normally not processed at all.
\LL
\stoptabulate
+For example, here is the character \quote {f} (decimal 102) in the font \type
+{cmr10 at 10pt}. The numbers that represent dimensions are in scaled points.
+
+\starttyping
+[102] = {
+ ["width"] = 200250,
+ ["height"] = 455111,
+ ["depth"] = 0,
+ ["italic"] = 50973,
+ ["kerns"] = {
+ [63] = 50973,
+ [93] = 50973,
+ [39] = 50973,
+ [33] = 50973,
+ [41] = 50973
+ },
+ ["ligatures"] = {
+ [102] = { ["char"] = 11, ["type"] = 0 },
+ [108] = { ["char"] = 13, ["type"] = 0 },
+ [105] = { ["char"] = 12, ["type"] = 0 }
+ }
+}
+\stoptyping
+
+
Two very special string indexes can be used also: \type {left_boundary} is a
virtual character whose ligatures and kerns are used to handle word boundary
processing. \type {right_boundary} is similar but not actually used for anything
@@ -235,7 +237,7 @@ indicates the final insertion point.
% \topicindex {fonts+virtual}
Virtual fonts have been introduced to overcome limitations of good old \TEX. They
-were mostly use for providing a direct mapping from for instance accented
+were mostly used for providing a direct mapping from for instance accented
characters onto a glyph. The backend was responsible for turning a reference to a
character slot into a real glyph, possibly constructed from other glyphs. In our
case there is no backend so there is also no need to pass this information
@@ -247,12 +249,11 @@ A virtual character can itself point to virtual characters but be careful with
nesting as you can create loops and overflow the stack (which often indicates an
error anyway).
-At the font level there can be a \type {fonts} an (indexed) \LUA\ table. The
-values are one- or two|-|key hashes themselves, each entry indicating one of the
-base fonts in a virtual font. In case your font is referring to itself in for
-instance a virtual font, you can use the \type {slot} command with a zero font
-reference, which indicates that the font itself is used. So, a table looks like
-this:
+At the font level there can be a an (indexed) \type {fonts} table. The values are
+one- or two|-|key hashes themselves, each entry indicating one of the base fonts
+in a virtual font. In case your font is referring to itself in for instance a
+virtual font, you can use the \type {slot} command with a zero font reference,
+which indicates that the font itself is used. So, a table looks like this:
\starttyping
fonts = {
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex b/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
index 56d5c7436..774f3d8d9 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
@@ -101,8 +101,9 @@ Hans Hagen
\vfilll
{\bf remark:} \LUAMETATEX\ development is mostly done by Hans Hagen and Alan
-Braslau, who love playing with the three languages involved. Testing is done by
-\CONTEXT\ developers and users. Many thanks for their patience!
+Braslau, who love playing with the three languages involved. And as usual Mojca
+Miklavec make sure all compiles well on the buildbot infrastructure. Testing is
+done by \CONTEXT\ developers and users. Many thanks for their patience!
{\bf remark:} When there are non|-|intrusive features that also make sense in
\LUATEX, these will be applied in the experimental branch first, so that there is
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex b/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
index 19112a7f1..b6607a9bb 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
@@ -85,17 +85,6 @@ time (in case of a single|-|glyph word).
\startitem
\type {ligature}, for constructed ligatures bit 1 is set.
\stopitem
- \startitem
- \type {ghost}, for so called \quote {ghost objects} bit 2 is set.
- \stopitem
- \startitem
- \type {left}, for ligatures created from a left word boundary and for
- ghosts created from \lpr {leftghost} bit 3 gets set.
- \stopitem
- \startitem
- \type {right}, for ligatures created from a right word boundary and
- for ghosts created from \lpr {rightghost} bit 4 is set.
- \stopitem
\stopitemize
The \nod {glyph} nodes also contain language data, split into four items that
@@ -142,8 +131,8 @@ initialized you start out with nothing, otherwise you already have a set.
When a \lpr {hjcode} is greater than 0 but less than 32 is indicates the
to be used length. In the following example we map a character (\type {x}) onto
-another one in the patterns and tell the engine that \type {Å“} counts as one
-character. Because traditionally zero itself is reserved for inhibiting
+another one in the patterns and tell the engine that \type {Å“} counts as two
+characters. Because traditionally zero itself is reserved for inhibiting
hyphenation, a value of 32 counts as zero.
Here are some examples (we assume that French patterns are used):
@@ -369,7 +358,7 @@ before---after \par
\stopcombination
\stopbuffer
-\startplacefigure[locationreference=automatichyphenmode:1,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with a \prm {hsize}
+\startplacefigure[reference=automatichyphenmode:1,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with a \prm {hsize}
of 6em and 2pt (which triggers a linebreak).}]
\dontcomplain \tt \getbuffer[demo]
\stopplacefigure
@@ -435,13 +424,6 @@ there are a few exceptions.
\stopitem
\startitem
- The \ALEPH|-|derived commands \lpr {leftghost} and \lpr {rightghost}
- create nodes of a third subtype: \quote {ghost}. These nodes are ignored
- completely by all further processing until the stage where inter|-|glyph
- kerning is added.
-\stopitem
-
-\startitem
Automatic discretionaries are handled differently. \TEX82 inserts an empty
discretionary after sensing an input character that matches the \prm
{hyphenchar} in the current font. This test is wrong in our opinion: whether
@@ -511,7 +493,7 @@ have been added:
\stoptyping
The first parameter has the following consequences for automatic discs (the ones
-resulting from an \prm {exhyphenchar}:
+resulting from an \prm {exhyphenchar}):
\starttabulate[|c|l|l|]
\DB mode \BC automatic disc \type {-} \BC explicit disc \prm{-} \NC \NR
@@ -609,7 +591,7 @@ actual explicit hyphen character if needed). For example, this matches the word
The motivation behind the \ETEX\ extension \prm {savinghyphcodes} was that
hyphenation heavily depended on font encodings. This is no longer true in
\LUATEX, and the corresponding primitive is basically ignored. Because we now
-have \lpr {hjcode}, the case relate codes can be used exclusively for \prm
+have \lpr {hjcode}, the case related codes can be used exclusively for \prm
{uppercase} and \prm {lowercase}.
The three curly brace pair pattern in an exception can be somewhat unexpected so
@@ -777,8 +759,8 @@ boundary items after it is done with them, and it does the same for \quote
{ghost} nodes. Finally, at the end of the kerning stage, all remaining \quote
{character} nodes are converted to \quote {glyph} nodes.
-This word separation is worth mentioning because, if you overrule from \LUA\ only
-one of the two callbacks related to font handling, then you have to make sure you
+This separation is worth mentioning because, if you overrule from \LUA\ only one
+of the two callbacks related to font handling, then you have to make sure you
perform the tasks normally done by \LUATEX\ itself in order to make sure that the
other, non|-|overruled, routine continues to function properly.
@@ -826,7 +808,7 @@ Here is that nested solution again, in a different representation:
\starttabulate[|l|c|c|c|c|c|c|]
\DB \BC pre \BC \BC post \BC \BC replace \BC \NC \NR
\TB
-\NC topdisc \NC \type {f-} \NC (1) \NC \NC sub 1 \NC \NC sub 2 \NC \NR
+\NC topdisc \NC \type {f-} \NC (1) \NC sub 1 \NC \NC sub 2 \NC \NC \NR
\NC sub 1 \NC \type {f-} \NC (2) \NC \type {i} \NC (3) \NC \type {<fi>} \NC (4) \NC \NR
\NC sub 2 \NC \type {<ff>-} \NC (5) \NC \type {i} \NC (6) \NC \type {<ffi>} \NC (7) \NC \NR
\LL
@@ -907,13 +889,13 @@ approach.
\topicindex {paragraphs}
\topicindex {discretionaries}
-This code is almost unchanged, but because of the above|-|mentioned changes
-with respect to discretionaries and ligatures, line breaking will potentially be
+This code is almost unchanged, but because of the above|-|mentioned changes with
+respect to discretionaries and ligatures, line breaking will potentially be
different from traditional \TEX. The actual line breaking code is still based on
-the \TEX82 algorithms, and it does not expect there to be discretionaries inside
-of discretionaries. But, as patterns evolve and font handling can influence
-discretionaries, you need to be aware of the fact that long term consistency is not
-an engine matter only.
+the \TEX82 algorithms, and there can be no discretionaries inside of
+discretionaries. But, as patterns evolve and font handling can influence
+discretionaries, you need to be aware of the fact that long term consistency is
+not an engine matter only.
But that situation is now fairly common in \LUATEX, due to the changes to the
ligaturing mechanism. And also, the \LUATEX\ discretionary nodes are implemented
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-math.tex b/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
index 111a6cf03..ce4fe1544 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
@@ -593,10 +593,12 @@ with zero being the default behaviour.
\start
+\def\MathHack#1{\mathsurroundmode#1\relax\inlinebuffer}
+
\def\OneLiner#1#2%
{\NC \type{#1}
- \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x$x$x}
- \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x $x$ x}
+ \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\hsize 100pt x$\MathHack{#1}x$x}
+ \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\hsize 100pt x $\MathHack{#1}x$ x}
\NC #2
\NC \NR}
@@ -605,7 +607,7 @@ with zero being the default behaviour.
\mathsurroundskip20pt
\stopbuffer
-\typebuffer \getbuffer
+\typebuffer
\starttabulate[|c|c|c|pl|]
\DB mode \BC x\$x\$x \BC x \$x\$ x \BC effect \NC \NR
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex b/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
index 3f0d0a945..5128f3d2a 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
@@ -448,32 +448,6 @@ id in the range 0 to 255; the returned \type {w} is in AFM units.
<number> d = char_depth(mp,<string> fontname, <number> char)
\stopfunctioncall
-These are rather useless and might become obsolete.
-
-\subsection{\type {get_[boolean|numeric|string|path]}}
-
-\libindex{get_boolean}
-\libindex{get_numeric}
-\libindex{get_path}
-\libindex{get_string}
-
-When a script call brings you from the \METAPOST\ run (temporarily) back to
-\LUA\ you can access variables, but only if they are known (so for instance
-anonymous capsules like loop variables are not accessible).
-
-\startfunctioncall
-<boolean> w = get_boolean(mp,<string> name)
-<number> n = get_numeric(mp,<string> name)
-<string> s = get_string (mp,<string> name)
-<table> p = get_path (mp,<string> name)
-\stopfunctioncall
-
-The path is returned a a table with subtables that have six numbers: the
-coordinates of the point, pre- and postcontrol. A \type {cycle} fields indicates
-if a path is cyclic.
-
-\stopsection
-
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex b/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
index 8b4f6101c..16c6e1202 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
@@ -16,11 +16,11 @@
\TEX's nodes are represented in \LUA\ as userdata objects with a variable set of
fields or by a numeric identifier when requested. When you print a node userdata
-object you will see these numbers. In the following syntax tables, such as the
-type of such a userdata object is represented as \syntax {<node>}.
+object you will see these numbers. In the following syntax tables the type of
+such a userdata object is represented as \syntax {<node>}.
\blank
-\dontleavehmode {\bf The return values of \type {node.types()} are:} \showtypes
+\dontleavehmode {\bf The return values of \type {node.types} are:} \showtypes
\blank
In \ETEX\ the \prm {lastnodetype} primitive has been introduced. With this
@@ -41,7 +41,7 @@ also reported with this helper, but they are backend specific.
\def\ShowValues#1{
\blank
\dontleavehmode
- {\bf The return values of \type {node.values("#1"} are:}
+ {\bf The return values of \type {node.values("#1")} are:}
\showvalues{#1}
\blank
}
@@ -489,7 +489,7 @@ bits for the \type {subtype} field are:
\stoptabulate
The \type {expansion_factor} has been introduced as part of the separation
-between font- and backend. It is the result of extensive experiments with a more
+between front- and backend. It is the result of extensive experiments with a more
efficient implementation of expansion. Early versions of \LUATEX\ already
replaced multiple instances of fonts in the backend by scaling but contrary to
\PDFTEX\ in \LUATEX\ we now also got rid of font copies in the frontend and
@@ -1011,7 +1011,7 @@ providing an overview of the possible top|-|level \type {id} types.
<table> t = node.types()
\stopfunctioncall
-when we issue this command, we get a table. The currently visible types are
+When we issue this command, we get a table. The currently visible types are
\inlineluavalue { node.types() } where the numbers are the internal identifiers.
Only those nodes are reported that make sense to users so there can be gaps in
the range of numbers.
@@ -1031,7 +1031,7 @@ This converts a single type name to its internal numeric representation.
The \type {node.id("glyph")} command returns the number \inlineluavalue { node.id
("glyph") } and \type {node.id("hlist")} returns \inlineluavalue { node.id
-("hlist") } where the number don't relate to importance or some ordering; they
+("hlist") } where the numbers don't relate to importance or some ordering; they
just appear in the order that is handy for the engine. Commands like this are
rather optimized so performance should be ok but you can of course always store
the id in a \LUA\ number.
@@ -1056,8 +1056,8 @@ there is no node with that id.
\libindex {fields}
\libindex {has_field}
-This function returns an indexed table with valid field names for a particular type of
-node.
+This function returns an indexed table with valid field names for a particular
+type of node.
\startfunctioncall
<table> t = node.fields(<number|string> id)
@@ -1185,9 +1185,9 @@ affect all the nodes that share that list.
node.write(<node> n)
\stopfunctioncall
-This function that will append a node list to \TEX's \quote {current list}. The
-node list is not deep|-|copied! There is no error checking either! You mignt need
-to enforce horizontal mode in order for this to work as expected.
+This function will append a node list to \TEX's \quote {current list}. The node
+list is not deep|-|copied! There is no error checking either! You might need to
+enforce horizontal mode in order for this to work as expected.
\stopsubsubsection
@@ -1199,7 +1199,7 @@ to enforce horizontal mode in order for this to work as expected.
\libindex {slide}
-This helper makes sure that the node lists is double linked and returns the found
+This helper makes sure that the node list is double linked and returns the found
tail node.
\startfunctioncall
@@ -1445,8 +1445,8 @@ experimental) convenience.
This helper returns the location of the first match at or after node \type {n}:
\startfunctioncall
-<node> n = node.traverse_list(<node> n, <integer> subtype)
-<node> n, subtype = node.traverse_list(<node> n)
+<node> n = node.find_node(<node> n, <integer> subtype)
+<node> n, subtype = node.find_node(<node> n)
\stopfunctioncall
\stopsubsubsection
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex b/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
index 382ed05a4..9e26c6bc4 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
@@ -337,8 +337,6 @@ new primitives, a summary is given below.
\NC \type {noboundary} \NC command \NC \NC \NR
\NC \type {protrusionboundary} \NC command \NC \NC \NR
\NC \type {wordboundary} \NC command \NC \NC \NR
-\NC \type {leftghost} \NC charactercode \NC \NC \NR
-\NC \type {rightghost} \NC charactercode \NC \NC \NR
\NC \type {nohrule} \NC command \NC \NC \NR
\NC \type {novrule} \NC command \NC \NC \NR
\NC \type {insertht} \NC number \NC \NC \NR
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
index 839bae409..25f70dd2f 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
@@ -273,7 +273,7 @@ on the actual \TEX\ values. As a result, most of the \LUA\ table operators (like
\type {pairs} and \type {#}) do not work on such items.
At the moment, it is possible to access almost every parameter that you can use
-after \prm {the}, is a single tokens or is sort of special in \TEX. This excludes
+after \prm {the}, is a single token or is sort of special in \TEX. This excludes
parameters that need extra arguments, like \type {\the\scriptfont}. The subset
comprising simple integer and dimension registers are writable as well as
readable (like \prm {tracingcommands} and \prm {parindent}).
@@ -1133,6 +1133,11 @@ The known fields are:
\LL
\stoptabulate
+When a second string argument is given to the \type {getnest}, the value with
+that name is returned. Of course the level must be valid. When \type {setnest}
+gets a third argument that value is assigned to the field given as second
+argument.
+
\stopsubsection
\startsubsection[reference=sec:luaprint,title={Print functions}]
@@ -2171,7 +2176,7 @@ a bit but for passing strings conversion to and from tokens has to be done anywa
\stopsubsection
-\startsubsection[title= {Picking up one token}]
+\startsubsection[title={Picking up one token}]
\libindex {get_next}
\libindex {scan_token}
diff --git a/doc/context/sources/general/manuals/sql/sql-mkiv.tex b/doc/context/sources/general/manuals/sql/sql-mkiv.tex
index 4d2ecbc6e..835065ba0 100644
--- a/doc/context/sources/general/manuals/sql/sql-mkiv.tex
+++ b/doc/context/sources/general/manuals/sql/sql-mkiv.tex
@@ -493,8 +493,8 @@ context --extra=sql-tables --help
\startsection[title=Example]
-The distribution has a few examples, for instance a logger. The following code shows
-a bit of this (we assume that the swiglib sqlite module is present):
+The distribution has a few examples, for instance a logger. The following code
+shows a bit of this (we assume that \SQLITE\ is installed):
\startbuffer
require("util-sql")
diff --git a/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua b/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua
index 0797f6406..802efcf3d 100644
--- a/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua
+++ b/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua
@@ -351,4 +351,15 @@ return {
<path d="M0,5 h-3 M0,7 h3 M0,9 h-1" stroke="rgba(255,0,0,.5)" />
</svg>
]],
+ [[
+ svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
+ <path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
+ <text text-anchor="start" x="60" y="40">A</text>
+ <text text-anchor="middle" x="60" y="75">A</text>
+ <text text-anchor="end" x="60" y="110">A</text>
+ <circle cx="60" cy="40" r="3" fill="red" />
+ <circle cx="60" cy="75" r="3" fill="red" />
+ <circle cx="60" cy="110" r="3" fill="red" />
+ </svg>
+ ]],
}
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 908d45686..fcba696c4 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -16,7 +16,7 @@ local lower = string.lower
local concat = table.concat
local write_nl = (logs and logs.writer) or (texio and texio.write_nl) or print
-local otlversion = 3.110
+local otlversion = 3.111
local helpinfo = [[
<?xml version="1.0"?>
diff --git a/scripts/context/lua/mtx-unicode.lua b/scripts/context/lua/mtx-unicode.lua
index 85860ddfd..297807889 100644
--- a/scripts/context/lua/mtx-unicode.lua
+++ b/scripts/context/lua/mtx-unicode.lua
@@ -699,9 +699,12 @@ do
local hash = { }
+ local crap = lpeg.P("e") * lpeg.R("09","..","09")^1 * lpeg.P(" ")^1
+
local replace = lpeg.replacer {
- ["#"] = "hash",
- ["*"] = "asterisk"
+ [crap] = "",
+ ["#"] = "hash",
+ ["*"] = "asterisk",
}
for i=1,#t do
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index bcc3bb243..15e99eb91 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -2102,7 +2102,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 42339, stripped down to: 21588
+-- original size: 41758, stripped down to: 22643
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2445,13 +2445,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -2470,6 +2470,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -2490,6 +2492,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -2561,6 +2565,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -2570,7 +2576,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2598,12 +2604,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -2611,12 +2621,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -2625,6 +2639,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -2641,6 +2657,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -2653,11 +2671,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -2679,6 +2699,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -2698,6 +2720,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -2715,6 +2739,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -2738,6 +2764,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3779,7 +3806,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 18925, stripped down to: 10095
+-- original size: 19102, stripped down to: 10192
if not modules then modules={} end modules ['l-os']={
version=1.001,
@@ -4200,6 +4227,12 @@ function os.validdate(year,month,day)
end
return year,month,day
end
+function os.date(fmt,...)
+ if not fmt then
+ fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
@@ -6530,7 +6563,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 45072, stripped down to: 22629
+-- original size: 45188, stripped down to: 22734
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6945,9 +6978,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -7412,7 +7448,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 29567, stripped down to: 16483
+-- original size: 32649, stripped down to: 18257
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7649,92 +7685,160 @@ function tables.encapsulate(core,capsule,protect)
} )
end
end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(0,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(0,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(0)
+ fastserialize(v)
+ m=m+1 r[m]=f_indexed_table(0)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
+ for i=1,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
end
end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv=type(v)
if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
+ m=m+1 r[m]=f_hashed_string(k,v)
elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
+ m=m+1 r[m]=f_hashed_number(k,v)
elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
+ m=m+1 r[m]=f_hashed_table(k)
fastserialize(v)
elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
+ r[m]="},"
end
+ return r
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ m=m+1
+ r[m]="[0]='"
+ if type(v)=="table" then
+ fastserialize(v)
+ else
+ r[m]=format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v=t[i]
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
end
function table.deserialize(str)
if not str or str=="" then
@@ -7828,27 +7932,27 @@ function table.twowaymapper(t)
return t
end
local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str=formatters["%w[%q]={"]
local f_start_key_boo=formatters["%w[%l]={"]
local f_start_key_nop=formatters["%w{"]
local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not=formatters["%w[%Q]={},"]
local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str=formatters["%w%Q,"]
local f_val_boo=formatters["%w%l,"]
local f_val_not=formatters["%w{},"]
@@ -21589,7 +21693,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16070, stripped down to: 11353
+-- original size: 16099, stripped down to: 11379
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21876,7 +21980,7 @@ function caches.is_writable(filepath,filename)
local tmaname,tmcname=setluanames(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions={ compact=true }
+local saveoptions={ compact=true,accurate=not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname,tmcname=setluanames(filepath,filename)
data.cache_uuid=osuuid()
@@ -25385,363 +25489,147 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-package.loaded["util-lib"] = package.loaded["util-lib"] or true
+package.loaded["libs-ini"] = package.loaded["libs-ini"] or true
--- original size: 17659, stripped down to: 9560
+-- original size: 5822, stripped down to: 3629
-if not modules then modules={} end modules ['util-lib']={
+if not modules then modules={} end modules ['libs-ini']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ license="see context related readme files"
}
+local type,unpack=type,unpack
local type=type
-local next=next
-local pcall=pcall
-local gsub=string.gsub
-local find=string.find
-local sort=table.sort
-local pathpart=file.pathpart
local nameonly=file.nameonly
local joinfile=file.join
-local removesuffix=file.removesuffix
local addsuffix=file.addsuffix
-local findfile=resolvers.findfile
-local findfiles=resolvers.findfiles
-local expandpaths=resolvers.expandedpathlistfromvariable
local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
-local done=false
-local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
+local findfile=resolvers.findfile
+local expandpaths=resolvers.expandedpathlistfromvariable
+local report=logs.reporter("resolvers","libraries")
+local trace=false
+trackers.register("resolvers.lib",function(v) trace=v end)
+local function findlib(required)
+ local suffix=os.libsuffix or "so"
+ if not qualifiedpath(required) then
+ local list=directives.value("system.librarynames" )
+ local only=nameonly(required)
+ if type(list)=="table" then
+ list=list[only]
+ if type(list)~="table" then
+ list={ only }
end
- found_library=required
else
- if trace then
- report("qualified name %a not found",required)
- end
- end
- else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine=environment.ownmain or false
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ list={ only }
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
+ if trace then
+ report("using lookup list for library %a: % | t",only,list)
end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
+ for i=1,#list do
+ local name=list[i]
+ local found=findfile(name,"lib")
+ if not found then
+ found=findfile(addsuffix(name,suffix),"lib")
end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
+ if found then
if trace then
- report("checking %s: %a","with version",asked_library)
+ report("library %a resolved via %a path to %a",name,"tds lib",found)
end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
- end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
+ if expandpaths then
+ local list=expandpaths("PATH")
+ local base=addsuffix(only,suffix)
+ for i=1,#list do
+ local full=joinfile(list[i],base)
+ local found=isfile(full) and full
+ if found then
+ if trace then
+ report("library %a resolved via %a path to %a",name,"system",found)
+ end
+ return found
end
- found_library=attempt()
end
- else
- found_library=attempt()
end
- end
- if not found_library then
+ elseif isfile(addsuffix(required,suffix)) then
if trace then
- report("not found: %a",required)
+ report("library with qualified name %a %sfound",required,"")
end
- library=false
+ return required
else
if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ report("library with qualified name %a %sfound",required,"not ")
end
end
- if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
- end
- return library or nil
+ return false
end
-resolvers.locatelib=locate
-do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+local foundlibraries=table.setmetatableindex(function(t,k)
+ local v=findlib(k)
+ t[k]=v
+ return v
+end)
+function resolvers.findlib(required)
+ return foundlibraries[required]
+end
+local libraries={}
+resolvers.libraries=libraries
+local report=logs.reporter("optional")
+if optional then optional.loaded={} end
+function libraries.validoptional(name)
+ local thelib=optional and optional[name]
+ if not thelib then
+ elseif thelib.initialize then
+ return thelib
+ else
+ report("invalid optional library %a",libname)
+ end
+end
+function libraries.optionalloaded(name,libnames)
+ local thelib=optional and optional[name]
+ if not thelib then
+ report("no optional %a library found",name)
+ else
+ local thelib_initialize=thelib.initialize
+ if not thelib_initialize then
+ report("invalid optional library %a",name)
+ else
+ if type(libnames)=="string" then
+ libnames={ libnames }
+ end
+ if type(libnames)=="table" then
+ for i=1,#libnames do
+ local libname=libnames[i]
+ local filename=foundlibraries[libname]
+ if filename then
+ libnames[i]=filename
+ else
+ report("unable to locate library %a",libname)
+ return
+ end
+ end
+ local initialized=thelib_initialize(unpack(libnames))
+ if initialized then
+ report("using library '% + t'",libnames)
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ report("unable to initialize library '% + t'",libnames)
end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
+ return initialized
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
- end
- return { required }
- end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
- end
+ local ffiload=ffi.load
function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
- end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
- end
- end
-end
-do
- local isfile=lfs.isfile
- local report=logs.reporter("resolvers","lib")
- local trace=false
- trackers.register("resolvers.lib",function(v) trace=v end)
- local function action(filename)
- return isfile(filename) and filename or false
- end
- function resolvers.findlib(required)
- local list=directives.value("system.librarynames" )
- local only=nameonly(required)
- if type(list)=="table" then
- list=list[only]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",only,list)
- end
- else
- list={ only }
- end
+ local full=name and foundlibraries[name]
+ if full then
+ return ffiload(full)
else
- list={ only }
- end
- for i=1,#list do
- local name=list[i]
- local found=locate(name,false,trace,report,action)
- if found then
- return found
- end
- end
- local getpaths=resolvers.expandedpathlistfromvariable
- if getpaths then
- local list=getpaths("PATH")
- local base=addsuffix(only,os.libsuffix)
- for i=1,#list do
- local full=joinfile(list[i],base)
- local found=locate(full,false,trace,report,action)
- if found then
- return found
- end
- end
+ return ffiload(name)
end
end
end
@@ -26187,10 +26075,10 @@ end
end -- of closure
--- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1047142
--- stripped bytes : 416876
+-- original bytes : 1038128
+-- stripped bytes : 410736
-- end library merge
@@ -26304,7 +26192,7 @@ local ownlibs = { -- order can be made better
'data-tmf.lua',
'data-lst.lua',
- 'util-lib.lua', -- swiglib
+ 'libs-ini.lua',
'luat-sta.lua',
'luat-fmt.lua',
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index bcc3bb243..15e99eb91 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -2102,7 +2102,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 42339, stripped down to: 21588
+-- original size: 41758, stripped down to: 22643
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2445,13 +2445,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -2470,6 +2470,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -2490,6 +2492,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -2561,6 +2565,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -2570,7 +2576,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2598,12 +2604,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -2611,12 +2621,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -2625,6 +2639,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -2641,6 +2657,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -2653,11 +2671,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -2679,6 +2699,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -2698,6 +2720,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -2715,6 +2739,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -2738,6 +2764,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3779,7 +3806,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 18925, stripped down to: 10095
+-- original size: 19102, stripped down to: 10192
if not modules then modules={} end modules ['l-os']={
version=1.001,
@@ -4200,6 +4227,12 @@ function os.validdate(year,month,day)
end
return year,month,day
end
+function os.date(fmt,...)
+ if not fmt then
+ fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
@@ -6530,7 +6563,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 45072, stripped down to: 22629
+-- original size: 45188, stripped down to: 22734
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6945,9 +6978,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -7412,7 +7448,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 29567, stripped down to: 16483
+-- original size: 32649, stripped down to: 18257
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7649,92 +7685,160 @@ function tables.encapsulate(core,capsule,protect)
} )
end
end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(0,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(0,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(0)
+ fastserialize(v)
+ m=m+1 r[m]=f_indexed_table(0)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
+ for i=1,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
end
end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv=type(v)
if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
+ m=m+1 r[m]=f_hashed_string(k,v)
elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
+ m=m+1 r[m]=f_hashed_number(k,v)
elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
+ m=m+1 r[m]=f_hashed_table(k)
fastserialize(v)
elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
+ r[m]="},"
end
+ return r
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ m=m+1
+ r[m]="[0]='"
+ if type(v)=="table" then
+ fastserialize(v)
+ else
+ r[m]=format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v=t[i]
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
end
function table.deserialize(str)
if not str or str=="" then
@@ -7828,27 +7932,27 @@ function table.twowaymapper(t)
return t
end
local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str=formatters["%w[%q]={"]
local f_start_key_boo=formatters["%w[%l]={"]
local f_start_key_nop=formatters["%w{"]
local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not=formatters["%w[%Q]={},"]
local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str=formatters["%w%Q,"]
local f_val_boo=formatters["%w%l,"]
local f_val_not=formatters["%w{},"]
@@ -21589,7 +21693,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16070, stripped down to: 11353
+-- original size: 16099, stripped down to: 11379
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21876,7 +21980,7 @@ function caches.is_writable(filepath,filename)
local tmaname,tmcname=setluanames(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions={ compact=true }
+local saveoptions={ compact=true,accurate=not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname,tmcname=setluanames(filepath,filename)
data.cache_uuid=osuuid()
@@ -25385,363 +25489,147 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-package.loaded["util-lib"] = package.loaded["util-lib"] or true
+package.loaded["libs-ini"] = package.loaded["libs-ini"] or true
--- original size: 17659, stripped down to: 9560
+-- original size: 5822, stripped down to: 3629
-if not modules then modules={} end modules ['util-lib']={
+if not modules then modules={} end modules ['libs-ini']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ license="see context related readme files"
}
+local type,unpack=type,unpack
local type=type
-local next=next
-local pcall=pcall
-local gsub=string.gsub
-local find=string.find
-local sort=table.sort
-local pathpart=file.pathpart
local nameonly=file.nameonly
local joinfile=file.join
-local removesuffix=file.removesuffix
local addsuffix=file.addsuffix
-local findfile=resolvers.findfile
-local findfiles=resolvers.findfiles
-local expandpaths=resolvers.expandedpathlistfromvariable
local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
-local done=false
-local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
+local findfile=resolvers.findfile
+local expandpaths=resolvers.expandedpathlistfromvariable
+local report=logs.reporter("resolvers","libraries")
+local trace=false
+trackers.register("resolvers.lib",function(v) trace=v end)
+local function findlib(required)
+ local suffix=os.libsuffix or "so"
+ if not qualifiedpath(required) then
+ local list=directives.value("system.librarynames" )
+ local only=nameonly(required)
+ if type(list)=="table" then
+ list=list[only]
+ if type(list)~="table" then
+ list={ only }
end
- found_library=required
else
- if trace then
- report("qualified name %a not found",required)
- end
- end
- else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine=environment.ownmain or false
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ list={ only }
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
+ if trace then
+ report("using lookup list for library %a: % | t",only,list)
end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
+ for i=1,#list do
+ local name=list[i]
+ local found=findfile(name,"lib")
+ if not found then
+ found=findfile(addsuffix(name,suffix),"lib")
end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
+ if found then
if trace then
- report("checking %s: %a","with version",asked_library)
+ report("library %a resolved via %a path to %a",name,"tds lib",found)
end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
- end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
+ if expandpaths then
+ local list=expandpaths("PATH")
+ local base=addsuffix(only,suffix)
+ for i=1,#list do
+ local full=joinfile(list[i],base)
+ local found=isfile(full) and full
+ if found then
+ if trace then
+ report("library %a resolved via %a path to %a",name,"system",found)
+ end
+ return found
end
- found_library=attempt()
end
- else
- found_library=attempt()
end
- end
- if not found_library then
+ elseif isfile(addsuffix(required,suffix)) then
if trace then
- report("not found: %a",required)
+ report("library with qualified name %a %sfound",required,"")
end
- library=false
+ return required
else
if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ report("library with qualified name %a %sfound",required,"not ")
end
end
- if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
- end
- return library or nil
+ return false
end
-resolvers.locatelib=locate
-do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+local foundlibraries=table.setmetatableindex(function(t,k)
+ local v=findlib(k)
+ t[k]=v
+ return v
+end)
+function resolvers.findlib(required)
+ return foundlibraries[required]
+end
+local libraries={}
+resolvers.libraries=libraries
+local report=logs.reporter("optional")
+if optional then optional.loaded={} end
+function libraries.validoptional(name)
+ local thelib=optional and optional[name]
+ if not thelib then
+ elseif thelib.initialize then
+ return thelib
+ else
+ report("invalid optional library %a",libname)
+ end
+end
+function libraries.optionalloaded(name,libnames)
+ local thelib=optional and optional[name]
+ if not thelib then
+ report("no optional %a library found",name)
+ else
+ local thelib_initialize=thelib.initialize
+ if not thelib_initialize then
+ report("invalid optional library %a",name)
+ else
+ if type(libnames)=="string" then
+ libnames={ libnames }
+ end
+ if type(libnames)=="table" then
+ for i=1,#libnames do
+ local libname=libnames[i]
+ local filename=foundlibraries[libname]
+ if filename then
+ libnames[i]=filename
+ else
+ report("unable to locate library %a",libname)
+ return
+ end
+ end
+ local initialized=thelib_initialize(unpack(libnames))
+ if initialized then
+ report("using library '% + t'",libnames)
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ report("unable to initialize library '% + t'",libnames)
end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
+ return initialized
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
- end
- return { required }
- end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
- end
+ local ffiload=ffi.load
function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
- end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
- end
- end
-end
-do
- local isfile=lfs.isfile
- local report=logs.reporter("resolvers","lib")
- local trace=false
- trackers.register("resolvers.lib",function(v) trace=v end)
- local function action(filename)
- return isfile(filename) and filename or false
- end
- function resolvers.findlib(required)
- local list=directives.value("system.librarynames" )
- local only=nameonly(required)
- if type(list)=="table" then
- list=list[only]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",only,list)
- end
- else
- list={ only }
- end
+ local full=name and foundlibraries[name]
+ if full then
+ return ffiload(full)
else
- list={ only }
- end
- for i=1,#list do
- local name=list[i]
- local found=locate(name,false,trace,report,action)
- if found then
- return found
- end
- end
- local getpaths=resolvers.expandedpathlistfromvariable
- if getpaths then
- local list=getpaths("PATH")
- local base=addsuffix(only,os.libsuffix)
- for i=1,#list do
- local full=joinfile(list[i],base)
- local found=locate(full,false,trace,report,action)
- if found then
- return found
- end
- end
+ return ffiload(name)
end
end
end
@@ -26187,10 +26075,10 @@ end
end -- of closure
--- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1047142
--- stripped bytes : 416876
+-- original bytes : 1038128
+-- stripped bytes : 410736
-- end library merge
@@ -26304,7 +26192,7 @@ local ownlibs = { -- order can be made better
'data-tmf.lua',
'data-lst.lua',
- 'util-lib.lua', -- swiglib
+ 'libs-ini.lua',
'luat-sta.lua',
'luat-fmt.lua',
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index bcc3bb243..15e99eb91 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -2102,7 +2102,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 42339, stripped down to: 21588
+-- original size: 41758, stripped down to: 22643
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2445,13 +2445,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -2470,6 +2470,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -2490,6 +2492,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -2561,6 +2565,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -2570,7 +2576,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2598,12 +2604,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -2611,12 +2621,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -2625,6 +2639,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -2641,6 +2657,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -2653,11 +2671,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -2679,6 +2699,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -2698,6 +2720,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -2715,6 +2739,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -2738,6 +2764,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3779,7 +3806,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 18925, stripped down to: 10095
+-- original size: 19102, stripped down to: 10192
if not modules then modules={} end modules ['l-os']={
version=1.001,
@@ -4200,6 +4227,12 @@ function os.validdate(year,month,day)
end
return year,month,day
end
+function os.date(fmt,...)
+ if not fmt then
+ fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
@@ -6530,7 +6563,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 45072, stripped down to: 22629
+-- original size: 45188, stripped down to: 22734
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6945,9 +6978,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -7412,7 +7448,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 29567, stripped down to: 16483
+-- original size: 32649, stripped down to: 18257
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7649,92 +7685,160 @@ function tables.encapsulate(core,capsule,protect)
} )
end
end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(0,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(0,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(0)
+ fastserialize(v)
+ m=m+1 r[m]=f_indexed_table(0)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
+ for i=1,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
end
end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv=type(v)
if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
+ m=m+1 r[m]=f_hashed_string(k,v)
elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
+ m=m+1 r[m]=f_hashed_number(k,v)
elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
+ m=m+1 r[m]=f_hashed_table(k)
fastserialize(v)
elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
+ r[m]="},"
end
+ return r
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ m=m+1
+ r[m]="[0]='"
+ if type(v)=="table" then
+ fastserialize(v)
+ else
+ r[m]=format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v=t[i]
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
end
function table.deserialize(str)
if not str or str=="" then
@@ -7828,27 +7932,27 @@ function table.twowaymapper(t)
return t
end
local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str=formatters["%w[%q]={"]
local f_start_key_boo=formatters["%w[%l]={"]
local f_start_key_nop=formatters["%w{"]
local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not=formatters["%w[%Q]={},"]
local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str=formatters["%w%Q,"]
local f_val_boo=formatters["%w%l,"]
local f_val_not=formatters["%w{},"]
@@ -21589,7 +21693,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16070, stripped down to: 11353
+-- original size: 16099, stripped down to: 11379
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21876,7 +21980,7 @@ function caches.is_writable(filepath,filename)
local tmaname,tmcname=setluanames(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions={ compact=true }
+local saveoptions={ compact=true,accurate=not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname,tmcname=setluanames(filepath,filename)
data.cache_uuid=osuuid()
@@ -25385,363 +25489,147 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-package.loaded["util-lib"] = package.loaded["util-lib"] or true
+package.loaded["libs-ini"] = package.loaded["libs-ini"] or true
--- original size: 17659, stripped down to: 9560
+-- original size: 5822, stripped down to: 3629
-if not modules then modules={} end modules ['util-lib']={
+if not modules then modules={} end modules ['libs-ini']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ license="see context related readme files"
}
+local type,unpack=type,unpack
local type=type
-local next=next
-local pcall=pcall
-local gsub=string.gsub
-local find=string.find
-local sort=table.sort
-local pathpart=file.pathpart
local nameonly=file.nameonly
local joinfile=file.join
-local removesuffix=file.removesuffix
local addsuffix=file.addsuffix
-local findfile=resolvers.findfile
-local findfiles=resolvers.findfiles
-local expandpaths=resolvers.expandedpathlistfromvariable
local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
-local done=false
-local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
+local findfile=resolvers.findfile
+local expandpaths=resolvers.expandedpathlistfromvariable
+local report=logs.reporter("resolvers","libraries")
+local trace=false
+trackers.register("resolvers.lib",function(v) trace=v end)
+local function findlib(required)
+ local suffix=os.libsuffix or "so"
+ if not qualifiedpath(required) then
+ local list=directives.value("system.librarynames" )
+ local only=nameonly(required)
+ if type(list)=="table" then
+ list=list[only]
+ if type(list)~="table" then
+ list={ only }
end
- found_library=required
else
- if trace then
- report("qualified name %a not found",required)
- end
- end
- else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine=environment.ownmain or false
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ list={ only }
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
+ if trace then
+ report("using lookup list for library %a: % | t",only,list)
end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
+ for i=1,#list do
+ local name=list[i]
+ local found=findfile(name,"lib")
+ if not found then
+ found=findfile(addsuffix(name,suffix),"lib")
end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
+ if found then
if trace then
- report("checking %s: %a","with version",asked_library)
+ report("library %a resolved via %a path to %a",name,"tds lib",found)
end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
- end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
+ if expandpaths then
+ local list=expandpaths("PATH")
+ local base=addsuffix(only,suffix)
+ for i=1,#list do
+ local full=joinfile(list[i],base)
+ local found=isfile(full) and full
+ if found then
+ if trace then
+ report("library %a resolved via %a path to %a",name,"system",found)
+ end
+ return found
end
- found_library=attempt()
end
- else
- found_library=attempt()
end
- end
- if not found_library then
+ elseif isfile(addsuffix(required,suffix)) then
if trace then
- report("not found: %a",required)
+ report("library with qualified name %a %sfound",required,"")
end
- library=false
+ return required
else
if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ report("library with qualified name %a %sfound",required,"not ")
end
end
- if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
- end
- return library or nil
+ return false
end
-resolvers.locatelib=locate
-do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+local foundlibraries=table.setmetatableindex(function(t,k)
+ local v=findlib(k)
+ t[k]=v
+ return v
+end)
+function resolvers.findlib(required)
+ return foundlibraries[required]
+end
+local libraries={}
+resolvers.libraries=libraries
+local report=logs.reporter("optional")
+if optional then optional.loaded={} end
+function libraries.validoptional(name)
+ local thelib=optional and optional[name]
+ if not thelib then
+ elseif thelib.initialize then
+ return thelib
+ else
+ report("invalid optional library %a",libname)
+ end
+end
+function libraries.optionalloaded(name,libnames)
+ local thelib=optional and optional[name]
+ if not thelib then
+ report("no optional %a library found",name)
+ else
+ local thelib_initialize=thelib.initialize
+ if not thelib_initialize then
+ report("invalid optional library %a",name)
+ else
+ if type(libnames)=="string" then
+ libnames={ libnames }
+ end
+ if type(libnames)=="table" then
+ for i=1,#libnames do
+ local libname=libnames[i]
+ local filename=foundlibraries[libname]
+ if filename then
+ libnames[i]=filename
+ else
+ report("unable to locate library %a",libname)
+ return
+ end
+ end
+ local initialized=thelib_initialize(unpack(libnames))
+ if initialized then
+ report("using library '% + t'",libnames)
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ report("unable to initialize library '% + t'",libnames)
end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
+ return initialized
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
- end
- return { required }
- end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
- end
+ local ffiload=ffi.load
function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
- end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
- end
- end
-end
-do
- local isfile=lfs.isfile
- local report=logs.reporter("resolvers","lib")
- local trace=false
- trackers.register("resolvers.lib",function(v) trace=v end)
- local function action(filename)
- return isfile(filename) and filename or false
- end
- function resolvers.findlib(required)
- local list=directives.value("system.librarynames" )
- local only=nameonly(required)
- if type(list)=="table" then
- list=list[only]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",only,list)
- end
- else
- list={ only }
- end
+ local full=name and foundlibraries[name]
+ if full then
+ return ffiload(full)
else
- list={ only }
- end
- for i=1,#list do
- local name=list[i]
- local found=locate(name,false,trace,report,action)
- if found then
- return found
- end
- end
- local getpaths=resolvers.expandedpathlistfromvariable
- if getpaths then
- local list=getpaths("PATH")
- local base=addsuffix(only,os.libsuffix)
- for i=1,#list do
- local full=joinfile(list[i],base)
- local found=locate(full,false,trace,report,action)
- if found then
- return found
- end
- end
+ return ffiload(name)
end
end
end
@@ -26187,10 +26075,10 @@ end
end -- of closure
--- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1047142
--- stripped bytes : 416876
+-- original bytes : 1038128
+-- stripped bytes : 410736
-- end library merge
@@ -26304,7 +26192,7 @@ local ownlibs = { -- order can be made better
'data-tmf.lua',
'data-lst.lua',
- 'util-lib.lua', -- swiglib
+ 'libs-ini.lua',
'luat-sta.lua',
'luat-fmt.lua',
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index bcc3bb243..15e99eb91 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -2102,7 +2102,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 42339, stripped down to: 21588
+-- original size: 41758, stripped down to: 22643
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2445,13 +2445,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -2470,6 +2470,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -2490,6 +2492,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -2561,6 +2565,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -2570,7 +2576,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2598,12 +2604,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -2611,12 +2621,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -2625,6 +2639,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -2641,6 +2657,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -2653,11 +2671,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -2679,6 +2699,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -2698,6 +2720,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -2715,6 +2739,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -2738,6 +2764,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3779,7 +3806,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 18925, stripped down to: 10095
+-- original size: 19102, stripped down to: 10192
if not modules then modules={} end modules ['l-os']={
version=1.001,
@@ -4200,6 +4227,12 @@ function os.validdate(year,month,day)
end
return year,month,day
end
+function os.date(fmt,...)
+ if not fmt then
+ fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
@@ -6530,7 +6563,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 45072, stripped down to: 22629
+-- original size: 45188, stripped down to: 22734
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6945,9 +6978,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -7412,7 +7448,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 29567, stripped down to: 16483
+-- original size: 32649, stripped down to: 18257
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7649,92 +7685,160 @@ function tables.encapsulate(core,capsule,protect)
} )
end
end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(0,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(0,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(0)
+ fastserialize(v)
+ m=m+1 r[m]=f_indexed_table(0)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
+ for i=1,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
end
end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv=type(v)
if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
+ m=m+1 r[m]=f_hashed_string(k,v)
elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
+ m=m+1 r[m]=f_hashed_number(k,v)
elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
+ m=m+1 r[m]=f_hashed_table(k)
fastserialize(v)
elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
+ r[m]="},"
end
+ return r
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ m=m+1
+ r[m]="[0]='"
+ if type(v)=="table" then
+ fastserialize(v)
+ else
+ r[m]=format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v=t[i]
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
end
function table.deserialize(str)
if not str or str=="" then
@@ -7828,27 +7932,27 @@ function table.twowaymapper(t)
return t
end
local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str=formatters["%w[%q]={"]
local f_start_key_boo=formatters["%w[%l]={"]
local f_start_key_nop=formatters["%w{"]
local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not=formatters["%w[%Q]={},"]
local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str=formatters["%w%Q,"]
local f_val_boo=formatters["%w%l,"]
local f_val_not=formatters["%w{},"]
@@ -21589,7 +21693,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16070, stripped down to: 11353
+-- original size: 16099, stripped down to: 11379
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21876,7 +21980,7 @@ function caches.is_writable(filepath,filename)
local tmaname,tmcname=setluanames(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions={ compact=true }
+local saveoptions={ compact=true,accurate=not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname,tmcname=setluanames(filepath,filename)
data.cache_uuid=osuuid()
@@ -25385,363 +25489,147 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-package.loaded["util-lib"] = package.loaded["util-lib"] or true
+package.loaded["libs-ini"] = package.loaded["libs-ini"] or true
--- original size: 17659, stripped down to: 9560
+-- original size: 5822, stripped down to: 3629
-if not modules then modules={} end modules ['util-lib']={
+if not modules then modules={} end modules ['libs-ini']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ license="see context related readme files"
}
+local type,unpack=type,unpack
local type=type
-local next=next
-local pcall=pcall
-local gsub=string.gsub
-local find=string.find
-local sort=table.sort
-local pathpart=file.pathpart
local nameonly=file.nameonly
local joinfile=file.join
-local removesuffix=file.removesuffix
local addsuffix=file.addsuffix
-local findfile=resolvers.findfile
-local findfiles=resolvers.findfiles
-local expandpaths=resolvers.expandedpathlistfromvariable
local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
-local done=false
-local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
+local findfile=resolvers.findfile
+local expandpaths=resolvers.expandedpathlistfromvariable
+local report=logs.reporter("resolvers","libraries")
+local trace=false
+trackers.register("resolvers.lib",function(v) trace=v end)
+local function findlib(required)
+ local suffix=os.libsuffix or "so"
+ if not qualifiedpath(required) then
+ local list=directives.value("system.librarynames" )
+ local only=nameonly(required)
+ if type(list)=="table" then
+ list=list[only]
+ if type(list)~="table" then
+ list={ only }
end
- found_library=required
else
- if trace then
- report("qualified name %a not found",required)
- end
- end
- else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine=environment.ownmain or false
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ list={ only }
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
+ if trace then
+ report("using lookup list for library %a: % | t",only,list)
end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
+ for i=1,#list do
+ local name=list[i]
+ local found=findfile(name,"lib")
+ if not found then
+ found=findfile(addsuffix(name,suffix),"lib")
end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
+ if found then
if trace then
- report("checking %s: %a","with version",asked_library)
+ report("library %a resolved via %a path to %a",name,"tds lib",found)
end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
- end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
+ if expandpaths then
+ local list=expandpaths("PATH")
+ local base=addsuffix(only,suffix)
+ for i=1,#list do
+ local full=joinfile(list[i],base)
+ local found=isfile(full) and full
+ if found then
+ if trace then
+ report("library %a resolved via %a path to %a",name,"system",found)
+ end
+ return found
end
- found_library=attempt()
end
- else
- found_library=attempt()
end
- end
- if not found_library then
+ elseif isfile(addsuffix(required,suffix)) then
if trace then
- report("not found: %a",required)
+ report("library with qualified name %a %sfound",required,"")
end
- library=false
+ return required
else
if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ report("library with qualified name %a %sfound",required,"not ")
end
end
- if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
- end
- return library or nil
+ return false
end
-resolvers.locatelib=locate
-do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+local foundlibraries=table.setmetatableindex(function(t,k)
+ local v=findlib(k)
+ t[k]=v
+ return v
+end)
+function resolvers.findlib(required)
+ return foundlibraries[required]
+end
+local libraries={}
+resolvers.libraries=libraries
+local report=logs.reporter("optional")
+if optional then optional.loaded={} end
+function libraries.validoptional(name)
+ local thelib=optional and optional[name]
+ if not thelib then
+ elseif thelib.initialize then
+ return thelib
+ else
+ report("invalid optional library %a",libname)
+ end
+end
+function libraries.optionalloaded(name,libnames)
+ local thelib=optional and optional[name]
+ if not thelib then
+ report("no optional %a library found",name)
+ else
+ local thelib_initialize=thelib.initialize
+ if not thelib_initialize then
+ report("invalid optional library %a",name)
+ else
+ if type(libnames)=="string" then
+ libnames={ libnames }
+ end
+ if type(libnames)=="table" then
+ for i=1,#libnames do
+ local libname=libnames[i]
+ local filename=foundlibraries[libname]
+ if filename then
+ libnames[i]=filename
+ else
+ report("unable to locate library %a",libname)
+ return
+ end
+ end
+ local initialized=thelib_initialize(unpack(libnames))
+ if initialized then
+ report("using library '% + t'",libnames)
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ report("unable to initialize library '% + t'",libnames)
end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
+ return initialized
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
- end
- return { required }
- end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
- end
+ local ffiload=ffi.load
function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
- end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
- end
- end
-end
-do
- local isfile=lfs.isfile
- local report=logs.reporter("resolvers","lib")
- local trace=false
- trackers.register("resolvers.lib",function(v) trace=v end)
- local function action(filename)
- return isfile(filename) and filename or false
- end
- function resolvers.findlib(required)
- local list=directives.value("system.librarynames" )
- local only=nameonly(required)
- if type(list)=="table" then
- list=list[only]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",only,list)
- end
- else
- list={ only }
- end
+ local full=name and foundlibraries[name]
+ if full then
+ return ffiload(full)
else
- list={ only }
- end
- for i=1,#list do
- local name=list[i]
- local found=locate(name,false,trace,report,action)
- if found then
- return found
- end
- end
- local getpaths=resolvers.expandedpathlistfromvariable
- if getpaths then
- local list=getpaths("PATH")
- local base=addsuffix(only,os.libsuffix)
- for i=1,#list do
- local full=joinfile(list[i],base)
- local found=locate(full,false,trace,report,action)
- if found then
- return found
- end
- end
+ return ffiload(name)
end
end
end
@@ -26187,10 +26075,10 @@ end
end -- of closure
--- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.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-sha.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 util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1047142
--- stripped bytes : 416876
+-- original bytes : 1038128
+-- stripped bytes : 410736
-- end library merge
@@ -26304,7 +26192,7 @@ local ownlibs = { -- order can be made better
'data-tmf.lua',
'data-lst.lua',
- 'util-lib.lua', -- swiglib
+ 'libs-ini.lua',
'luat-sta.lua',
'luat-fmt.lua',
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 9e0025e0f..8570ac7a9 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{2020.01.26 18:34}
+\newcontextversion{2020.02.11 16:36}
%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 aa7c02cf4..e02bc12dd 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{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/char-emj.lua b/tex/context/base/mkiv/char-emj.lua
index b00e9ebf8..e6c059174 100644
--- a/tex/context/base/mkiv/char-emj.lua
+++ b/tex/context/base/mkiv/char-emj.lua
@@ -16,6 +16,7 @@ return {
["a button (blood type)"]={ 0x1F170, 0xFE0F },
["ab button (blood type)"]={ 0x1F18E },
["abacus"]={ 0x1F9EE },
+ ["accordion"]={ 0x1FA97 },
["adhesive bandage"]={ 0x1FA79 },
["admission tickets"]={ 0x1F39F, 0xFE0F },
["aerial tramway"]={ 0x1F6A1 },
@@ -29,6 +30,7 @@ return {
["ambulance"]={ 0x1F691 },
["american football"]={ 0x1F3C8 },
["amphora"]={ 0x1F3FA },
+ ["anatomical heart"]={ 0x1FAC0 },
["anchor"]={ 0x2693 },
["anger symbol"]={ 0x1F4A2 },
["angry face"]={ 0x1F620 },
@@ -40,8 +42,20 @@ return {
["aquarius"]={ 0x2652 },
["aries"]={ 0x2648 },
["articulated lorry"]={ 0x1F69B },
+ ["artist"]={ 0x1F9D1, 0x200D, 0x1F3A8 },
["artist palette"]={ 0x1F3A8 },
+ ["artist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3A8 },
+ ["artist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3A8 },
+ ["artist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3A8 },
+ ["artist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3A8 },
+ ["artist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3A8 },
["astonished face"]={ 0x1F632 },
+ ["astronaut"]={ 0x1F9D1, 0x200D, 0x1F680 },
+ ["astronaut: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F680 },
+ ["astronaut: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F680 },
+ ["astronaut: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F680 },
+ ["astronaut: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F680 },
+ ["astronaut: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F680 },
["atm sign"]={ 0x1F3E7 },
["atom symbol"]={ 0x269B, 0xFE0F },
["auto rickshaw"]={ 0x1F6FA },
@@ -115,9 +129,12 @@ return {
["beaming face with smiling eyes"]={ 0x1F601 },
["bear"]={ 0x1F43B },
["beating heart"]={ 0x1F493 },
+ ["beaver"]={ 0x1F9AB },
["bed"]={ 0x1F6CF, 0xFE0F },
["beer mug"]={ 0x1F37A },
+ ["beetle"]={ 0x1FAB2 },
["bell"]={ 0x1F514 },
+ ["bell pepper"]={ 0x1FAD1 },
["bell with slash"]={ 0x1F515 },
["bellhop bell"]={ 0x1F6CE, 0xFE0F },
["bento box"]={ 0x1F371 },
@@ -128,6 +145,8 @@ return {
["biohazard"]={ 0x2623, 0xFE0F },
["bird"]={ 0x1F426 },
["birthday cake"]={ 0x1F382 },
+ ["bison"]={ 0x1F9AC },
+ ["black cat"]={ 0x1F408, 0x200D, 0x2B1B },
["black circle"]={ 0x26AB },
["black flag"]={ 0x1F3F4 },
["black heart"]={ 0x1F5A4 },
@@ -143,12 +162,14 @@ return {
["blue circle"]={ 0x1F535 },
["blue heart"]={ 0x1F499 },
["blue square"]={ 0x1F7E6 },
+ ["blueberries"]={ 0x1FAD0 },
["boar"]={ 0x1F417 },
["bomb"]={ 0x1F4A3 },
["bone"]={ 0x1F9B4 },
["bookmark"]={ 0x1F516 },
["bookmark tabs"]={ 0x1F4D1 },
["books"]={ 0x1F4DA },
+ ["boomerang"]={ 0x1FA83 },
["bottle with popping cork"]={ 0x1F37E },
["bouquet"]={ 0x1F490 },
["bow and arrow"]={ 0x1F3F9 },
@@ -170,14 +191,9 @@ return {
["breast-feeding: medium-dark skin tone"]={ 0x1F931, 0x1F3FE },
["breast-feeding: medium-light skin tone"]={ 0x1F931, 0x1F3FC },
["brick"]={ 0x1F9F1 },
- ["bride with veil"]={ 0x1F470 },
- ["bride with veil: dark skin tone"]={ 0x1F470, 0x1F3FF },
- ["bride with veil: light skin tone"]={ 0x1F470, 0x1F3FB },
- ["bride with veil: medium skin tone"]={ 0x1F470, 0x1F3FD },
- ["bride with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE },
- ["bride with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC },
["bridge at night"]={ 0x1F309 },
["briefcase"]={ 0x1F4BC },
+ ["briefs"]={ 0x1FA72 },
["bright button"]={ 0x1F506 },
["broccoli"]={ 0x1F966 },
["broken heart"]={ 0x1F494 },
@@ -185,6 +201,8 @@ return {
["brown circle"]={ 0x1F7E4 },
["brown heart"]={ 0x1F90E },
["brown square"]={ 0x1F7EB },
+ ["bubble tea"]={ 0x1F9CB },
+ ["bucket"]={ 0x1FAA3 },
["bug"]={ 0x1F41B },
["building construction"]={ 0x1F3D7, 0xFE0F },
["bullet train"]={ 0x1F685 },
@@ -218,6 +236,7 @@ return {
["card index dividers"]={ 0x1F5C2, 0xFE0F },
["carousel horse"]={ 0x1F3A0 },
["carp streamer"]={ 0x1F38F },
+ ["carpentry saw"]={ 0x1FA9A },
["carrot"]={ 0x1F955 },
["castle"]={ 0x1F3F0 },
["cat"]={ 0x1F408 },
@@ -284,9 +303,11 @@ return {
["club suit"]={ 0x2663, 0xFE0F },
["clutch bag"]={ 0x1F45D },
["coat"]={ 0x1F9E5 },
+ ["cockroach"]={ 0x1FAB3 },
["cocktail glass"]={ 0x1F378 },
["coconut"]={ 0x1F965 },
["coffin"]={ 0x26B0, 0xFE0F },
+ ["coin"]={ 0x1FA99 },
["cold face"]={ 0x1F976 },
["collision"]={ 0x1F4A5 },
["comet"]={ 0x2604, 0xFE0F },
@@ -305,6 +326,12 @@ return {
["construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC },
["control knobs"]={ 0x1F39B, 0xFE0F },
["convenience store"]={ 0x1F3EA },
+ ["cook"]={ 0x1F9D1, 0x200D, 0x1F373 },
+ ["cook: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F373 },
+ ["cook: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F373 },
+ ["cook: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F373 },
+ ["cook: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F373 },
+ ["cook: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F373 },
["cooked rice"]={ 0x1F35A },
["cookie"]={ 0x1F36A },
["cooking"]={ 0x1F373 },
@@ -392,12 +419,14 @@ return {
["dim button"]={ 0x1F505 },
["direct hit"]={ 0x1F3AF },
["disappointed face"]={ 0x1F61E },
+ ["disguised face"]={ 0x1F978 },
+ ["divide"]={ 0x2797 },
["diving mask"]={ 0x1F93F },
- ["division sign"]={ 0x2797 },
["diya lamp"]={ 0x1FA94 },
["dizzy"]={ 0x1F4AB },
["dizzy face"]={ 0x1F635 },
["dna"]={ 0x1F9EC },
+ ["dodo"]={ 0x1F9A4 },
["dog"]={ 0x1F415 },
["dog face"]={ 0x1F436 },
["dollar banknote"]={ 0x1F4B5 },
@@ -447,6 +476,7 @@ return {
["eject button"]={ 0x23CF, 0xFE0F },
["electric plug"]={ 0x1F50C },
["elephant"]={ 0x1F418 },
+ ["elevator"]={ 0x1F6D7 },
["eleven o’clock"]={ 0x1F55A },
["eleven-thirty"]={ 0x1F566 },
["elf"]={ 0x1F9DD },
@@ -486,6 +516,12 @@ return {
["face with tongue"]={ 0x1F61B },
["face without mouth"]={ 0x1F636 },
["factory"]={ 0x1F3ED },
+ ["factory worker"]={ 0x1F9D1, 0x200D, 0x1F3ED },
+ ["factory worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3ED },
+ ["factory worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3ED },
+ ["factory worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3ED },
+ ["factory worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3ED },
+ ["factory worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3ED },
["fairy"]={ 0x1F9DA },
["fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF },
["fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB },
@@ -520,12 +556,19 @@ return {
["family: woman, woman, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467 },
["family: woman, woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 },
["family: woman, woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["farmer"]={ 0x1F9D1, 0x200D, 0x1F33E },
+ ["farmer: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F33E },
+ ["farmer: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F33E },
+ ["farmer: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F33E },
+ ["farmer: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F33E },
+ ["farmer: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F33E },
["fast down button"]={ 0x23EC },
["fast reverse button"]={ 0x23EA },
["fast up button"]={ 0x23EB },
["fast-forward button"]={ 0x23E9 },
["fax machine"]={ 0x1F4E0 },
["fearful face"]={ 0x1F628 },
+ ["feather"]={ 0x1FAB6 },
["female sign"]={ 0x2640, 0xFE0F },
["ferris wheel"]={ 0x1F3A1 },
["ferry"]={ 0x26F4, 0xFE0F },
@@ -538,6 +581,12 @@ return {
["fire engine"]={ 0x1F692 },
["fire extinguisher"]={ 0x1F9EF },
["firecracker"]={ 0x1F9E8 },
+ ["firefighter"]={ 0x1F9D1, 0x200D, 0x1F692 },
+ ["firefighter: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F692 },
+ ["firefighter: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F692 },
+ ["firefighter: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F692 },
+ ["firefighter: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F692 },
+ ["firefighter: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F692 },
["fireworks"]={ 0x1F386 },
["first quarter moon"]={ 0x1F313 },
["first quarter moon face"]={ 0x1F31B },
@@ -684,7 +733,6 @@ return {
["flag: lithuania"]={ 0x1F1F1, 0x1F1F9 },
["flag: luxembourg"]={ 0x1F1F1, 0x1F1FA },
["flag: macao sar china"]={ 0x1F1F2, 0x1F1F4 },
- ["flag: macedonia"]={ 0x1F1F2, 0x1F1F0 },
["flag: madagascar"]={ 0x1F1F2, 0x1F1EC },
["flag: malawi"]={ 0x1F1F2, 0x1F1FC },
["flag: malaysia"]={ 0x1F1F2, 0x1F1FE },
@@ -718,6 +766,7 @@ return {
["flag: niue"]={ 0x1F1F3, 0x1F1FA },
["flag: norfolk island"]={ 0x1F1F3, 0x1F1EB },
["flag: north korea"]={ 0x1F1F0, 0x1F1F5 },
+ ["flag: north macedonia"]={ 0x1F1F2, 0x1F1F0 },
["flag: northern mariana islands"]={ 0x1F1F2, 0x1F1F5 },
["flag: norway"]={ 0x1F1F3, 0x1F1F4 },
["flag: oman"]={ 0x1F1F4, 0x1F1F2 },
@@ -811,6 +860,7 @@ return {
["flamingo"]={ 0x1F9A9 },
["flashlight"]={ 0x1F526 },
["flat shoe"]={ 0x1F97F },
+ ["flatbread"]={ 0x1FAD3 },
["fleur-de-lis"]={ 0x269C, 0xFE0F },
["flexed biceps"]={ 0x1F4AA },
["flexed biceps: dark skin tone"]={ 0x1F4AA, 0x1F3FF },
@@ -821,6 +871,7 @@ return {
["floppy disk"]={ 0x1F4BE },
["flower playing cards"]={ 0x1F3B4 },
["flushed face"]={ 0x1F633 },
+ ["fly"]={ 0x1FAB0 },
["flying disc"]={ 0x1F94F },
["flying saucer"]={ 0x1F6F8 },
["fog"]={ 0x1F32B, 0xFE0F },
@@ -831,6 +882,7 @@ return {
["folded hands: medium skin tone"]={ 0x1F64F, 0x1F3FD },
["folded hands: medium-dark skin tone"]={ 0x1F64F, 0x1F3FE },
["folded hands: medium-light skin tone"]={ 0x1F64F, 0x1F3FC },
+ ["fondue"]={ 0x1FAD5 },
["foot"]={ 0x1F9B6 },
["foot: dark skin tone"]={ 0x1F9B6, 0x1F3FF },
["foot: light skin tone"]={ 0x1F9B6, 0x1F3FB },
@@ -926,6 +978,13 @@ return {
["handshake"]={ 0x1F91D },
["hatching chick"]={ 0x1F423 },
["headphone"]={ 0x1F3A7 },
+ ["headstone"]={ 0x1FAA6 },
+ ["health worker"]={ 0x1F9D1, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2695, 0xFE0F },
["hear-no-evil monkey"]={ 0x1F649 },
["heart decoration"]={ 0x1F49F },
["heart exclamation"]={ 0x2763, 0xFE0F },
@@ -947,6 +1006,7 @@ return {
["hollow red circle"]={ 0x2B55 },
["honey pot"]={ 0x1F36F },
["honeybee"]={ 0x1F41D },
+ ["hook"]={ 0x1FA9D },
["horizontal traffic light"]={ 0x1F6A5 },
["horse"]={ 0x1F40E },
["horse face"]={ 0x1F434 },
@@ -971,8 +1031,9 @@ return {
["hugging face"]={ 0x1F917 },
["hundred points"]={ 0x1F4AF },
["hushed face"]={ 0x1F62F },
+ ["hut"]={ 0x1F6D6 },
+ ["ice"]={ 0x1F9CA },
["ice cream"]={ 0x1F368 },
- ["ice cube"]={ 0x1F9CA },
["ice hockey"]={ 0x1F3D2 },
["ice skate"]={ 0x26F8, 0xFE0F },
["id button"]={ 0x1F194 },
@@ -1016,6 +1077,12 @@ return {
["jeans"]={ 0x1F456 },
["joker"]={ 0x1F0CF },
["joystick"]={ 0x1F579, 0xFE0F },
+ ["judge"]={ 0x1F9D1, 0x200D, 0x2696, 0xFE0F },
+ ["judge: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
+ ["judge: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2696, 0xFE0F },
["kaaba"]={ 0x1F54B },
["kangaroo"]={ 0x1F998 },
["key"]={ 0x1F511 },
@@ -1047,12 +1114,14 @@ return {
["kitchen knife"]={ 0x1F52A },
["kite"]={ 0x1FA81 },
["kiwi fruit"]={ 0x1F95D },
+ ["knot"]={ 0x1FAA2 },
["koala"]={ 0x1F428 },
["lab coat"]={ 0x1F97C },
["label"]={ 0x1F3F7, 0xFE0F },
["lacrosse"]={ 0x1F94D },
+ ["ladder"]={ 0x1FA9C },
["lady beetle"]={ 0x1F41E },
- ["laptop computer"]={ 0x1F4BB },
+ ["laptop"]={ 0x1F4BB },
["large blue diamond"]={ 0x1F537 },
["large orange diamond"]={ 0x1F536 },
["last quarter moon"]={ 0x1F317 },
@@ -1099,6 +1168,7 @@ return {
["locked with pen"]={ 0x1F50F },
["locomotive"]={ 0x1F682 },
["lollipop"]={ 0x1F36D },
+ ["long drum"]={ 0x1FA98 },
["lotion bottle"]={ 0x1F9F4 },
["loudly crying face"]={ 0x1F62D },
["loudspeaker"]={ 0x1F4E2 },
@@ -1111,6 +1181,7 @@ return {
["love-you gesture: medium-dark skin tone"]={ 0x1F91F, 0x1F3FE },
["love-you gesture: medium-light skin tone"]={ 0x1F91F, 0x1F3FC },
["luggage"]={ 0x1F9F3 },
+ ["lungs"]={ 0x1FAC1 },
["lying face"]={ 0x1F925 },
["mage"]={ 0x1F9D9 },
["mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF },
@@ -1118,11 +1189,13 @@ return {
["mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD },
["mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE },
["mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC },
+ ["magic wand"]={ 0x1FA84 },
["magnet"]={ 0x1F9F2 },
["magnifying glass tilted left"]={ 0x1F50D },
["magnifying glass tilted right"]={ 0x1F50E },
["mahjong red dragon"]={ 0x1F004 },
["male sign"]={ 0x2642, 0xFE0F },
+ ["mammoth"]={ 0x1F9A3 },
["man"]={ 0x1F468 },
["man artist"]={ 0x1F468, 0x200D, 0x1F3A8 },
["man artist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A8 },
@@ -1220,6 +1293,12 @@ return {
["man farmer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F33E },
["man farmer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F33E },
["man farmer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F33E },
+ ["man feeding baby"]={ 0x1F468, 0x200D, 0x1F37C },
+ ["man feeding baby: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F37C },
+ ["man feeding baby: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F37C },
+ ["man feeding baby: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F37C },
+ ["man feeding baby: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F37C },
+ ["man feeding baby: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F37C },
["man firefighter"]={ 0x1F468, 0x200D, 0x1F692 },
["man firefighter: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F692 },
["man firefighter: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F692 },
@@ -1299,18 +1378,12 @@ return {
["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
- ["man in suit levitating"]={ 0x1F574, 0xFE0F },
- ["man in suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF },
- ["man in suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB },
- ["man in suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD },
- ["man in suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE },
- ["man in suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC },
- ["man in tuxedo"]={ 0x1F935 },
- ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF },
- ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB },
- ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD },
- ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE },
- ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC },
+ ["man in tuxedo"]={ 0x1F935, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
["man judge"]={ 0x1F468, 0x200D, 0x2696, 0xFE0F },
["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
@@ -1497,18 +1570,18 @@ return {
["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
- ["man with chinese cap"]={ 0x1F472 },
- ["man with chinese cap: dark skin tone"]={ 0x1F472, 0x1F3FF },
- ["man with chinese cap: light skin tone"]={ 0x1F472, 0x1F3FB },
- ["man with chinese cap: medium skin tone"]={ 0x1F472, 0x1F3FD },
- ["man with chinese cap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE },
- ["man with chinese cap: medium-light skin tone"]={ 0x1F472, 0x1F3FC },
- ["man with probing cane"]={ 0x1F468, 0x200D, 0x1F9AF },
- ["man with probing cane: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9AF },
- ["man with probing cane: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9AF },
- ["man with probing cane: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9AF },
- ["man with probing cane: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9AF },
- ["man with probing cane: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["man with veil"]={ 0x1F470, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: dark skin tone"]={ 0x1F470, 0x1F3FF, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: light skin tone"]={ 0x1F470, 0x1F3FB, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium skin tone"]={ 0x1F470, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
+ ["man with white cane"]={ 0x1F468, 0x200D, 0x1F9AF },
+ ["man with white cane: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["man with white cane: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["man with white cane: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["man with white cane: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["man with white cane: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9AF },
["man zombie"]={ 0x1F9DF, 0x200D, 0x2642, 0xFE0F },
["man: bald"]={ 0x1F468, 0x200D, 0x1F9B2 },
["man: beard"]={ 0x1F9D4 },
@@ -1560,6 +1633,12 @@ return {
["martial arts uniform"]={ 0x1F94B },
["mate"]={ 0x1F9C9 },
["meat on bone"]={ 0x1F356 },
+ ["mechanic"]={ 0x1F9D1, 0x200D, 0x1F527 },
+ ["mechanic: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F527 },
+ ["mechanic: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F527 },
+ ["mechanic: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F527 },
+ ["mechanic: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F527 },
+ ["mechanic: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F527 },
["mechanical arm"]={ 0x1F9BE },
["mechanical leg"]={ 0x1F9BF },
["medical symbol"]={ 0x2695, 0xFE0F },
@@ -1573,15 +1652,25 @@ return {
["men holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men holding hands: dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: light skin tone"]={ 0x1F46C, 0x1F3FB },
+ ["men holding hands: light skin tone, dark skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
+ ["men holding hands: light skin tone, medium skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
+ ["men holding hands: light skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
+ ["men holding hands: light skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium skin tone"]={ 0x1F46C, 0x1F3FD },
+ ["men holding hands: medium skin tone, dark skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium skin tone, light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
+ ["men holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men holding hands: medium skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium-dark skin tone"]={ 0x1F46C, 0x1F3FE },
+ ["men holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium-dark skin tone, light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
["men holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
["men holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium-light skin tone"]={ 0x1F46C, 0x1F3FC },
+ ["men holding hands: medium-light skin tone, dark skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium-light skin tone, light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
+ ["men holding hands: medium-light skin tone, medium skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
+ ["men holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men with bunny ears"]={ 0x1F46F, 0x200D, 0x2642, 0xFE0F },
["men wrestling"]={ 0x1F93C, 0x200D, 0x2642, 0xFE0F },
["menorah"]={ 0x1F54E },
@@ -1614,10 +1703,12 @@ return {
["middle finger: medium skin tone"]={ 0x1F595, 0x1F3FD },
["middle finger: medium-dark skin tone"]={ 0x1F595, 0x1F3FE },
["middle finger: medium-light skin tone"]={ 0x1F595, 0x1F3FC },
+ ["military helmet"]={ 0x1FA96 },
["military medal"]={ 0x1F396, 0xFE0F },
["milky way"]={ 0x1F30C },
["minibus"]={ 0x1F690 },
- ["minus sign"]={ 0x2796 },
+ ["minus"]={ 0x2796 },
+ ["mirror"]={ 0x1FA9E },
["moai"]={ 0x1F5FF },
["mobile phone"]={ 0x1F4F1 },
["mobile phone off"]={ 0x1F4F4 },
@@ -1643,6 +1734,7 @@ return {
["mountain railway"]={ 0x1F69E },
["mouse"]={ 0x1F401 },
["mouse face"]={ 0x1F42D },
+ ["mouse trap"]={ 0x1FAA4 },
["mouth"]={ 0x1F444 },
["movie camera"]={ 0x1F3A5 },
["mrs. claus"]={ 0x1F936 },
@@ -1651,13 +1743,19 @@ return {
["mrs. claus: medium skin tone"]={ 0x1F936, 0x1F3FD },
["mrs. claus: medium-dark skin tone"]={ 0x1F936, 0x1F3FE },
["mrs. claus: medium-light skin tone"]={ 0x1F936, 0x1F3FC },
- ["multiplication sign"]={ 0x2716, 0xFE0F },
+ ["multiply"]={ 0x2716, 0xFE0F },
["mushroom"]={ 0x1F344 },
["musical keyboard"]={ 0x1F3B9 },
["musical note"]={ 0x1F3B5 },
["musical notes"]={ 0x1F3B6 },
["musical score"]={ 0x1F3BC },
["muted speaker"]={ 0x1F507 },
+ ["mx claus"]={ 0x1F9D1, 0x200D, 0x1F384 },
+ ["mx claus: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F384 },
+ ["mx claus: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F384 },
+ ["mx claus: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F384 },
+ ["mx claus: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F384 },
+ ["mx claus: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F384 },
["nail polish"]={ 0x1F485 },
["nail polish: dark skin tone"]={ 0x1F485, 0x1F3FF },
["nail polish: light skin tone"]={ 0x1F485, 0x1F3FB },
@@ -1670,6 +1768,7 @@ return {
["nazar amulet"]={ 0x1F9FF },
["necktie"]={ 0x1F454 },
["nerd face"]={ 0x1F913 },
+ ["nesting dolls"]={ 0x1FA86 },
["neutral face"]={ 0x1F610 },
["new button"]={ 0x1F195 },
["new moon"]={ 0x1F311 },
@@ -1680,6 +1779,12 @@ return {
["night with stars"]={ 0x1F303 },
["nine o’clock"]={ 0x1F558 },
["nine-thirty"]={ 0x1F564 },
+ ["ninja"]={ 0x1F977 },
+ ["ninja: dark skin tone"]={ 0x1F977, 0x1F3FF },
+ ["ninja: light skin tone"]={ 0x1F977, 0x1F3FB },
+ ["ninja: medium skin tone"]={ 0x1F977, 0x1F3FD },
+ ["ninja: medium-dark skin tone"]={ 0x1F977, 0x1F3FE },
+ ["ninja: medium-light skin tone"]={ 0x1F977, 0x1F3FC },
["no bicycles"]={ 0x1F6B3 },
["no entry"]={ 0x26D4 },
["no littering"]={ 0x1F6AF },
@@ -1701,6 +1806,12 @@ return {
["octopus"]={ 0x1F419 },
["oden"]={ 0x1F362 },
["office building"]={ 0x1F3E2 },
+ ["office worker"]={ 0x1F9D1, 0x200D, 0x1F4BC },
+ ["office worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F4BC },
+ ["office worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F4BC },
+ ["office worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F4BC },
+ ["office worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F4BC },
+ ["office worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F4BC },
["ogre"]={ 0x1F479 },
["oil drum"]={ 0x1F6E2, 0xFE0F },
["ok button"]={ 0x1F197 },
@@ -1729,6 +1840,7 @@ return {
["older person: medium skin tone"]={ 0x1F9D3, 0x1F3FD },
["older person: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE },
["older person: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC },
+ ["olive"]={ 0x1FAD2 },
["om"]={ 0x1F549, 0xFE0F },
["on! arrow"]={ 0x1F51B },
["oncoming automobile"]={ 0x1F698 },
@@ -1809,15 +1921,26 @@ return {
["people holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
["people holding hands: dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: light skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
+ ["people holding hands: light skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: light skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people holding hands: light skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: medium skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
["people holding hands: medium skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium-dark skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
["people holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
["people holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
+ ["people holding hands: medium-light skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium-light skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: medium-light skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people hugging"]={ 0x1FAC2 },
["people with bunny ears"]={ 0x1F46F },
["people wrestling"]={ 0x1F93C },
["performing arts"]={ 0x1F3AD },
@@ -1859,6 +1982,12 @@ return {
["person facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD },
["person facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE },
["person facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC },
+ ["person feeding baby"]={ 0x1F9D1, 0x200D, 0x1F37C },
+ ["person feeding baby: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F37C },
+ ["person feeding baby: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F37C },
+ ["person feeding baby: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F37C },
+ ["person feeding baby: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F37C },
+ ["person feeding baby: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F37C },
["person fencing"]={ 0x1F93A },
["person frowning"]={ 0x1F64D },
["person frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF },
@@ -1908,12 +2037,36 @@ return {
["person in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD },
["person in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE },
["person in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC },
+ ["person in manual wheelchair"]={ 0x1F9D1, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9BD },
+ ["person in motorized wheelchair"]={ 0x1F9D1, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9BC },
["person in steamy room"]={ 0x1F9D6 },
["person in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF },
["person in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB },
["person in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD },
["person in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE },
["person in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC },
+ ["person in suit levitating"]={ 0x1F574, 0xFE0F },
+ ["person in suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF },
+ ["person in suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB },
+ ["person in suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD },
+ ["person in suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE },
+ ["person in suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC },
+ ["person in tuxedo"]={ 0x1F935 },
+ ["person in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF },
+ ["person in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB },
+ ["person in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD },
+ ["person in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE },
+ ["person in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC },
["person juggling"]={ 0x1F939 },
["person juggling: dark skin tone"]={ 0x1F939, 0x1F3FF },
["person juggling: light skin tone"]={ 0x1F939, 0x1F3FB },
@@ -2022,25 +2175,80 @@ return {
["person wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD },
["person wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE },
["person wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC },
+ ["person with skullcap"]={ 0x1F472 },
+ ["person with skullcap: dark skin tone"]={ 0x1F472, 0x1F3FF },
+ ["person with skullcap: light skin tone"]={ 0x1F472, 0x1F3FB },
+ ["person with skullcap: medium skin tone"]={ 0x1F472, 0x1F3FD },
+ ["person with skullcap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE },
+ ["person with skullcap: medium-light skin tone"]={ 0x1F472, 0x1F3FC },
+ ["person with veil"]={ 0x1F470 },
+ ["person with veil: dark skin tone"]={ 0x1F470, 0x1F3FF },
+ ["person with veil: light skin tone"]={ 0x1F470, 0x1F3FB },
+ ["person with veil: medium skin tone"]={ 0x1F470, 0x1F3FD },
+ ["person with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE },
+ ["person with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC },
+ ["person with white cane"]={ 0x1F9D1, 0x200D, 0x1F9AF },
+ ["person with white cane: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["person with white cane: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["person with white cane: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["person with white cane: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["person with white cane: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["person: bald"]={ 0x1F9D1, 0x200D, 0x1F9B2 },
["person: blond hair"]={ 0x1F471 },
+ ["person: curly hair"]={ 0x1F9D1, 0x200D, 0x1F9B1 },
["person: dark skin tone"]={ 0x1F9D1, 0x1F3FF },
+ ["person: dark skin tone, bald"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B2 },
["person: dark skin tone, blond hair"]={ 0x1F471, 0x1F3FF },
+ ["person: dark skin tone, curly hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B1 },
+ ["person: dark skin tone, red hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B0 },
+ ["person: dark skin tone, white hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B3 },
["person: light skin tone"]={ 0x1F9D1, 0x1F3FB },
+ ["person: light skin tone, bald"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B2 },
["person: light skin tone, blond hair"]={ 0x1F471, 0x1F3FB },
+ ["person: light skin tone, curly hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B1 },
+ ["person: light skin tone, red hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B0 },
+ ["person: light skin tone, white hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B3 },
["person: medium skin tone"]={ 0x1F9D1, 0x1F3FD },
+ ["person: medium skin tone, bald"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B2 },
["person: medium skin tone, blond hair"]={ 0x1F471, 0x1F3FD },
+ ["person: medium skin tone, curly hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B1 },
+ ["person: medium skin tone, red hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B0 },
+ ["person: medium skin tone, white hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B3 },
["person: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE },
+ ["person: medium-dark skin tone, bald"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B2 },
["person: medium-dark skin tone, blond hair"]={ 0x1F471, 0x1F3FE },
+ ["person: medium-dark skin tone, curly hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B1 },
+ ["person: medium-dark skin tone, red hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B0 },
+ ["person: medium-dark skin tone, white hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B3 },
["person: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC },
+ ["person: medium-light skin tone, bald"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B2 },
["person: medium-light skin tone, blond hair"]={ 0x1F471, 0x1F3FC },
+ ["person: medium-light skin tone, curly hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B1 },
+ ["person: medium-light skin tone, red hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B0 },
+ ["person: medium-light skin tone, white hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B3 },
+ ["person: red hair"]={ 0x1F9D1, 0x200D, 0x1F9B0 },
+ ["person: white hair"]={ 0x1F9D1, 0x200D, 0x1F9B3 },
["petri dish"]={ 0x1F9EB },
["pick"]={ 0x26CF, 0xFE0F },
+ ["pickup truck"]={ 0x1F6FB },
["pie"]={ 0x1F967 },
["pig"]={ 0x1F416 },
["pig face"]={ 0x1F437 },
["pig nose"]={ 0x1F43D },
["pile of poo"]={ 0x1F4A9 },
["pill"]={ 0x1F48A },
+ ["pilot"]={ 0x1F9D1, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2708, 0xFE0F },
+ ["pinched fingers"]={ 0x1F90C },
+ ["pinched fingers: dark skin tone"]={ 0x1F90C, 0x1F3FF },
+ ["pinched fingers: light skin tone"]={ 0x1F90C, 0x1F3FB },
+ ["pinched fingers: medium skin tone"]={ 0x1F90C, 0x1F3FD },
+ ["pinched fingers: medium-dark skin tone"]={ 0x1F90C, 0x1F3FE },
+ ["pinched fingers: medium-light skin tone"]={ 0x1F90C, 0x1F3FC },
["pinching hand"]={ 0x1F90F },
["pinching hand: dark skin tone"]={ 0x1F90F, 0x1F3FF },
["pinching hand: light skin tone"]={ 0x1F90F, 0x1F3FB },
@@ -2054,11 +2262,15 @@ return {
["pisces"]={ 0x2653 },
["pistol"]={ 0x1F52B },
["pizza"]={ 0x1F355 },
+ ["piñata"]={ 0x1FA85 },
+ ["placard"]={ 0x1FAA7 },
["place of worship"]={ 0x1F6D0 },
["play button"]={ 0x25B6, 0xFE0F },
["play or pause button"]={ 0x23EF, 0xFE0F },
["pleading face"]={ 0x1F97A },
- ["plus sign"]={ 0x2795 },
+ ["plunger"]={ 0x1FAA0 },
+ ["plus"]={ 0x2795 },
+ ["polar bear"]={ 0x1F43B, 0x200D, 0x2744, 0xFE0F },
["police car"]={ 0x1F693 },
["police car light"]={ 0x1F6A8 },
["police officer"]={ 0x1F46E },
@@ -2076,6 +2288,7 @@ return {
["pot of food"]={ 0x1F372 },
["potable water"]={ 0x1F6B0 },
["potato"]={ 0x1F954 },
+ ["potted plant"]={ 0x1FAB4 },
["poultry leg"]={ 0x1F357 },
["pound banknote"]={ 0x1F4B7 },
["pouting cat"]={ 0x1F63E },
@@ -2101,7 +2314,6 @@ return {
["princess: medium-dark skin tone"]={ 0x1F478, 0x1F3FE },
["princess: medium-light skin tone"]={ 0x1F478, 0x1F3FC },
["printer"]={ 0x1F5A8, 0xFE0F },
- ["probing cane"]={ 0x1F9AF },
["prohibited"]={ 0x1F6AB },
["purple circle"]={ 0x1F7E3 },
["purple heart"]={ 0x1F49C },
@@ -2187,10 +2399,12 @@ return {
["ringed planet"]={ 0x1FA90 },
["roasted sweet potato"]={ 0x1F360 },
["robot"]={ 0x1F916 },
+ ["rock"]={ 0x1FAA8 },
["rocket"]={ 0x1F680 },
["roll of paper"]={ 0x1F9FB },
["rolled-up newspaper"]={ 0x1F5DE, 0xFE0F },
["roller coaster"]={ 0x1F3A2 },
+ ["roller skate"]={ 0x1F6FC },
["rolling on the floor laughing"]={ 0x1F923 },
["rooster"]={ 0x1F413 },
["rose"]={ 0x1F339 },
@@ -2220,10 +2434,18 @@ return {
["saxophone"]={ 0x1F3B7 },
["scarf"]={ 0x1F9E3 },
["school"]={ 0x1F3EB },
+ ["scientist"]={ 0x1F9D1, 0x200D, 0x1F52C },
+ ["scientist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F52C },
+ ["scientist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F52C },
+ ["scientist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F52C },
+ ["scientist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F52C },
+ ["scientist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F52C },
["scissors"]={ 0x2702, 0xFE0F },
["scorpio"]={ 0x264F },
["scorpion"]={ 0x1F982 },
+ ["screwdriver"]={ 0x1FA9B },
["scroll"]={ 0x1F4DC },
+ ["seal"]={ 0x1F9AD },
["seat"]={ 0x1F4BA },
["see-no-evil monkey"]={ 0x1F648 },
["seedling"]={ 0x1F331 },
@@ -2236,6 +2458,7 @@ return {
["service dog"]={ 0x1F415, 0x200D, 0x1F9BA },
["seven o’clock"]={ 0x1F556 },
["seven-thirty"]={ 0x1F562 },
+ ["sewing needle"]={ 0x1FAA1 },
["shallow pan of food"]={ 0x1F958 },
["shamrock"]={ 0x2618, 0xFE0F },
["shark"]={ 0x1F988 },
@@ -2259,6 +2482,12 @@ return {
["sign of the horns: medium skin tone"]={ 0x1F918, 0x1F3FD },
["sign of the horns: medium-dark skin tone"]={ 0x1F918, 0x1F3FE },
["sign of the horns: medium-light skin tone"]={ 0x1F918, 0x1F3FC },
+ ["singer"]={ 0x1F9D1, 0x200D, 0x1F3A4 },
+ ["singer: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3A4 },
+ ["singer: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3A4 },
+ ["singer: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3A4 },
+ ["singer: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3A4 },
+ ["singer: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3A4 },
["six o’clock"]={ 0x1F555 },
["six-thirty"]={ 0x1F561 },
["skateboard"]={ 0x1F6F9 },
@@ -2285,6 +2514,7 @@ return {
["smiling face with horns"]={ 0x1F608 },
["smiling face with smiling eyes"]={ 0x1F60A },
["smiling face with sunglasses"]={ 0x1F60E },
+ ["smiling face with tear"]={ 0x1F972 },
["smirking face"]={ 0x1F60F },
["snail"]={ 0x1F40C },
["snake"]={ 0x1F40D },
@@ -2345,6 +2575,12 @@ return {
["stopwatch"]={ 0x23F1, 0xFE0F },
["straight ruler"]={ 0x1F4CF },
["strawberry"]={ 0x1F353 },
+ ["student"]={ 0x1F9D1, 0x200D, 0x1F393 },
+ ["student: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F393 },
+ ["student: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F393 },
+ ["student: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F393 },
+ ["student: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F393 },
+ ["student: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F393 },
["studio microphone"]={ 0x1F399, 0xFE0F },
["stuffed flatbread"]={ 0x1F959 },
["sun"]={ 0x2600, 0xFE0F },
@@ -2374,19 +2610,32 @@ return {
["suspension railway"]={ 0x1F69F },
["swan"]={ 0x1F9A2 },
["sweat droplets"]={ 0x1F4A6 },
- ["swim brief"]={ 0x1FA72 },
["synagogue"]={ 0x1F54D },
["syringe"]={ 0x1F489 },
["t-rex"]={ 0x1F996 },
["t-shirt"]={ 0x1F455 },
["taco"]={ 0x1F32E },
["takeout box"]={ 0x1F961 },
+ ["tamale"]={ 0x1FAD4 },
["tanabata tree"]={ 0x1F38B },
["tangerine"]={ 0x1F34A },
["taurus"]={ 0x2649 },
["taxi"]={ 0x1F695 },
+ ["teacher"]={ 0x1F9D1, 0x200D, 0x1F3EB },
+ ["teacher: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3EB },
+ ["teacher: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3EB },
+ ["teacher: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3EB },
+ ["teacher: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3EB },
+ ["teacher: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3EB },
["teacup without handle"]={ 0x1F375 },
+ ["teapot"]={ 0x1FAD6 },
["tear-off calendar"]={ 0x1F4C6 },
+ ["technologist"]={ 0x1F9D1, 0x200D, 0x1F4BB },
+ ["technologist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F4BB },
+ ["technologist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F4BB },
+ ["technologist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F4BB },
+ ["technologist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F4BB },
+ ["technologist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F4BB },
["teddy bear"]={ 0x1F9F8 },
["telephone"]={ 0x260E, 0xFE0F },
["telephone receiver"]={ 0x1F4DE },
@@ -2399,6 +2648,7 @@ return {
["test tube"]={ 0x1F9EA },
["thermometer"]={ 0x1F321, 0xFE0F },
["thinking face"]={ 0x1F914 },
+ ["thong sandal"]={ 0x1FA74 },
["thought balloon"]={ 0x1F4AD },
["thread"]={ 0x1F9F5 },
["three o’clock"]={ 0x1F552 },
@@ -2426,6 +2676,7 @@ return {
["tongue"]={ 0x1F445 },
["toolbox"]={ 0x1F9F0 },
["tooth"]={ 0x1F9B7 },
+ ["toothbrush"]={ 0x1FAA5 },
["top arrow"]={ 0x1F51D },
["top hat"]={ 0x1F3A9 },
["tornado"]={ 0x1F32A, 0xFE0F },
@@ -2435,6 +2686,8 @@ return {
["train"]={ 0x1F686 },
["tram"]={ 0x1F68A },
["tram car"]={ 0x1F68B },
+ ["transgender flag"]={ 0x1F3F3, 0xFE0F, 0x200D, 0x26A7, 0xFE0F },
+ ["transgender symbol"]={ 0x26A7, 0xFE0F },
["triangular flag"]={ 0x1F6A9 },
["triangular ruler"]={ 0x1F4D0 },
["trident emblem"]={ 0x1F531 },
@@ -2519,6 +2772,7 @@ return {
["whale"]={ 0x1F40B },
["wheel of dharma"]={ 0x2638, 0xFE0F },
["wheelchair symbol"]={ 0x267F },
+ ["white cane"]={ 0x1F9AF },
["white circle"]={ 0x26AA },
["white exclamation mark"]={ 0x2755 },
["white flag"]={ 0x1F3F3, 0xFE0F },
@@ -2533,6 +2787,7 @@ return {
["wilted flower"]={ 0x1F940 },
["wind chime"]={ 0x1F390 },
["wind face"]={ 0x1F32C, 0xFE0F },
+ ["window"]={ 0x1FA9F },
["wine glass"]={ 0x1F377 },
["winking face"]={ 0x1F609 },
["winking face with tongue"]={ 0x1F61C },
@@ -2660,6 +2915,12 @@ return {
["woman farmer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F33E },
["woman farmer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F33E },
["woman farmer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F33E },
+ ["woman feeding baby"]={ 0x1F469, 0x200D, 0x1F37C },
+ ["woman feeding baby: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F37C },
+ ["woman feeding baby: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F37C },
["woman firefighter"]={ 0x1F469, 0x200D, 0x1F692 },
["woman firefighter: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F692 },
["woman firefighter: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F692 },
@@ -2739,6 +3000,12 @@ return {
["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo"]={ 0x1F935, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
["woman judge"]={ 0x1F469, 0x200D, 0x2696, 0xFE0F },
["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
@@ -2931,12 +3198,18 @@ return {
["woman with headscarf: medium skin tone"]={ 0x1F9D5, 0x1F3FD },
["woman with headscarf: medium-dark skin tone"]={ 0x1F9D5, 0x1F3FE },
["woman with headscarf: medium-light skin tone"]={ 0x1F9D5, 0x1F3FC },
- ["woman with probing cane"]={ 0x1F469, 0x200D, 0x1F9AF },
- ["woman with probing cane: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9AF },
- ["woman with probing cane: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["woman with veil"]={ 0x1F470, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: dark skin tone"]={ 0x1F470, 0x1F3FF, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: light skin tone"]={ 0x1F470, 0x1F3FB, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium skin tone"]={ 0x1F470, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
+ ["woman with white cane"]={ 0x1F469, 0x200D, 0x1F9AF },
+ ["woman with white cane: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["woman with white cane: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9AF },
["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640, 0xFE0F },
["woman: bald"]={ 0x1F469, 0x200D, 0x1F9B2 },
["woman: blond hair"]={ 0x1F471, 0x200D, 0x2640, 0xFE0F },
@@ -2984,20 +3257,32 @@ return {
["women holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women holding hands: dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: light skin tone"]={ 0x1F46D, 0x1F3FB },
+ ["women holding hands: light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
+ ["women holding hands: light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
+ ["women holding hands: light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
+ ["women holding hands: light skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium skin tone"]={ 0x1F46D, 0x1F3FD },
+ ["women holding hands: medium skin tone, dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium skin tone, light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
+ ["women holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women holding hands: medium skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium-dark skin tone"]={ 0x1F46D, 0x1F3FE },
+ ["women holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium-dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
["women holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
["women holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium-light skin tone"]={ 0x1F46D, 0x1F3FC },
+ ["women holding hands: medium-light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium-light skin tone, light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
+ ["women holding hands: medium-light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
+ ["women holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women with bunny ears"]={ 0x1F46F, 0x200D, 0x2640, 0xFE0F },
["women wrestling"]={ 0x1F93C, 0x200D, 0x2640, 0xFE0F },
["women’s room"]={ 0x1F6BA },
+ ["wood"]={ 0x1FAB5 },
["woozy face"]={ 0x1F974 },
["world map"]={ 0x1F5FA, 0xFE0F },
+ ["worm"]={ 0x1FAB1 },
["worried face"]={ 0x1F61F },
["wrapped gift"]={ 0x1F381 },
["wrench"]={ 0x1F527 },
diff --git a/tex/context/base/mkiv/cont-fil.mkiv b/tex/context/base/mkiv/cont-fil.mkiv
index 9257e2e1e..aa7d9ddb3 100644
--- a/tex/context/base/mkiv/cont-fil.mkiv
+++ b/tex/context/base/mkiv/cont-fil.mkiv
@@ -16,137 +16,142 @@
\writestatus{loading}{ConTeXt File Synonyms}
-\definefilesynonym [chemics] [chemic]
-
-\definefilesynonym [unit] [units]
-
-\definefilesynonym [pstric] [pstricks]
-\definefilesynonym [pstrick] [pstricks]
-
-\definefilesynonym [finance] [financ]
-
-\definefilesynonym [dir-make] [dir-01]
-\definefilesynonym [dir-identify] [dir-05]
-
-\definefilesynonym [int-load] [set-11]
-\definefilesynonym [int-make] [set-12]
-
- \definefilesynonym [fig-base] [fig-00]
- \definefilesynonym [fig-make] [fig-01]
- \definefilesynonym [fig-fake] [fig-02]
- \definefilesynonym [fig-missing] [fig-06]
-
-\definefilesynonym [exi-interface] [exi-21]
-
- \definefilesynonym [res-make] [res-01]
- \definefilesynonym [res-base] [res-04]
- \definefilesynonym [res-crop] [res-07]
- \definefilesynonym [res-trace] [res-08]
- \definefilesynonym [res-log] [res-09]
- \definefilesynonym [res-identify] [res-12]
-
- \definefilesynonym [med-show] [res-50]
-
-\definefilesynonym [pre-general] [pre-00]
-\definefilesynonym [pre-01] [present-original]
-\definefilesynonym [pre-original] [present-original]
-\definefilesynonym [pre-02] [present-green]
-\definefilesynonym [pre-green] [present-green]
-\definefilesynonym [pre-03] [present-funny]
-\definefilesynonym [pre-funny] [present-funny]
-\definefilesynonym [pre-04] [present-colorful]
-\definefilesynonym [pre-colorful] [present-colorful]
-\definefilesynonym [pre-05] [present-fuzzy]
-\definefilesynonym [pre-fuzzy] [present-fuzzy]
-\definefilesynonym [pre-polish] [pre-06]
-\definefilesynonym [pre-spider] [pre-07]
-\definefilesynonym [pre-wonder] [pre-08]
-\definefilesynonym [pre-09] [present-windows]
-\definefilesynonym [pre-windows] [present-windows]
-\definefilesynonym [pre-10] [present-grow]
-\definefilesynonym [pre-grow] [present-grow]
-\definefilesynonym [pre-11] [present-stack]
-\definefilesynonym [pre-stack] [present-stack]
-\definefilesynonym [pre-arrows] [pre-12]
-\definefilesynonym [pre-writing] [pre-13]
-\definefilesynonym [pre-split] [present-split]
-\definefilesynonym [pre-14] [present-split]
-\definefilesynonym [pre-balls] [present-balls]
-\definefilesynonym [pre-15] [present-balls]
-\definefilesynonym [pre-knot] [pre-16]
-\definefilesynonym [pre-17] [present-weird]
-\definefilesynonym [pre-weird] [present-weird]
-\definefilesynonym [pre-shade] [pre-18]
-\definefilesynonym [pre-organic] [pre-19]
-\definefilesynonym [pre-speckle] [pre-20]
-\definefilesynonym [pre-zoom] [pre-21]
-\definefilesynonym [pre-cycle] [pre-22]
-\definefilesynonym [pre-super] [pre-23]
-%definefilesynonym [pre-more] [pre-24]
-%definefilesynonym [pre-more] [pre-25]
-\definefilesynonym [pre-more] [pre-26]
-%definefilesynonym [pre-more] [pre-27]
-%definefilesynonym [pre-more] [pre-28]
-%definefilesynonym [pre-more] [pre-29]
-%definefilesynonym [pre-more] [pre-30]
-\definefilesynonym [pre-41] [present-tiles]
-\definefilesynonym [pre-60] [present-stepwise]
-\definefilesynonym [pre-stepwise] [present-stepwise]
-\definefilesynonym [pre-61] [present-stepper]
-\definefilesynonym [pre-stepper] [present-stepper]
-\definefilesynonym [pre-62] [present-overlap]
-\definefilesynonym [pre-69] [present-wobbling]
-\definefilesynonym [pre-punk] [present-punk]
-\definefilesynonym [pre-70] [present-punk]
-\definefilesynonym [pre-random] [present-random]
-\definefilesynonym [pre-71] [present-random]
-
-\definefilesynonym [abr-01] [abbreviations-pseudocaps]
-\definefilesynonym [abr-02] [abbreviations-smallcaps]
-\definefilesynonym [abr-03] [abbreviations-words]
-\definefilesynonym [abr-04] [abbreviations-mixed]
-
-\definefilesynonym [art-01] [article-basic]
-\definefilesynonym [article] [article-basic]
-\definefilesynonym [mag-01] [magazine-basic]
-\definefilesynonym [magazine] [magazine-basic]
-\definefilesynonym [mod-01] [module-basic]
-\definefilesynonym [module] [module-basic]
-
-\definefilesynonym [map-10] [maps] % for a while
-
-\definefilesynonym [mml] [mathml]
-\definefilesynonym [cml] [chemml]
-
-\definefilesynonym [letter] [cor-01]
-\definefilesynonym [memo] [cor-02]
-\definefilesynonym [resume] [cor-03]
-
-\definefilesynonym [fnt-10] [fonts-complete]
-\definefilesynonym [fnt-11] [fonts-system]
-\definefilesynonym [fnt-20] [fonts-steps]
-\definefilesynonym [fnt-21] [fonts-steps]
-\definefilesynonym [fnt-22] [fonts-engines]
-\definefilesynonym [fnt-23] [fonts-shapes]
-\definefilesynonym [fnt-24] [fonts-cjk]
-\definefilesynonym [fnt-25] [math-characters]
-\definefilesynonym [fnt-28] [fonts-goodies]
-\definefilesynonym [fnt-29] [fonts-shapes]
-\definefilesynonym [fnt-31] [fonts-coverage]
-\definefilesynonym [fnt-33] [math-coverage]
-
-\definefilesynonym [mat-10] [math-characters]
-\definefilesynonym [mat-11] [math-characters]
-\definefilesynonym [mat-12] [math-parameters]
-\definefilesynonym [mat-20] [math-parameters]
-
-\definefilesynonym [syn-01] [syntax]
-
-\definefilesynonym [reg-01] [regimes-list]
-
-\definefilesynonym [set-11] [setups-basics]
-\definefilesynonym [set-12] [setups-overview]
-%definefilesynonym [set-13] [setups-proofing]
-%definefilesynonym [set-15] [setups-generate]
+\definefilesynonym [chemics] [chemic]
+
+\definefilesynonym [unit] [units]
+
+\definefilesynonym [pstric] [pstricks]
+\definefilesynonym [pstrick] [pstricks]
+
+\definefilesynonym [finance] [financ]
+
+\definefilesynonym [dir-make] [dir-01]
+\definefilesynonym [dir-identify] [dir-05]
+
+\definefilesynonym [int-load] [set-11]
+\definefilesynonym [int-make] [set-12]
+
+ \definefilesynonym [fig-base] [fig-00]
+ \definefilesynonym [fig-make] [fig-01]
+ \definefilesynonym [fig-fake] [fig-02]
+ \definefilesynonym [fig-missing] [fig-06]
+
+ \definefilesynonym [exi-interface] [exi-21]
+
+ \definefilesynonym [res-make] [res-01]
+ \definefilesynonym [res-base] [res-04]
+ \definefilesynonym [res-crop] [res-07]
+ \definefilesynonym [res-trace] [res-08]
+ \definefilesynonym [res-log] [res-09]
+ \definefilesynonym [res-identify] [res-12]
+
+ \definefilesynonym [med-show] [res-50]
+
+\definefilesynonym [pre-general] [pre-00]
+\definefilesynonym [pre-01] [present-original]
+\definefilesynonym [pre-original] [present-original]
+\definefilesynonym [pre-02] [present-green]
+\definefilesynonym [pre-green] [present-green]
+\definefilesynonym [pre-03] [present-funny]
+\definefilesynonym [pre-funny] [present-funny]
+\definefilesynonym [pre-04] [present-colorful]
+\definefilesynonym [pre-colorful] [present-colorful]
+\definefilesynonym [pre-05] [present-fuzzy]
+\definefilesynonym [pre-fuzzy] [present-fuzzy]
+\definefilesynonym [pre-polish] [pre-06]
+\definefilesynonym [pre-spider] [pre-07]
+\definefilesynonym [pre-wonder] [pre-08]
+\definefilesynonym [pre-09] [present-windows]
+\definefilesynonym [pre-windows] [present-windows]
+\definefilesynonym [pre-10] [present-grow]
+\definefilesynonym [pre-grow] [present-grow]
+\definefilesynonym [pre-11] [present-stack]
+\definefilesynonym [pre-stack] [present-stack]
+\definefilesynonym [pre-arrows] [pre-12]
+\definefilesynonym [pre-writing] [pre-13]
+\definefilesynonym [pre-split] [present-split]
+\definefilesynonym [pre-14] [present-split]
+\definefilesynonym [pre-balls] [present-balls]
+\definefilesynonym [pre-15] [present-balls]
+\definefilesynonym [pre-knot] [pre-16]
+\definefilesynonym [pre-17] [present-weird]
+\definefilesynonym [pre-weird] [present-weird]
+\definefilesynonym [pre-shade] [pre-18]
+\definefilesynonym [pre-organic] [pre-19]
+\definefilesynonym [pre-speckle] [pre-20]
+\definefilesynonym [pre-zoom] [pre-21]
+\definefilesynonym [pre-cycle] [pre-22]
+\definefilesynonym [pre-super] [pre-23]
+%definefilesynonym [pre-more] [pre-24]
+%definefilesynonym [pre-more] [pre-25]
+\definefilesynonym [pre-more] [pre-26]
+%definefilesynonym [pre-more] [pre-27]
+%definefilesynonym [pre-more] [pre-28]
+%definefilesynonym [pre-more] [pre-29]
+%definefilesynonym [pre-more] [pre-30]
+\definefilesynonym [pre-41] [present-tiles]
+\definefilesynonym [pre-60] [present-stepwise]
+\definefilesynonym [pre-stepwise] [present-stepwise]
+\definefilesynonym [pre-61] [present-stepper]
+\definefilesynonym [pre-stepper] [present-stepper]
+\definefilesynonym [pre-62] [present-overlap]
+\definefilesynonym [pre-69] [present-wobbling]
+\definefilesynonym [pre-punk] [present-punk]
+\definefilesynonym [pre-70] [present-punk]
+\definefilesynonym [pre-random] [present-random]
+\definefilesynonym [pre-71] [present-random]
+
+\definefilesynonym [abr-01] [abbreviations-pseudocaps]
+\definefilesynonym [abr-02] [abbreviations-smallcaps]
+\definefilesynonym [abr-03] [abbreviations-words]
+\definefilesynonym [abr-04] [abbreviations-mixed]
+
+\definefilesynonym [art-01] [article-basic]
+\definefilesynonym [article] [article-basic]
+\definefilesynonym [mag-01] [magazine-basic]
+\definefilesynonym [magazine] [magazine-basic]
+\definefilesynonym [mod-01] [module-basic]
+\definefilesynonym [module] [module-basic]
+
+\definefilesynonym [map-10] [maps] % for a while
+
+\definefilesynonym [mml] [mathml]
+\definefilesynonym [cml] [chemml]
+
+\definefilesynonym [letter] [cor-01]
+\definefilesynonym [memo] [cor-02]
+\definefilesynonym [resume] [cor-03]
+
+\definefilesynonym [fnt-10] [fonts-complete]
+\definefilesynonym [fnt-11] [fonts-system]
+\definefilesynonym [fnt-20] [fonts-steps]
+\definefilesynonym [fnt-21] [fonts-steps]
+\definefilesynonym [fnt-22] [fonts-engines]
+\definefilesynonym [fnt-23] [fonts-shapes]
+\definefilesynonym [fnt-24] [fonts-cjk]
+\definefilesynonym [fnt-25] [math-characters]
+\definefilesynonym [fnt-28] [fonts-goodies]
+\definefilesynonym [fnt-29] [fonts-shapes]
+\definefilesynonym [fnt-31] [fonts-coverage]
+\definefilesynonym [fnt-33] [math-coverage]
+
+\definefilesynonym [mat-10] [math-characters]
+\definefilesynonym [mat-11] [math-characters]
+\definefilesynonym [mat-12] [math-parameters]
+\definefilesynonym [mat-20] [math-parameters]
+
+\definefilesynonym [syn-01] [syntax]
+
+\definefilesynonym [reg-01] [regimes-list]
+
+\definefilesynonym [set-11] [setups-basics]
+\definefilesynonym [set-12] [setups-overview]
+%definefilesynonym [set-13] [setups-proofing]
+%definefilesynonym [set-15] [setups-generate]
+
+\ifcase\contextlmtxmode \else
+ \definefilesynonym [ecmascript] [libs-imp-mujs]
+ \definefilesynonym [zint] [libs-imp-zint]
+\fi
\endinput
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 2cc2a1098..cd700391a 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.01.26 18:34}
+\newcontextversion{2020.02.11 16:36}
%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 d4206a4e8..30389e598 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 1b4da4e96..ef3fddc3d 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/data-tmp.lua b/tex/context/base/mkiv/data-tmp.lua
index bfced1e64..9b0117c15 100644
--- a/tex/context/base/mkiv/data-tmp.lua
+++ b/tex/context/base/mkiv/data-tmp.lua
@@ -364,7 +364,7 @@ function caches.is_writable(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions = { compact = true }
+local saveoptions = { compact = true, accurate = not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname, tmcname = setluanames(filepath,filename)
diff --git a/tex/context/base/mkiv/driv-shp.lua b/tex/context/base/mkiv/driv-shp.lua
index cc8b6bdbe..a4e36105d 100644
--- a/tex/context/base/mkiv/driv-shp.lua
+++ b/tex/context/base/mkiv/driv-shp.lua
@@ -381,6 +381,7 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
factor = 0
end
end
+
if pos_r == righttoleft_code then
pos_h = pos_h - width
end
@@ -390,6 +391,7 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
if vfcommands then
flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommands) -- also f ?
else
+ -- kind of messy that we do orientation here and offsets elsewhere
local orientation = data.orientation
if orientation and (orientation == 1 or orientation == 3) then
local x = data.xoffset
@@ -401,10 +403,10 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
pos_v = pos_v + y
end
pushorientation(orientation,pos_h,pos_v)
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
poporientation(orientation,pos_h,pos_v)
else
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
end
end
return width, height, depth
diff --git a/tex/context/base/mkiv/file-job.lua b/tex/context/base/mkiv/file-job.lua
index 4b29f57ec..407c3c15d 100644
--- a/tex/context/base/mkiv/file-job.lua
+++ b/tex/context/base/mkiv/file-job.lua
@@ -326,6 +326,8 @@ end
local suffixes = {
mkvi = usetexfile,
mkiv = usetexfile,
+ mklx = usetexfile,
+ mkxl = usetexfile,
tex = usetexfile,
luc = useluafile,
lua = useluafile,
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index e42d20d4e..1bb63aa51 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -1139,6 +1139,7 @@ hashmethods.normal = function(list)
m = m + 1
t[m] = k .. '=' .. tostring(v)
end
+ sort(t)
s[n] = k .. '={' .. concat(t,",") .. "}"
else
s[n] = k .. '=' .. tostring(v)
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index cbb81cdb7..bf14dd309 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -887,23 +887,6 @@ specifiers.definecontext = definecontext
-- we extend the hasher:
--- constructors.hashmethods.virtual = function(list)
--- local s = { }
--- local n = 0
--- for k, v in next, list do
--- n = n + 1
--- s[n] = k -- no checking on k
--- end
--- if n > 0 then
--- sort(s)
--- for i=1,n do
--- local k = s[i]
--- s[i] = k .. '=' .. tostring(list[k])
--- end
--- return concat(s,"+")
--- end
--- end
-
constructors.hashmethods.virtual = function(list)
local s = { }
local n = 0
@@ -924,6 +907,54 @@ constructors.hashmethods.virtual = function(list)
end
end
+if not JITSUPPORTED then
+
+ constructors.hashmethods.normal = function(list)
+ local s = { }
+ local n = 0
+ for k, v in next, list do
+ if not k then
+ -- no need to add to hash
+ elseif k == "number" or k == "features" then
+ -- no need to add to hash (maybe we need a skip list)
+ else
+ n = n + 1
+ if type(v) == "table" then
+ -- table.sequenced
+ local t = { }
+ local m = 0
+ for k, v in next, v do
+ m = m + 1
+ t[m] = format("%q=%q",k,v)
+ end
+ sort(t)
+ s[n] = format("%q={%s}",k,concat(t,","))
+ else
+ s[n] = format("%q=%q",k,v)
+ end
+ end
+ end
+ if n > 0 then
+ sort(s)
+ return concat(s,"+")
+ end
+ end
+
+ constructors.hashmethods.virtual = function(list)
+ local s = { }
+ local n = 0
+ for k, v in next, list do
+ n = n + 1
+ s[n] = format("%q=%q",k,v)
+ end
+ if n > 0 then
+ sort(s)
+ return concat(s,"+")
+ end
+ end
+
+end
+
-- end of redefine
-- local withcache = { } -- concat might be less efficient than nested tables
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 7777f9c6a..3058be37b 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -3237,7 +3237,8 @@ function readers.sbix(f,fontdata,specification)
return b.ppem < a.ppem
end
end)
- local glyphs = { }
+ local glyphs = { }
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike = strikes[i]
local strikeppem = strike.ppem
@@ -3254,13 +3255,28 @@ function readers.sbix(f,fontdata,specification)
local datasize = nextoffset - glyphoffset
if datasize > 0 then
setposition(f,strikeoffset + glyphoffset)
+ local x = readshort(f)
+ local y = readshort(f)
+ local tag = readtag(f) -- or just skip, we never needed it till now
+ local size = datasize - 8
+ local data = nil
+ local offset = nil
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ data = readstring(f,size)
+ size = nil
+ end
shapes[i] = {
- x = readshort(f),
- y = readshort(f),
- tag = readtag(f), -- maybe for tracing
- data = readstring(f,datasize-8),
- ppem = strikeppem, -- not used, for tracing
- ppi = strikeppi, -- not used, for tracing
+ x = x,
+ y = y,
+ o = offset,
+ s = size,
+ data = data,
+ -- tag = tag, -- maybe for tracing
+ -- ppem = strikeppem, -- not used, for tracing
+ -- ppi = strikeppi, -- not used, for tracing
}
done = done + 1
if done == nofglyphs then
@@ -3462,32 +3478,48 @@ do
local default = { width = 0, height = 0 }
local glyphs = fontdata.glyphs
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for index, subtable in sortedhash(shapes) do
if type(subtable) == "table" then
local data = nil
+ local size = nil
local metrics = default
local format = subtable.format
local offset = subtable.offsets[index]
setposition(f,offset)
if format == 17 then
metrics = getsmallmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 18 then
metrics = getbigmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 19 then
metrics = subtable.metrics
- data = readstring(f,readulong(f))
+ size = true
else
-- forget about it
end
+ if size then
+ size = readulong(f)
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ offset = nil
+ data = readstring(f,size)
+ size = nil
+ end
+ else
+ offset = nil
+ end
local x = metrics.width
local y = metrics.height
shapes[index] = {
- -- maybe some metrics
x = x,
y = y,
+ o = offset,
+ s = size,
data = data,
}
-- I'll look into this in more details when needed
@@ -3498,12 +3530,11 @@ do
local height = width * y/x
glyph.boundingbox = { 0, 0, width, height }
end
-
else
shapes[index] = {
x = 0,
y = 0,
- data = "",
+ data = "", -- or just nil
}
end
end
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index da02ab608..fe972114f 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.110
+ otf.version = otf.version or 3.111
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua
index 77e1538f9..eef221e46 100644
--- a/tex/context/base/mkiv/font-ocl.lua
+++ b/tex/context/base/mkiv/font-ocl.lua
@@ -401,7 +401,7 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg
-- The down and right will change too (we can move that elsewhere). We have
-- a different treatment in lmtx but the next kind of works. These images are
-- a mess anyway as in svg the bbox can be messed up absent). A png image
- -- needs the x/y. I might normalize this once we moev to lmtx exlusively.
+ -- needs the x/y. I might normalize this once we move to lmtx exlusively.
character.commands = {
not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) },
-- lmtx (when we deal with depth in vfimage, currently disabled):
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 5d3bd4230..aff4cc8c8 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.110 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.111 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
@@ -534,6 +534,9 @@ local converters = {
}
}
+-- We can get differences between daylight saving etc ... but it makes no sense to
+-- mess with trickery .. so be it when you use a different binary.
+
local function checkconversion(specification)
local filename = specification.filename
local converter = converters[lower(file.suffix(filename))]
diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua
index 8394d19e7..64c7de567 100644
--- a/tex/context/base/mkiv/l-os.lua
+++ b/tex/context/base/mkiv/l-os.lua
@@ -637,6 +637,14 @@ function os.validdate(year,month,day)
return year, month, day
end
+function os.date(fmt,...)
+ if not fmt then
+ -- otherwise differences between unix, mingw and msvc
+ fmt = "%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
+
local osexit = os.exit
local exitcode = nil
diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua
index 98b377bdc..c20bd4733 100644
--- a/tex/context/base/mkiv/l-table.lua
+++ b/tex/context/base/mkiv/l-table.lua
@@ -525,84 +525,15 @@ function table.fromhash(t)
return hsh
end
-local noquotes, hexify, handle, compact, inline, functions, metacheck
+local noquotes, hexify, handle, compact, inline, functions, metacheck, accurate
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
- 'NaN', 'goto',
+ 'NaN', 'goto', 'const',
}
--- local function is_simple_table(t)
--- if #t > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- end
--- if n == #t then
--- local tt, nt = { }, 0
--- for i=1,#t do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- nt = nt + 1
--- if hexify then
--- tt[nt] = format("0x%X",v)
--- else
--- tt[nt] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- nt = nt + 1
--- tt[nt] = format("%q",v)
--- elseif tv == "boolean" then
--- nt = nt + 1
--- tt[nt] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
--- local function is_simple_table(t)
--- local nt = #t
--- if nt > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- -- if type(v) == "table" then
--- -- return nil
--- -- end
--- end
--- if n == nt then
--- local tt = { }
--- for i=1,nt do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- if hexify then
--- tt[i] = format("0x%X",v)
--- else
--- tt[i] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- tt[i] = format("%q",v)
--- elseif tv == "boolean" then
--- tt[i] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
-local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify,accurate) -- also used in util-tab so maybe public
local nt = #t
if nt > 0 then
local n = 0
@@ -623,6 +554,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i] = v -- not needed tostring(v)
if hexify then
tt[i] = format("0x%X",v)
+ elseif accurate then
+ tt[i] = format("%q",v)
else
tt[i] = v -- not needed tostring(v)
end
@@ -644,6 +577,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i+1] = v -- not needed tostring(v)
if hexify then
tt[i+1] = format("0x%X",v)
+ elseif accurate then
+ tt[i+1] = format("%q",v)
else
tt[i+1] = v -- not needed tostring(v)
end
@@ -738,6 +673,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv == "number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
@@ -747,7 +684,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v) == nil then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -775,12 +712,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif tk == "boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
end
@@ -789,12 +730,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
@@ -803,6 +748,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -820,6 +767,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -833,11 +782,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -860,6 +811,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -881,6 +834,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -899,6 +854,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -927,6 +884,7 @@ local function serialize(_handle,root,name,specification) -- handle wins
if type(specification) == "table" then
noquotes = specification.noquotes
hexify = specification.hexify
+ accurate = specification.accurate
handle = _handle or specification.handle or print
functions = specification.functions
compact = specification.compact
diff --git a/tex/context/base/mkiv/libs-imp-mujs.lua b/tex/context/base/mkiv/libs-imp-mujs.lua
new file mode 100644
index 000000000..264c8e531
--- /dev/null
+++ b/tex/context/base/mkiv/libs-imp-mujs.lua
@@ -0,0 +1,126 @@
+if not modules then modules = { } end modules ['libs-imp-mujs'] = {
+ version = 1.001,
+ comment = "companion to luat-imp-mujs.mkxl",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is an experiment. When a new user knows \JAVASCRIPT\ it can be a
+-- stepping stone to using \LUA.
+
+-- local ecmascript = optional.mujs.initialize("libmujs")
+-- local execute = optional.mujs.execute
+
+local libname = "mujs"
+local libfile = "libmujs"
+
+if package.loaded[libname] then
+ return package.loaded[libname]
+end
+
+local mujslib = resolvers.libraries.validoptional(libname)
+
+if not mujslib then
+ return
+end
+
+local files = { }
+local openfile = io.open
+local findfile = resolvers.findfile
+
+local mujs_execute = mujslib.execute
+local mujs_dofile = mujslib.dofile
+local mujs_reset = mujslib.reset
+
+local function okay()
+ if resolvers.libraries.optionalloaded(libname,libfile) then
+ mujs_execute(
+ "var catcodes = { " ..
+ "'tex': " .. tex.texcatcodes .. "," ..
+ "'ctx': " .. tex.ctxcatcodes .. "," ..
+ "'prt': " .. tex.prtcatcodes .. "," ..
+ "'vrb': " .. tex.vrbcatcodes .. "," ..
+ "};"
+ )
+ okay = function() return true end
+ else
+ okay = function() return false end
+ end
+ return okay()
+end
+
+mujslib.setfindfile(findfile)
+
+mujslib.setopenfile(function(name)
+ local full = findfile(name)
+ if full then
+ local f = openfile(full,"rb")
+ if f then
+ for i=1,100 do
+ if not files[i] then
+ files[i] = f
+ return i
+ end
+ end
+ end
+ end
+end)
+
+mujslib.setclosefile(function(id)
+ local f = files[id]
+ if f then
+ f:close()
+ files[id] = false
+ end
+end)
+
+mujslib.setreadfile(function(id,how)
+ local f = files[id]
+ if f then
+ return (f:read(how or "*l"))
+ end
+end)
+
+mujslib.setseekfile(function(id,whence,offset)
+ local f = files[id]
+ if f then
+ return (f:seek(whence,offset))
+ end
+end)
+
+local reporters = {
+ console = logs.reporter("mujs","console"),
+ report = logs.reporter("mujs","report"),
+}
+
+mujslib.setconsole(function(category,name)
+ reporters[category](name)
+end)
+
+local mujs = {
+ ["execute"] = function(c,s) if okay() then mujs_execute(c,s) end end,
+ ["dofile"] = function(n) if okay() then mujs_dofile(n) end end,
+ ["reset"] = function(n) if okay() then mujs_reset(n) end end,
+}
+
+package.loaded[libname] = mujs
+
+optional.loaded.mujs = mujs
+
+interfaces.implement {
+ name = "ecmacode",
+ actions = mujs.execute,
+ arguments = "string",
+ public = true,
+}
+
+interfaces.implement {
+ name = "ecmafile",
+ actions = mujs.dofile,
+ arguments = "string",
+ public = true,
+ protected = true,
+}
+
+return mujs
diff --git a/tex/context/base/mkiv/libs-imp-mujs.mkxl b/tex/context/base/mkiv/libs-imp-mujs.mkxl
new file mode 100644
index 000000000..0f278dff5
--- /dev/null
+++ b/tex/context/base/mkiv/libs-imp-mujs.mkxl
@@ -0,0 +1,121 @@
+%D \module
+%D [ file=libs-imp-mujs,
+%D version=2020.02.08,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=MuJS interpreter,
+%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.
+
+%D Just an experiment:
+%D
+%D \starttyping
+%D http://mujs.com
+%D \stoptyping
+
+\ifdefined\ecmacode
+ \expandafter \endinput
+\fi
+
+\registerctxluafile{libs-imp-mujs}{}
+
+\unprotect
+
+% todo: environment
+
+\let\stopecmacode\relax
+
+\normalprotected\def\startecmacode % \stopecmacode
+ {\begingroup
+ \obeylualines
+ \obeyluatokens
+ \luat_start_ecma_code_indeed}
+
+\def\luat_start_ecma_code_indeed#1\stopecmacode
+ {\normalexpanded{\endgroup\noexpand\ecmacode{#1}}}
+
+\protect
+
+\continueifinputfile{libs-imp-mujs.mkxl}
+
+\usemodule[article-basic,abbreviations-logos]
+
+\starttext
+
+\startbuffer
+\startluacode
+ local mujs = require("libs-imp-mujs")
+
+ mujs.execute [[
+ var MyMax = 1000;
+ ]]
+
+ mujs.execute [[
+ console("Example One!");
+ texsprint("\\startpacked");
+ for (var i = 1; i <= MyMax; i = i + 1) {
+ texprint(
+ "This is a buildbot compilation challenge for Mojca: "
+ .concat(Math.sqrt(i/MyMax))
+ .concat("!\\par")
+ );
+ }
+ texsprint("\\stoppacked");
+ ]]
+
+ -- mujs.execute [[
+ -- something very bad: an error
+ -- ]]
+\stopluacode
+
+\startecmacode
+ console("Example Two!");
+ for (var i = 1; i <= MyMax; i = i + 1) {
+ texsprint(
+ "And an opportunity for Alan to attract highschool students to \\TeX: "
+ .concat(i)
+ .concat("! ")
+ );
+ }
+\stopecmacode
+
+\ecmacode {
+ console("Example Three!");
+ texprint("And otherwise a way to prototype \\JAVASCRIPT\\ code in \\PDF.")
+}
+
+\startecmacode
+ var f = File("libs-imp-mujs.mkxl","r");
+ console(f);
+ // var l = f.read(400);
+ var l = f.read("*a");
+ console(l);
+ f.close();
+\stopecmacode
+
+\startecmacode
+ console("Example Four!");
+ texsprint("\\startMPcode "
+ .concat(' fill fullcircle scaled 6cm withcolor "darkred";')
+ .concat(' fill fullcircle scaled 4cm withcolor "darkgreen";')
+ .concat(' fill fullcircle scaled 2cm withcolor "darkblue";')
+ .concat("\\stopMPcode ")
+ );
+\stopecmacode
+
+\startluacode
+ context.startMPcode()
+ context('fill fullcircle scaled 6cm withcolor "middlecyan";')
+ context('fill fullcircle scaled 4cm withcolor "middlemagenta";')
+ context('fill fullcircle scaled 2cm withcolor "middleyellow";')
+ context.stopMPcode()
+\stopluacode
+\stopbuffer
+
+\typebuffer \page \getbuffer
+
+\stoptext
diff --git a/tex/context/base/mkiv/libs-imp-mysql.lua b/tex/context/base/mkiv/libs-imp-mysql.lua
index b3896acd4..3e938a6de 100644
--- a/tex/context/base/mkiv/libs-imp-mysql.lua
+++ b/tex/context/base/mkiv/libs-imp-mysql.lua
@@ -44,15 +44,20 @@ local validspecification = helpers.validspecification
local preparetemplate = helpers.preparetemplate
local querysplitter = helpers.querysplitter
local cache = { }
+local timeout -- = 3600 -- to be tested
local function connect(specification)
- return mysql_open(
+ local db = mysql_open(
specification.database or "",
specification.username or "",
specification.password or "",
specification.host or "",
specification.port
)
+ if db and timeout then
+ mysql_execute(db,formatters["SET SESSION connect_timeout=%s ;"](timeout))
+ end
+ return db
end
local function execute_once(specification,retry)
@@ -110,13 +115,13 @@ local function execute_once(specification,retry)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
@@ -131,7 +136,7 @@ local function execute_once(specification,retry)
for i=1,#query do
local okay = mysql_execute(db,query[i],callback)
if not okay then
- if id and option == "retry" and i == 1 then
+ if id and retry and i == 1 then
report("error: %s, retrying to connect",mysql_getmessage(db))
mysql_close(db)
cache[id] = nil
@@ -183,6 +188,23 @@ return function(cells)
end
]]
+-- return function(result)
+-- if not result then
+-- return { }
+-- end
+-- local nofrows = #result
+-- if nofrows == 0 then
+-- return { }
+-- end
+-- local target = { } -- no %s needed here
+-- for i=1,nofrows do
+-- target[%s] = {
+-- %s
+-- }
+-- end
+-- return result
+-- end
+
local celltemplate = "cells[%s]"
methods.mysql = {
@@ -192,5 +214,7 @@ methods.mysql = {
celltemplate = celltemplate,
}
-package.loaded["util-sql-imp-mysql"] = methods.mysql
-package.loaded[libname] = methods.mysql
+package.loaded["util-sql-imp-ffi"] = methods.mysql
+package.loaded["util-sql-imp-mysql"] = methods.mysql
+package.loaded["util-sql-imp-library"] = methods.mysql
+package.loaded[libname] = methods.mysql
diff --git a/tex/context/base/mkiv/libs-imp-postgress.lua b/tex/context/base/mkiv/libs-imp-postgress.lua
index 5cd04e03b..629079b01 100644
--- a/tex/context/base/mkiv/libs-imp-postgress.lua
+++ b/tex/context/base/mkiv/libs-imp-postgress.lua
@@ -114,13 +114,13 @@ local function execute_once(specification,retry)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
@@ -135,7 +135,7 @@ local function execute_once(specification,retry)
for i=1,#query do
local okay = postgress_execute(db,query[i],callback)
if not okay then
- if id and option == "retry" and i == 1 then
+ if id and retry and i == 1 then
report("error: %s, retrying to connect",postgress_getmessage(db))
postgress_close(db)
cache[id] = nil
diff --git a/tex/context/base/mkiv/libs-imp-sqlite.lua b/tex/context/base/mkiv/libs-imp-sqlite.lua
index 15c3222ea..5d38986f3 100644
--- a/tex/context/base/mkiv/libs-imp-sqlite.lua
+++ b/tex/context/base/mkiv/libs-imp-sqlite.lua
@@ -119,13 +119,13 @@ local function execute(specification)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
diff --git a/tex/context/base/mkiv/libs-imp-zint.lua b/tex/context/base/mkiv/libs-imp-zint.lua
index eef2cd605..2c346ae7d 100644
--- a/tex/context/base/mkiv/libs-imp-zint.lua
+++ b/tex/context/base/mkiv/libs-imp-zint.lua
@@ -78,7 +78,7 @@ local shown = false
----- f_rectangle = string.formatters["%sofill unitsquare xysized (%N,%N) shifted (%N,%N);"]
-function zint.execute(specification)
+local function execute(specification)
if okay() then
local code = specification.code
local text = specification.text
@@ -146,3 +146,16 @@ function zint.execute(specification)
end
end
end
+
+optional.loaded.zint = { execute = execute }
+
+interfaces.implement {
+ name = "zint",
+ actions = execute,
+ arguments = {
+ {
+ { "code" },
+ { "text" },
+ }
+ }
+}
diff --git a/tex/context/base/mkiv/libs-imp-zint.mkxl b/tex/context/base/mkiv/libs-imp-zint.mkxl
index d7436a4a4..72ce8157e 100644
--- a/tex/context/base/mkiv/libs-imp-zint.mkxl
+++ b/tex/context/base/mkiv/libs-imp-zint.mkxl
@@ -35,7 +35,10 @@
[\c!alternative=,\c!text=,#1]%
\scale
[#1]%
- {\ctxlua{utilities.zint.execute{code="\dummyparameter\c!alternative",text=\!!bs\dummyparameter\c!text\!!es}}}%
+ {\clf_zint
+ code {\dummyparameter\c!alternative}
+ text {\dummyparameter\c!text}
+ \relax}
\egroup}
\protect
diff --git a/tex/context/base/mkiv/libs-ini.lua b/tex/context/base/mkiv/libs-ini.lua
index 2422305f0..2bac3201d 100644
--- a/tex/context/base/mkiv/libs-ini.lua
+++ b/tex/context/base/mkiv/libs-ini.lua
@@ -106,6 +106,8 @@ resolvers.libraries = libraries
local report = logs.reporter("optional")
+if optional then optional.loaded = { } end
+
function libraries.validoptional(name)
local thelib = optional and optional[name]
if not thelib then
@@ -152,6 +154,21 @@ function libraries.optionalloaded(name,libnames)
end
end
+if FFISUPPORTED and ffi and ffi.load then
+
+ local ffiload = ffi.load
+
+ function ffi.load(name)
+ local full = name and foundlibraries[name]
+ if full then
+ return ffiload(full)
+ else
+ return ffiload(name)
+ end
+ end
+
+end
+
-- local patterns = {
-- "libs-imp-%s.mkxl",
-- "libs-imp-%s.mklx",
diff --git a/tex/context/base/mkiv/lpdf-emb.lua b/tex/context/base/mkiv/lpdf-emb.lua
index 8db2ecaf1..4ffcfd8a8 100644
--- a/tex/context/base/mkiv/lpdf-emb.lua
+++ b/tex/context/base/mkiv/lpdf-emb.lua
@@ -1721,6 +1721,12 @@ do
-- Acrobat X pro only seems to see the image mask but other viewers are doing it ok. Acrobat
-- reader crashes. We really need to add a notdef!
+ local files = utilities.files
+ local openfile = files.open
+ local closefile = files.close
+ local setposition = files.setposition
+ local readstring = files.readstring
+
function methods.png(filename,details)
local properties = details.properties
local pngshapes = properties.indexdata[1]
@@ -1732,23 +1738,37 @@ do
local nofglyphs = 0
local scale = 10 * parameters.size/parameters.designsize
local factor = bpfactor / scale
- local units = parameters.units / 1000
+ -- local units = parameters.units -- / 1000
+ local units = 1000
+ local filehandle = openfile(details.filename,true)
local function pngtopdf(glyph,data)
- -- local width = data.width
- local info = graphics.identifiers.png(glyph.data,"string")
- info.enforcecmyk = pngshapes.enforcecmyk
- local image = lpdf.injectors.png(info,"string")
- embedimage(image)
- nofglyphs = nofglyphs + 1
- local width = (data.width or 0) * factor
- local xoffset = (glyph.x or 0) / units
- local yoffset = (glyph.y or 0) / units
- local name = f_glyph(nofglyphs)
- xforms[name] = pdfreference(image.objnum)
- local pdf = f_image_xy(width,xoffset,yoffset,name)
- return pdf, width
+ -- local info = graphics.identifiers.png(glyph.data,"string")
+ local offset = glyph.o
+ local size = glyph.s
+ local pdfdata = nil
+ if offset and size then
+ setposition(filehandle,offset)
+ local blob = readstring(filehandle,size)
+ local info = graphics.identifiers.png(blob,"string")
+ info.enforcecmyk = pngshapes.enforcecmyk
+ local image = lpdf.injectors.png(info,"string")
+ local width = (data.width or 0) * factor
+ if image then
+ embedimage(image)
+ nofglyphs = nofglyphs + 1
+ local xoffset = (glyph.x or 0) / units
+ local yoffset = (glyph.y or 0) / units
+ local name = f_glyph(nofglyphs)
+ xforms[name] = pdfreference(image.objnum)
+ pdfdata = f_image_xy(width,xoffset,yoffset,name)
+ end
+ end
+ return pdfdata or f_stream(width), width
end
local function closepng()
+ if filehandle then
+ closefile(filehandle)
+ end
pngshapes = nil
end
local function getresources()
diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua
index a14df3eca..0ad0c4e5e 100644
--- a/tex/context/base/mkiv/lpdf-lmt.lua
+++ b/tex/context/base/mkiv/lpdf-lmt.lua
@@ -74,6 +74,7 @@ local pdf_form = pdfconstant("Form")
local fonthashes = fonts.hashes
local characters = fonthashes.characters
+local descriptions = fonthashes.descriptions
local parameters = fonthashes.parameters
local properties = fonthashes.properties
@@ -146,6 +147,7 @@ end
-- fonts
local fontcharacters
+local fontdescriptions
local fontparameters
local fontproperties
local usedcharacters = setmetatableindex("table")
@@ -161,6 +163,7 @@ lpdf.usedcharacters = usedcharacters
local function updatefontstate(font)
fontcharacters = characters[font]
+ fontdescriptions = descriptions[font]
fontparameters = parameters[font]
fontproperties = properties[font]
local size = fontparameters.size -- or bad news
@@ -373,6 +376,32 @@ local flushcharacter do
-- as fontparameters already has checked / set it we can also have a variable
-- for it so
+ local naturalwidth = nil
+
+ local naturalwidths = setmetatableindex(function(t,font)
+ local d = descriptions[font]
+ local c = characters[font]
+ local f = parameters[font].hfactor
+ local v = setmetatableindex(function(t,char)
+ local e = d and d[char]
+ local w = 0
+ if e then
+ w = e.width
+ if w then
+ w = w * f
+ end
+ end
+ e = c[char]
+ if e then
+ w = e.width or 0
+ end
+ t[char] = w
+ return w
+ end)
+ t[font] = v
+ return v
+ end)
+
local function setup_fontparameters(font,factor,f,e)
local slant = fontparameters.slantfactor or 0
local extend = fontparameters.extendfactor or 1
@@ -401,6 +430,8 @@ local flushcharacter do
if format == "opentype" or format == "type1" then
fs = fs * 1000 / fontparameters.units -- can we avoid this ?
end
+ --
+ naturalwidth = naturalwidths[font]
end
-- This only saves a little on hz because there we switch a lot of
@@ -512,7 +543,7 @@ local flushcharacter do
local trace_threshold = false trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end)
- flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
if need_tf or font ~= f_cur or f_pdf ~= f_pdf_cur or fs ~= fs_cur or mode == "page" then
pdf_goto_textmode()
setup_fontparameters(font,factor,f,e)
@@ -523,12 +554,12 @@ local flushcharacter do
end
local move = calc_pdfpos(pos_h,pos_v)
- if trace_threshold then
- report(
- "font %i, char %C, factor %i, width %p, naturalwidth %p, move %l, tm %l, hpos %p, delta %p, threshold %p, cw %p",
- font,char,factor,width,naturalwidth,move,need_tm,pos_h,tj_delta,threshold,cw
- )
- end
+ -- if trace_threshold then
+ -- report(
+ -- "font %i, char %C, factor %i, naturalwidth %p, move %l, tm %l, hpos %p, delta %p, threshold %p, cw %p",
+ -- font,char,factor,naturalwidth[char],move,need_tm,pos_h,tj_delta,threshold,cw
+ -- )
+ -- end
if move or need_tm then
if not need_tm then
@@ -569,7 +600,8 @@ local flushcharacter do
end
-- cw = cw + naturalwidth
- cw = cw + width
+ -- cw = cw + width
+ cw = cw + naturalwidth[char]
local index = data.index or char
@@ -2407,67 +2439,69 @@ updaters.register("backend.update.pdf",function()
end
local function embedimage(specification)
- lastindex = lastindex + 1
- index = lastindex
- specification.index = index
- local xobject = pdfdictionary { }
- if not specification.notype then
- xobject.Type = pdf_xobject
- xobject.Subtype = pdf_form
- xobject.FormType = 1
- end
- local bbox = specification.bbox
- if bbox and not specification.nobbox then
- xobject.BBox = pdfarray {
- bbox[1] * bpfactor,
- bbox[2] * bpfactor,
- bbox[3] * bpfactor,
- bbox[4] * bpfactor,
- }
- end
- xobject = xobject + specification.attr
- if bbox and not specification.width then
- specification.width = bbox[3]
- end
- if bbox and not specification.height then
- specification.height = bbox[4]
- end
- local dict = xobject()
- --
- nofobjects = nofobjects + 1
- local objnum = nofobjects
- local nolength = specification.nolength
- local stream = specification.stream or specification.string
- --
- -- We cannot set type in native img so we need this hack or
- -- otherwise we need to patch too much. Better that i write
- -- a wrapper then. Anyway, it has to be done better: a key that
- -- tells either or not to scale by xsize/ysize when flushing.
- --
- if not specification.type then
- local kind = specification.kind
- if kind then
- -- take that one
- elseif attr and find(attr,"BBox") then
- kind = img_stream
- else
- -- hack: a bitmap
- kind = img_none
+ if specification then
+ lastindex = lastindex + 1
+ index = lastindex
+ specification.index = index
+ local xobject = pdfdictionary { }
+ if not specification.notype then
+ xobject.Type = pdf_xobject
+ xobject.Subtype = pdf_form
+ xobject.FormType = 1
end
- specification.type = kind
- specification.kind = kind
- end
- local compress = compresslevel and compresslevel > 0 or nil
- flushstreamobj(stream,objnum,dict,compress,nolength)
- specification.objnum = objnum
- specification.rotation = specification.rotation or 0
- specification.orientation = specification.orientation or 0
- specification.transform = specification.transform or 0
- specification.stream = nil
- specification.attr = nil
- specification.type = specification.kind or specification.type or img_none
- indices[index] = specification -- better create a real specification
- return specification
+ local bbox = specification.bbox
+ if bbox and not specification.nobbox then
+ xobject.BBox = pdfarray {
+ bbox[1] * bpfactor,
+ bbox[2] * bpfactor,
+ bbox[3] * bpfactor,
+ bbox[4] * bpfactor,
+ }
+ end
+ xobject = xobject + specification.attr
+ if bbox and not specification.width then
+ specification.width = bbox[3]
+ end
+ if bbox and not specification.height then
+ specification.height = bbox[4]
+ end
+ local dict = xobject()
+ --
+ nofobjects = nofobjects + 1
+ local objnum = nofobjects
+ local nolength = specification.nolength
+ local stream = specification.stream or specification.string
+ --
+ -- We cannot set type in native img so we need this hack or
+ -- otherwise we need to patch too much. Better that i write
+ -- a wrapper then. Anyway, it has to be done better: a key that
+ -- tells either or not to scale by xsize/ysize when flushing.
+ --
+ if not specification.type then
+ local kind = specification.kind
+ if kind then
+ -- take that one
+ elseif attr and find(attr,"BBox") then
+ kind = img_stream
+ else
+ -- hack: a bitmap
+ kind = img_none
+ end
+ specification.type = kind
+ specification.kind = kind
+ end
+ local compress = compresslevel and compresslevel > 0 or nil
+ flushstreamobj(stream,objnum,dict,compress,nolength)
+ specification.objnum = objnum
+ specification.rotation = specification.rotation or 0
+ specification.orientation = specification.orientation or 0
+ specification.transform = specification.transform or 0
+ specification.stream = nil
+ specification.attr = nil
+ specification.type = specification.kind or specification.type or img_none
+ indices[index] = specification -- better create a real specification
+ return specification
+ end
end
codeinjections.embedimage = embedimage
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua
index b8648b32a..8e0a45a00 100644
--- a/tex/context/base/mkiv/lpdf-wid.lua
+++ b/tex/context/base/mkiv/lpdf-wid.lua
@@ -252,20 +252,25 @@ job.register('job.fileobjreferences.collected', tobesavedobjrefs, initializer)
local function flushembeddedfiles()
if enabled and next(filestreams) then
local e = pdfarray()
+ local f = pdfarray()
for tag, reference in sortedhash(filestreams) do
if not reference then
report_attachment("unreferenced file, tag %a",tag)
--- elseif referenced[tag] == "hidden" then
- elseif referenced[tag] ~= "hidden" then
+ elseif referenced[tag] == "hidden" then
e[#e+1] = pdfstring(tag)
e[#e+1] = reference -- already a reference
+ f[#f+1] = reference -- collect all file description references
else
- -- -- messy spec ... when annot not in named else twice in menu list acrobat
+ -- messy spec ... when annot not in named else twice in menu list acrobat
+ f[#f+1] = reference
end
end
if #e > 0 then
lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e })))
end
+ if #f > 0 then -- PDF/A-2|3: all associated files must have a relationship to the PDF document (global or part)
+ lpdf.addtocatalog("AF", pdfreference(pdfflushobject(f))) -- global (Catalog)
+ end
end
end
@@ -430,6 +435,7 @@ function nodeinjections.attachfile(specification)
else
referenced[hash] = "annotation"
local name, appearance = analyzesymbol(specification.symbol,attachment_symbols)
+ local flags = specification.flags or 0 -- to keep it expandable
local d = pdfdictionary {
Subtype = pdfconstant("FileAttachment"),
FS = aref,
@@ -442,7 +448,8 @@ function nodeinjections.attachfile(specification)
CA = analyzetransparency(specification.transparencyvalue),
AP = appearance,
OC = analyzelayer(specification.layer),
- F = pdfnull(), -- another rediculous need to satisfy validation
+ -- F = pdfnull(), -- another rediculous need to satisfy validation
+ F = (flags | 4) & (1023-1-2-32-256), -- set 3, clear 1,2,6,9; PDF 32000-1, p385
}
local width = specification.width or 0
local height = specification.height or 0
@@ -534,7 +541,6 @@ function nodeinjections.comment(specification) -- brrr: seems to be done twice
Name = name,
NM = pdfstring("comment:"..nofcomments),
AP = appearance,
- F = pdfnull(), -- another rediculous need to satisfy validation
}
local width = specification.width or 0
local height = specification.height or 0
diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua
index 51eab5a1d..3125495b4 100644
--- a/tex/context/base/mkiv/luat-cod.lua
+++ b/tex/context/base/mkiv/luat-cod.lua
@@ -137,10 +137,8 @@ if LUATEXENGINE == nil then
end
if LUATEXVERSION == nil then
- LUATEXVERSION = status.luatex_revision
LUATEXVERSION = status.luatex_version/100
- -- + tonumber(LUATEXVERSION)/1000
- + (tonumber(LUATEXVERSION) or (string.byte(LUATEXVERSION)-string.byte("a")+10))/1000
+ + tonumber(status.luatex_revision)/10000
end
if CONTEXTLMTXMODE == nil then
diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua
index 332980013..cec0161e7 100644
--- a/tex/context/base/mkiv/luat-ini.lua
+++ b/tex/context/base/mkiv/luat-ini.lua
@@ -26,7 +26,7 @@ if not global then
end
LUATEXVERSION = status.luatex_version/100
- + tonumber(status.luatex_revision)/1000
+ + tonumber(status.luatex_revision)/10000
LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex")
diff --git a/tex/context/base/mkiv/luat-lib.mkiv b/tex/context/base/mkiv/luat-lib.mkiv
index c3bbd8e19..0ffd1dd40 100644
--- a/tex/context/base/mkiv/luat-lib.mkiv
+++ b/tex/context/base/mkiv/luat-lib.mkiv
@@ -73,9 +73,9 @@
\registerctxluafile{data-use}{}
\registerctxluafile{data-aux}{}
-\ifcase\contextlmtxmode
- \registerctxluafile{util-lib}{}
-\fi
+% \ifcase\contextlmtxmode
+% \registerctxluafile{util-lib}{}
+% \fi
\registerctxluafile{luat-cbk}{}
\registerctxluafile{luat-run}{}
diff --git a/tex/context/base/mkiv/m-gnuplot.mkxl b/tex/context/base/mkiv/m-gnuplot.mkxl
new file mode 100644
index 000000000..2077b1741
--- /dev/null
+++ b/tex/context/base/mkiv/m-gnuplot.mkxl
@@ -0,0 +1,97 @@
+%D \module
+%D [ file=m-gnuplot,
+%D version=2020.02.10,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Gnuplot,
+%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.
+
+%D This is a variant on the \GNUPLOT\ terminal code. At some point (when there is a
+%D reason) I will make a proper environment that can be used for embedded code.
+
+\unexpanded\def\includegnuplotsvgfile[#1]%
+ {\hbox\bgroup
+ \ctxlua{metapost.startsvghashing()}%
+ \includesvgfile[#1]%
+ \ctxlua{metapost.stopsvghashing()}%
+ \egroup}
+
+\startluacode
+
+local modificationtime = lfs.modification
+local longtostring = string.longtostring
+local formatters = string.formatters
+local expandfilename = dir.expandname
+local isfile = lfs.isfile
+
+local runner = sandbox.registerrunner {
+ name = "gnuplot to svg",
+ program = "gnuplot",
+ template = longtostring [[
+ -e "set output '%newname%'; set terminal svg"
+ "%oldname%"
+ ]],
+ checkers = {
+ oldname = "readable",
+ newname = "writable",
+ },
+}
+
+figures.programs.gnuplot = {
+ runner = runner,
+}
+
+local function remap(specification)
+ local oldname = specification.fullname
+ if oldname then
+ local newname = file.replacesuffix(oldname,"svg")
+ local oldtime = modificationtime(oldname) or 0
+ local newtime = modificationtime(newname) or 0
+ if newtime == 0 or oldtime > newtime then
+ runner {
+ newname = expandfilename(newname),
+ oldname = expandfilename(oldname),
+ }
+ end
+ if isfile(newname) then
+ local only = file.nameonly(newname)
+ local name = formatters["svg-%s-inclusion"](only)
+ local code = formatters["\\includegnuplotsvgfile[%s]\\resetbuffer[%s]"](newname,name)
+ buffers.assign(name,code)
+ specification.format = "buffer"
+ specification.fullname = name
+ end
+ end
+ return specification
+end
+
+figures.remappers.gp = { svg = remap }
+
+\stopluacode
+
+\continueifinputfile{m-gnuplot.mkxl}
+
+\startluacode
+io.savedata("m-gnuplot-demo.gp", [[
+set format xy "$%g$"
+
+set title 'This is a plot of $y=\\sin(x)$'
+set xlabel 'This is the $x$ axis'
+set ylabel 'This is the $y$ axis'
+
+plot [0:6.28] [0:1] sin(x)
+]])
+\stopluacode
+
+\starttext
+
+ \externalfigure[m-gnuplot-demo.gp][conversion=svg,width=4cm]
+
+ \externalfigure[m-gnuplot-demo.gp][conversion=svg,width=8cm]
+
+\stoptext
diff --git a/tex/context/base/mkiv/m-zint.mkxl b/tex/context/base/mkiv/m-zint.mkxl
deleted file mode 100644
index 7135126ba..000000000
--- a/tex/context/base/mkiv/m-zint.mkxl
+++ /dev/null
@@ -1,7 +0,0 @@
-% this is a stub:
-
-% \uselibrary[zint]
-
-\input libs-imp-zint.mkxl
-
-\endinput
diff --git a/tex/context/base/mkiv/meta-imp-threesix.mkxl b/tex/context/base/mkiv/meta-imp-threesix.mkxl
new file mode 100644
index 000000000..277aa85f7
--- /dev/null
+++ b/tex/context/base/mkiv/meta-imp-threesix.mkxl
@@ -0,0 +1,253 @@
+% not yet a module
+
+\startluacode
+ local gsub, utfbyte = string.gsub, utf.byte
+
+ -- The font from DEK's facs9b.ps (I wish I was clever enough to understand all the good
+ -- stuff in there):
+
+ local font36 = {
+ ["0"] = [[00111100 01111110 11000011 11000011 11000011 11000011 01111110 00111100]],
+ ["1"] = [[00011100 11111100 11101100 00001100 00001100 00001100 11111111 11111111]],
+ ["2"] = [[00111110 01110011 01110011 00000011 00001110 00111000 11110001 11111111]],
+ ["3"] = [[01111110 01100110 00000110 00111100 00000110 11100111 11100111 01111110]],
+ ["4"] = [[00001110 00011110 00110110 01100110 11111111 11111111 00000110 00001110]],
+ ["5"] = [[01111110 01111110 01000000 01111100 01000111 00000011 11000111 11111110]],
+ ["6"] = [[01111110 01100110 11000000 11011100 11100110 11000011 01100011 01111110]],
+ ["7"] = [[11111111 11111111 10000111 10001110 00011100 00011100 00011100 00011100]],
+ ["8"] = [[01111110 01100110 01100110 00111100 11000011 11000011 11000011 01111110]],
+ ["9"] = [[01111110 11000110 11000011 01100111 00111011 00000011 01100110 01111110]],
+ ["A"] = [[000110000 000111000 001111100 001101100 011001110 011111110 010000110 111100111]],
+ ["B"] = [[1111100 1110110 0110110 0111100 0110011 0110011 1110011 1111100]],
+ ["C"] = [[01111101 11110011 11100001 11100001 11100000 11100000 11100001 01111110]],
+ ["D"] = [[11111100 11100010 01100011 01100011 01100011 01100011 11100010 11111100]],
+ ["E"] = [[1111111 1110001 0110101 0111100 0110100 0110001 1110001 1111111]],
+ ["F"] = [[11111111 11100001 01100101 01111100 01100100 01100000 11111000 11111000]],
+ ["G"] = [[01111010 11100110 11100010 11100000 11100111 11100010 11100010 01111100]],
+ ["H"] = [[11100111 11100111 01000010 01111110 01000010 01000010 11100111 11100111]],
+ ["I"] = [[1111111 1111111 0011000 0011000 0011000 0011000 1111111 1111111]],
+ ["J"] = [[01111111 01111111 00000110 00000110 11110110 01100110 01100110 00111100]],
+ ["K"] = [[11101110 11100100 01101000 01110000 01111000 01101100 11100110 11101111]],
+ ["L"] = [[111111000 111111000 011000000 011000000 011000000 011000011 111000011 111111111]],
+ ["M"] = [[1100000011 1110000111 0111111110 0100110010 0100110010 0100000010 1100000011 1100000011]],
+ ["N"] = [[11000011 11100011 01110010 01111010 01011110 01001110 11100110 11100010]],
+ ["O"] = [[01111110 11000011 11000011 11000011 11000011 11000011 11000011 01111110]],
+ ["P"] = [[11111110 11100011 01100011 01111110 01100000 01100000 11111000 11111000]],
+ ["Q"] = [[01111100 11000110 11000110 11000110 11000110 11001110 11000110 01111101]],
+ ["R"] = [[11111100 11100110 01100110 01111100 01101000 01100100 11100010 11100111]],
+ ["S"] = [[01111110 11100001 11100001 01111000 00011110 10000111 11000011 10111110]],
+ ["T"] = [[1111111111 1100110011 1100110011 0000110000 0000110000 0000110000 0001111000 0001111000]],
+ ["U"] = [[111101111 111101111 011000010 011000010 011000010 011000010 011000010 001111100]],
+ ["V"] = [[11111000111 11111000111 01110000010 00110000100 00111000100 00011001000 00001101000 00001110000]],
+ ["W"] = [[111000000111 111000000111 110000000010 011000000100 011001000100 001101101000 001101101000 000110110000]],
+ ["X"] = [[1111001110 1111000110 0001101000 0000110000 0000110000 0001011000 0110001111 0111001111]],
+ ["Y"] = [[111100011 111100011 011000010 001110100 000111000 000011000 001111110 001111110]],
+ ["Z"] = [[11111111 10000111 00001110 00011100 00111000 01110000 11100001 11111111]],
+ }
+
+ local f_code = string.formatters["ThreeSix(%s);"]
+ local replace = { ["0"] = "N;", ["1"] = "Y;", [" "] = "L;" }
+
+ local function remap(str)
+ -- permit abundant spacing (bonus)
+ str = gsub(str,"%s+", " ")
+ -- remap what we got to macro calls
+ str = gsub(str,".",replace)
+ -- return the result
+ return str
+ end
+
+ function MP.registerthreesix(name)
+ fonts.dropins.registerglyphs {
+ name = name,
+ units = 12,
+ usecolor = true,
+ preamble = "InitializeThreeSix;",
+ }
+ for u, v in table.sortedhash(font36) do
+ local ny = 8
+ local nx = (#v - ny + 1) // ny
+ local height = ny * 1.1 - 0.1
+ local width = nx * 1.1 - 0.1
+ fonts.dropins.registerglyph {
+ category = name,
+ unicode = utfbyte(u),
+ width = width,
+ height = height,
+ code = f_code(remap(v)),
+ }
+ end
+ end
+
+ MP.registerthreesix("fontthreesix")
+\stopluacode
+
+% \startMPcalculation{simplefun}
+% def InitializeThreeSix =
+% save Y, N, L, S ; save dx, dy, nx, ny ;
+% save shape, fillcolor, mypen, random, currentpen, spread, hoffset ;
+% string shape, fillcolor, mypen ; boolean random ; pen currentpen ;
+% dx := 11/10 ;
+% dy := - 11/10 ;
+% nx := - dx ;
+% ny := 0 ;
+% shape := getparameterdefault "mpsfont" "shape" "circle" ;
+% random := hasoption "mpsfont" "random" "true" ;
+% fillcolor := getparameterdefault "mpsfont" "color" "" ;
+% mypen := getparameterdefault "mpsfont" "pen" "" ;
+% spread := getparameterdefault "mpsfont" "spread" 0 ;
+% hoffset := 12 * spread / 2 ;
+% currentpen := pencircle
+% if mypen = "fancy" :
+% xscaled 1/20 yscaled 2/20 rotated 45
+% else :
+% scaled 1/20
+% fi ;
+% if shape == "square" :
+% def S =
+% unitsquare if random : randomized 1/10 fi
+% shifted (nx,ny)
+% enddef ;
+% elseif shape = "diamond" :
+% def S =
+% unitdiamond if random : randomized 1/10 fi
+% shifted (nx,ny)
+% enddef ;
+% else :
+% def S =
+% unitcircle if random : randomizedcontrols 1/20 fi
+% shifted (nx,ny)
+% enddef ;
+% fi ;
+% def N =
+% nx := nx + dx ;
+% draw S ;
+% enddef ;
+% if fillcolor = "random" :
+% def Y =
+% nx := nx + dx ;
+% fillup S withcolor white randomized (2/3,2/3,2/3) ;
+% enddef ;
+% elseif fillcolor = "" :
+% def Y =
+% nx := nx + dx ;
+% fillup S ;
+% enddef ;
+% else :
+% def Y =
+% nx := nx + dx ;
+% fillup S withcolor fillcolor ;
+% enddef ;
+% fi ;
+% def L =
+% nx := - dx ;
+% ny := ny + dy ;
+% enddef ;
+% enddef ;
+%
+% vardef ThreeSix (text code) =
+% InitializeThreeSix ;
+% draw image (code) shifted (hoffset,-ny) ;
+% enddef ;
+% \stopMPcalculation
+
+\startMPcalculation{simplefun}
+ def InitializeThreeSix =
+ save Y, N, L, S ;
+ % save dx, dy, nx, ny ;
+ save shape, fillcolor, mypen, random, threesixpen, spread, hoffset ;
+ string shape, fillcolor, mypen ; boolean random ; pen threesixpen ;
+ % dx := 11/10 ;
+ % dy := - 11/10 ;
+ % nx := - dx ;
+ % ny := 0 ;
+ shape := getparameterdefault "mpsfont" "shape" "circle" ;
+ random := hasoption "mpsfont" "random" "true" ;
+ fillcolor := getparameterdefault "mpsfont" "color" "" ;
+ mypen := getparameterdefault "mpsfont" "pen" "" ;
+ spread := getparameterdefault "mpsfont" "spread" 0 ;
+ hoffset := 12 * spread / 2 ;
+ threesixpen := pencircle
+ if mypen = "fancy" :
+ xscaled 1/20 yscaled 2/20 rotated 45
+ else :
+ scaled 1/20
+ fi ;
+ if shape == "square" :
+ def S =
+ unitsquare if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ elseif shape = "diamond" :
+ def S =
+ unitdiamond if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ else :
+ def S =
+ unitcircle if random : randomizedcontrols 1/20 fi
+ shifted (nx,ny)
+ enddef ;
+ fi ;
+ def N =
+ nx := nx + dx ;
+ draw S ;
+ enddef ;
+ if fillcolor = "random" :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor white randomized (2/3,2/3,2/3) ;
+ enddef ;
+ elseif fillcolor = "" :
+ def Y =
+ nx := nx + dx ;
+ fillup S ;
+ enddef ;
+ else :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor fillcolor ;
+ enddef ;
+ fi ;
+ def L =
+ nx := - dx ;
+ ny := ny + dy ;
+ enddef ;
+ enddef ;
+
+ vardef ThreeSix (text code) =
+ save dx, dy, nx, ny ;
+ dx := 11/10 ;
+ dy := - 11/10 ;
+ nx := - dx ;
+ ny := 0 ;
+ pickup threesixpen ;
+ draw image (code) shifted (hoffset,-ny) ;
+ enddef ;
+\stopMPcalculation
+
+\definefontfeature % black and white, with some spread
+ [fontthreesix]
+ [default]
+ [metapost=fontthreesix]
+
+\definefontfeature % color, with some spread
+ [fontthreesix-tweak]
+ [default]
+ [metapost={category=fontthreesix,spread=.1}]
+
+\definefontfeature % color, with some spread
+ [fontthreesix-color]
+ [default]
+ [metapost={category=fontthreesix,shape=diamond,color=random,pen=fancy,spread=.1}]
+
+\definefontfeature % color, tight
+ [fontthreesix-initial]
+ [metapost={category=fontthreesix,color=random,shape=circle}] % units?
+
+\definefont[DEKFontA][Serif*fontthreesix]
+\definefont[DEKFontB][Serif*fontthreesix-color]
+\definefont[DEKFontC][Serif*fontthreesix-initial]
+\definefont[DEKFontD][Serif*fontthreesix-tweak]
+
+\endinput
diff --git a/tex/context/base/mkiv/meta-tex.mkiv b/tex/context/base/mkiv/meta-tex.mkiv
index 418ddc196..c580596f7 100644
--- a/tex/context/base/mkiv/meta-tex.mkiv
+++ b/tex/context/base/mkiv/meta-tex.mkiv
@@ -236,4 +236,7 @@
\unexpanded\def\svgsetlayer#1#2%
{\setlayer[svgmps][\c!x=#1\onebasepoint,\c!y=#2\onebasepoint]} % {#3}
+\unexpanded\def\svghashed#1%
+ {\clf_svghashed#1\relax}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/mlib-svg.lua b/tex/context/base/mkiv/mlib-svg.lua
index b56c1fd54..f4b3117a6 100644
--- a/tex/context/base/mkiv/mlib-svg.lua
+++ b/tex/context/base/mkiv/mlib-svg.lua
@@ -75,24 +75,21 @@ if not modules then modules = { } end modules ['mlib-svg'] = {
-- One can run into pretty crazy images, like lines that are fills being clipped
-- to some width. That's the danger of hiding yourself behind an interface I guess.
-local rawget, type, tonumber, tostring, next, setmetatable = rawget, type, tonumber, tostring, next, setmetatable
+local rawget, rawset, type, tonumber, tostring, next, setmetatable = rawget, rawset, type, tonumber, tostring, next, setmetatable
-local P, S, R, C, Ct, Cs, Cc, Cp, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Carg
+local P, S, R, C, Ct, Cs, Cc, Cp, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Cg, lpeg.Cf, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local pi, sin, cos, asin, sind, cosd, tan, abs, sqrt = math.pi, math.sin, math.cos, math.asin, math.sind, math.cosd, math.tan, math.abs, math.sqrt
+local sqrt = math.sqrt
local concat, setmetatableindex, sortedhash = table.concat, table.setmetatableindex, table.sortedhash
local gmatch, gsub, find, match, rep = string.gmatch, string.gsub, string.find, string.match, string.rep
local formatters, fullstrip = string.formatters, string.fullstrip
-local extract = bit32.extract
local utfsplit, utfbyte = utf.split, utf.byte
local xmlconvert, xmlcollected, xmlcount, xmlfirst, xmlroot = xml.convert, xml.collected, xml.count, xml.first, xml.root
local xmltext, xmltextonly = xml.text, xml.textonly
local css = xml.css or { } -- testing
-local bpfactor = number.dimenfactors.bp
-
local function xmlinheritattributes(c,pa)
local at = c.at
local dt = c.dt
@@ -134,6 +131,47 @@ local pathtracer = {
["fill-opacity"] = ".75",
}
+-- This is just an experiment. Todo: reset hash etc. Also implement
+-- an option handler.
+
+local svghash = false do
+
+ local svglast = 0
+ local svglist = false
+
+ local function checkhash(t,k)
+ local n = svglast + 1
+ svglast = n
+ svglist[n] = k
+ t[k] = n
+ return n
+ end
+
+ function metapost.startsvghashing()
+ svglast = 0
+ svglist = { }
+ svghash = setmetatableindex(checkhash)
+ end
+
+ function metapost.stopsvghashing()
+ svglast = 0
+ svglist = false
+ svghash = false
+ end
+
+ interfaces.implement {
+ name = "svghashed",
+ arguments = "integer",
+ actions = function(n)
+ local t = svglist and svglist[n]
+ if t then
+ context(t)
+ end
+ end
+ }
+
+end
+
-- We have quite some closures because otherwise we run into the local variable
-- limitations. It doesn't always look pretty now, sorry. I'll clean up this mess
-- some day (the usual nth iteration of code).
@@ -149,6 +187,8 @@ local pathtracer = {
local a2c do
+ local pi, sin, cos, tan, asin, abs = math.pi, math.sin, math.cos, math.tan, math.asin, math.abs
+
local d120 = (pi * 120) / 180
local pi2 = 2 * pi
@@ -401,6 +441,8 @@ local rgbcomponents, withcolor, thecolor do
local f_svggray = formatters['svggray(%.3N)']
local f_svgname = formatters['"%s"']
+ local extract = bit32.extract
+
local triplets = setmetatableindex(function(t,k)
-- we delay building all these strings
local v = svgcolors[k]
@@ -971,6 +1013,8 @@ local f_wrapped_stop = formatters[") shifted (0,%N) scaled %N ;"]
local handletransform, handleviewbox do
+ local sind = math.sind
+
--todo: better lpeg
local f_rotatedaround = formatters[" rotatedaround((%N,%N),%N)"]
@@ -1017,7 +1061,7 @@ local handletransform, handleviewbox do
local function skewx(x)
if x then
- return f_slanted_x(math.sind(-x))
+ return f_slanted_x(sind(-x))
else
return ""
end
@@ -1025,7 +1069,7 @@ local handletransform, handleviewbox do
local function skewy(y)
if y then
- return f_slanted_y(math.sind(-y))
+ return f_slanted_y(sind(-y))
else
return ""
end
@@ -1035,24 +1079,34 @@ local handletransform, handleviewbox do
return f_matrix(rx or 1, sx or 0, sy or 0, ry or 1, tx or 0, - (ty or 0))
end
- -- how to deal with units here?
+ -- How to deal with units here? Anyway, order seems to matter.
- local p_transform = Cs ( (
- P("translate") * p_numbers / translate -- maybe xy
- + P("scale") * p_numbers / scale
- + P("rotate") * p_numbers / rotate
- + P("matrix") * p_numbers / matrix
- + P("skewX") * p_numbers / skewx
- + P("skewY") * p_numbers / skewy
- -- + p_separator
- + P(1)/""
- )^1)
+ local p_transform = Cf ( Ct("") * (
+ lpegpatterns.whitespace^0 * Cg(
+ C("translate") * (p_numbers / translate) -- maybe xy
+ + C("scale") * (p_numbers / scale)
+ + C("rotate") * (p_numbers / rotate)
+ + C("matrix") * (p_numbers / matrix)
+ + C("skewX") * (p_numbers / skewx)
+ + C("skewY") * (p_numbers / skewy)
+ )
+ )^1, rawset)
handletransform = function(at)
local t = at.transform
if t then
local e = lpegmatch(p_transform,t)
- return s_transform_start, f_transform_stop(e), t
+ if e then
+ e = concat({
+ e.rotate or "",
+ e.skewX or "",
+ e.skewY or "",
+ e.scale or "",
+ e.translate or "",
+ e.matrix or "",
+ }, " ")
+ return s_transform_start, f_transform_stop(e), t
+ end
end
end
@@ -2340,6 +2394,7 @@ do
local f_scaled = formatters["\\svgscaled{%N}{%s}{%s}{%s}"]
local f_normal = formatters["\\svgnormal{%s}{%s}{%s}"]
+ local f_hashed = formatters["\\svghashed{%s}"]
-- We move to the outer (x,y) and when we have an inner offset we
-- (need to) compensate for that outer offset.
@@ -2348,8 +2403,14 @@ do
-- local f_text_normal_svg = formatters['(svgtext("%s") shifted (%N,%N))']
-- local f_text_simple_svg = formatters['svgtext("%s")']
- local f_text_normal_svg = formatters['(textext.drt("%s") shifted (%N,%N))']
- local f_text_simple_svg = formatters['textext.drt("%s")']
+ local anchors = {
+ ["start"] = "drt",
+ ["end"] = "dflt",
+ ["middle"] = "d",
+ }
+
+ local f_text_normal_svg = formatters['(textext.%s("%s") shifted (%N,%N))']
+ local f_text_simple_svg = formatters['textext.%s("%s")']
-- or just maptext
@@ -2480,7 +2541,9 @@ do
di = gsub(di,"%s+$","")
end
local chars = utfsplit(di)
- if tx then
+ if svghash then
+ di = f_hashed(svghash[di])
+ elseif tx then
for i=1,#chars do
chars[i] = f_poschar(
(tx[i] or 0) - x,
@@ -2540,6 +2603,7 @@ do
v_fill = "black"
end
local color, opacity, invisible = fillproperties(v_fill,at)
+ local anchor = anchors[at["text-anchor"] or "start"] or "drt"
local r = metapost.remappedtext(only)
if r then
if x == 0 and y == 0 then
@@ -2567,9 +2631,9 @@ do
result[#result+1] = s_stoplayer
result = concat(result)
if x == 0 and y == 0 then
- result = f_text_simple_svg(result)
+ result = f_text_simple_svg(anchor,result)
else
- result = f_text_normal_svg(result,x,y)
+ result = f_text_normal_svg(anchor,result,x,y)
end
flushobject(result,at,color,opacity)
if trace_text then
@@ -2741,7 +2805,7 @@ do
definitions = { }
tagstyles = { }
classstyles = { }
- for s in xmlcollected(c,"/style") do
+ for s in xmlcollected(c,"style") do -- can also be in a def, so let's play safe
handlestyle(c)
end
handlechains(c)
@@ -2777,101 +2841,107 @@ end
-- a bit more efficient, because we now go to mp and back which is kind of redundant,
-- but for now it will do.
-function metapost.includesvgfile(filename,offset) -- offset in sp
- if lfs.isfile(filename) then
+do
+
+ local bpfactor = number.dimenfactors.bp
+
+ function metapost.includesvgfile(filename,offset) -- offset in sp
+ if lfs.isfile(filename) then
+ context.startMPcode("doublefun")
+ context('draw lmt_svg [ filename = "%s", offset = %N ] ;',filename,(offset or 0)*bpfactor)
+ context.stopMPcode()
+ end
+ end
+
+ function metapost.includesvgbuffer(name,offset) -- offset in sp
context.startMPcode("doublefun")
- context('draw lmt_svg [ filename = "%s", offset = %N ] ;',filename,(offset or 0)*bpfactor)
+ context('draw lmt_svg [ buffer = "%s", offset = %N ] ;',name or "",(offset or 0)*bpfactor)
context.stopMPcode()
end
-end
-
-function metapost.includesvgbuffer(name,offset) -- offset in sp
- context.startMPcode("doublefun")
- context('draw lmt_svg [ buffer = "%s", offset = %N ] ;',name or "",(offset or 0)*bpfactor)
- context.stopMPcode()
-end
-interfaces.implement {
- name = "includesvgfile",
- actions = metapost.includesvgfile,
- arguments = { "string", "dimension" },
-}
+ interfaces.implement {
+ name = "includesvgfile",
+ actions = metapost.includesvgfile,
+ arguments = { "string", "dimension" },
+ }
-interfaces.implement {
- name = "includesvgbuffer",
- actions = metapost.includesvgbuffer,
- arguments = { "string", "dimension" },
-}
+ interfaces.implement {
+ name = "includesvgbuffer",
+ actions = metapost.includesvgbuffer,
+ arguments = { "string", "dimension" },
+ }
-function metapost.showsvgpage(data)
- local dd = data.data
- if not dd then
- local fn = data.filename
- dd = fn and table.load(fn)
- end
- if type(dd) == "table" then
- local comment = data.comment
- local offset = data.pageoffset
- local index = data.index
- local first = math.max(index or 1,1)
- local last = math.min(index or #dd,#dd)
- for i=first,last do
- local d = setmetatableindex( {
- data = dd[i],
- comment = comment and i or false,
- pageoffset = offset or nil,
- }, data)
- metapost.showsvgpage(d)
- end
- elseif data.method == "code" then
- context.startMPcode(doublefun)
- context(metapost.svgtomp(data))
- context.stopMPcode()
- else
- context.startMPpage { instance = "doublefun", offset = data.pageoffset or nil }
- context(metapost.svgtomp(data))
+ function metapost.showsvgpage(data)
+ local dd = data.data
+ if not dd then
+ local fn = data.filename
+ dd = fn and table.load(fn)
+ end
+ if type(dd) == "table" then
local comment = data.comment
- if comment then
- context("draw boundingbox currentpicture withcolor .6red ;")
- context('draw textext.bot("\\strut\\tttf %s") ysized (10pt) shifted center bottomboundary currentpicture ;',comment)
- end
- context.stopMPpage()
- end
-end
-
-function metapost.typesvgpage(data)
- local dd = data.data
- if not dd then
- local fn = data.filename
- dd = fn and table.load(fn)
- end
- if type(dd) == "table" then
- local index = data.index
- if index and index > 0 and index <= #dd then
- data = dd[index]
+ local offset = data.pageoffset
+ local index = data.index
+ local first = math.max(index or 1,1)
+ local last = math.min(index or #dd,#dd)
+ for i=first,last do
+ local d = setmetatableindex( {
+ data = dd[i],
+ comment = comment and i or false,
+ pageoffset = offset or nil,
+ }, data)
+ metapost.showsvgpage(d)
+ end
+ elseif data.method == "code" then
+ context.startMPcode(doublefun)
+ context(metapost.svgtomp(data))
+ context.stopMPcode()
else
- data = nil
+ context.startMPpage { instance = "doublefun", offset = data.pageoffset or nil }
+ context(metapost.svgtomp(data))
+ local comment = data.comment
+ if comment then
+ context("draw boundingbox currentpicture withcolor .6red ;")
+ context('draw textext.bot("\\strut\\tttf %s") ysized (10pt) shifted center bottomboundary currentpicture ;',comment)
+ end
+ context.stopMPpage()
end
end
- if type(data) == "string" and data ~= "" then
- buffers.assign("svgpage",data)
- context.typebuffer ({ "svgpage" }, { option = "XML", strip = "yes" })
+
+ function metapost.typesvgpage(data)
+ local dd = data.data
+ if not dd then
+ local fn = data.filename
+ dd = fn and table.load(fn)
+ end
+ if type(dd) == "table" then
+ local index = data.index
+ if index and index > 0 and index <= #dd then
+ data = dd[index]
+ else
+ data = nil
+ end
+ end
+ if type(data) == "string" and data ~= "" then
+ buffers.assign("svgpage",data)
+ context.typebuffer ({ "svgpage" }, { option = "XML", strip = "yes" })
+ end
end
-end
-function metapost.svgtopdf(data,...)
- local mps = metapost.svgtomp(data,...)
- if mps then
- -- todo: special instance, only basics needed
- local pdf = metapost.simple("metafun",mps,true,false,"svg")
- if pdf then
- return pdf
+ function metapost.svgtopdf(data,...)
+ local mps = metapost.svgtomp(data,...)
+ if mps then
+ -- todo: special instance, only basics needed
+ local pdf = metapost.simple("metafun",mps,true,false,"svg")
+ if pdf then
+ return pdf
+ else
+ -- message
+ end
else
-- message
end
- else
- -- message
end
+
end
do
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b7c571975..e5fe90ad2 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 453fc01db..ac49b2139 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua
index d2b1e9768..2ff87e21a 100644
--- a/tex/context/base/mkiv/tabl-xtb.lua
+++ b/tex/context/base/mkiv/tabl-xtb.lua
@@ -478,36 +478,50 @@ end
function xtables.initialize_construct()
local r = data.currentrow
local c = data.currentcolumn + 1
+ local settings = data.settings
local rows = data.rows
local row = rows[r]
while row[c].span do -- can also be previous row ones
c = c + 1
end
data.currentcolumn = c
- local widths = data.widths
- local heights = data.heights
- local depths = data.depths
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ local distances = data.distances
--
local drc = row[c]
local wd = drc.wd
local ht = drc.ht
local dp = drc.dp
+ local nx = drc.nx - 1
+ local ny = drc.ny - 1
--
local width = widths[c]
local height = heights[r]
local depth = depths[r] -- problem: can be the depth of a one liner
--
- for x=1,drc.nx-1 do
- width = width + widths[c+x]
+ local total = height + depth
+ --
+ if nx > 0 then
+ for x=1,nx do
+ width = width + widths[c+x] + distances[c+x-1]
+ end
+ local distance = settings.columndistance
+ if distance ~= 0 then
+ width = width + nx * distance
+ end
end
--
- local total = height + depth
- local ny = drc.ny
- if ny > 1 then
- for y=1,ny-1 do
+ if ny > 0 then
+ for y=1,ny do
local nxt = r + y
total = total + heights[nxt] + depths[nxt]
end
+ local distance = settings.rowdistance
+ if distance ~= 0 then
+ total = total + ny * distance
+ end
end
--
texsetdimen("d_tabl_x_width",width)
diff --git a/tex/context/base/mkiv/util-pck.lua b/tex/context/base/mkiv/util-pck.lua
index b90853fb6..6af53f9eb 100644
--- a/tex/context/base/mkiv/util-pck.lua
+++ b/tex/context/base/mkiv/util-pck.lua
@@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['util-pck'] = {
local next, tostring, type = next, tostring, type
local sort, concat = table.sort, table.concat
+local format = string.format
local sortedhashkeys, sortedkeys, tohash = table.sortedhashkeys, table.sortedkeys, table.tohash
utilities = utilities or { }
@@ -17,14 +18,17 @@ utilities.packers = utilities.packers or { }
local packers = utilities.packers
packers.version = 1.01
+local fmt_kv = JITSUPPORTED and "%s=%s" or "%s=%q"
+local fmt_kt = JITSUPPORTED and "%s={%s}" or "%s={%q}"
+
local function hashed(t)
local s, ns = { }, 0
for k, v in next, t do
ns = ns + 1
if type(v) == "table" then
- s[ns] = k .. "={" .. hashed(v) .. "}"
+ s[ns] = format(fmt_kt,k,hashed(v))
else
- s[ns] = k .. "=" .. tostring(v)
+ s[ns] = format(fmt_kv,k,v)
end
end
sort(s)
@@ -35,7 +39,7 @@ local function simplehashed(t)
local s, ns = { }, 0
for k, v in next, t do
ns = ns + 1
- s[ns] = k .. "=" .. v
+ s[ns] = format(fmt_kv,k,v)
end
sort(s)
return concat(s,",")
diff --git a/tex/context/base/mkiv/util-sql.lua b/tex/context/base/mkiv/util-sql.lua
index 61f1f19fa..36f3eab19 100644
--- a/tex/context/base/mkiv/util-sql.lua
+++ b/tex/context/base/mkiv/util-sql.lua
@@ -116,12 +116,12 @@ if optional then
library = "mysql",
swiglib = "mysql",
postgress = "postgress",
- sqlite = "sqlite"
- sqlite3 = "sqlite"
+ sqlite = "sqlite",
+ sqlite3 = "sqlite",
}
setmetatableindex(sql.methods,function(t,k)
- local m = methods[k
+ local m = methods[k]
if m then
report_state("start loading method %a as %a",k,m)
require("libs-imp-" .. m)
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index 68c9be586..4d23f88b7 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -701,14 +701,18 @@ local format_left = function(f)
end
end
-local format_q = function()
+local format_q = JITSUPPORTED and function()
n = n + 1
-- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
-- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
-- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end or function()
+ n = n + 1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
+
local format_Q = function() -- fast escaping
n = n + 1
-- return format("format('%%q',tostring(a%s))",n)
diff --git a/tex/context/base/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua
index 410292ca8..4dafb2acd 100644
--- a/tex/context/base/mkiv/util-tab.lua
+++ b/tex/context/base/mkiv/util-tab.lua
@@ -314,102 +314,177 @@ end
-- best keep [%q] keys (as we have some in older applications i.e. saving user data (otherwise
-- we also need to check for reserved words)
-local f_hashed_string = formatters["[%Q]=%Q,"]
-local f_hashed_number = formatters["[%Q]=%s,"]
-local f_hashed_boolean = formatters["[%Q]=%l,"]
-local f_hashed_table = formatters["[%Q]="]
-
-local f_indexed_string = formatters["[%s]=%Q,"]
-local f_indexed_number = formatters["[%s]=%s,"]
-local f_indexed_boolean = formatters["[%s]=%l,"]
-local f_indexed_table = formatters["[%s]="]
-
-local f_ordered_string = formatters["%Q,"]
-local f_ordered_number = formatters["%s,"]
-local f_ordered_boolean = formatters["%l,"]
-
-function table.fastserialize(t,prefix) -- todo, move local function out
-
- -- prefix should contain the =
- -- not sorted
- -- only number and string indices (currently)
-
- local r = { type(prefix) == "string" and prefix or "return" }
- local m = 1
- local function fastserialize(t,outer) -- no mixes
- local n = #t
- m = m + 1
- r[m] = "{"
- if n > 0 then
- local v = t[0]
- if v then
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(0,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(0,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(0)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(0,v)
+if JITSUPPORTED then
+
+ local f_hashed_string = formatters["[%Q]=%Q,"]
+ local f_hashed_number = formatters["[%Q]=%s,"]
+ local f_hashed_boolean = formatters["[%Q]=%l,"]
+ local f_hashed_table = formatters["[%Q]="]
+
+ local f_indexed_string = formatters["[%s]=%Q,"]
+ local f_indexed_number = formatters["[%s]=%s,"]
+ local f_indexed_boolean = formatters["[%s]=%l,"]
+ local f_indexed_table = formatters["[%s]="]
+
+ local f_ordered_string = formatters["%Q,"]
+ local f_ordered_number = formatters["%s,"]
+ local f_ordered_boolean = formatters["%l,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+
+ -- prefix should contain the =
+ -- not sorted
+ -- only number and string indices (currently)
+
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(0,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(0,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(0)
+ fastserialize(v)
+ m = m + 1 r[m] = f_indexed_table(0)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_ordered_string(v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_ordered_number(v)
- elseif tv == "table" then
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_ordered_boolean(v)
+ for i=1,n do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_ordered_string(v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_ordered_number(v)
+ elseif tv == "table" then
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_ordered_boolean(v)
+ end
end
end
- end
- -- hm, can't we avoid this ... lua should have a way to check if there
- -- is a hash part
- for k, v in next, t do
- local tk = type(k)
- if tk == "number" then
- if k > n or k < 0 then
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv = type(v)
if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(k,v)
+ m = m + 1 r[m] = f_hashed_string(k,v)
elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(k,v)
+ m = m + 1 r[m] = f_hashed_number(k,v)
elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(k)
+ m = m + 1 r[m] = f_hashed_table(k)
fastserialize(v)
elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(k,v)
+ m = m + 1 r[m] = f_hashed_boolean(k,v)
end
end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
else
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_hashed_string(k,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_hashed_number(k,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_hashed_table(k)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_hashed_boolean(k,v)
- end
+ r[m] = "},"
end
+ return r
end
- m = m + 1
- if outer then
- r[m] = "}"
- else
- r[m] = "},"
+ return concat(fastserialize(t,true))
+ end
+
+else
+
+ local f_v = formatters["[%q]=%q,"]
+ local f_t = formatters["[%q]="]
+ local f_q = formatters["%q,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ m = m + 1
+ r[m] = "[0]='"
+ if type(v) == "table" then
+ fastserialize(v)
+ else
+ r[m] = format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v = t[i]
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
+ else
+ r[m] = "},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
+
end
function table.deserialize(str)
@@ -533,34 +608,34 @@ end
-- husayni.tma : 0.28 -> 0.19
local f_start_key_idx = formatters["%w{"]
-local f_start_key_num = formatters["%w[%s]={"]
+local f_start_key_num = JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str = formatters["%w[%q]={"]
local f_start_key_boo = formatters["%w[%l]={"]
local f_start_key_nop = formatters["%w{"]
local f_stop = formatters["%w},"]
-local f_key_num_value_num = formatters["%w[%s]=%s,"]
-local f_key_str_value_num = formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+local f_key_num_value_num = JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num = JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num = JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
-local f_key_num_value_str = formatters["%w[%s]=%Q,"]
+local f_key_num_value_str = JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str = formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str = formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_num_value_boo = JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo = formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
-local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_num_value_not = JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not = formatters["%w[%Q]={},"]
local f_key_boo_value_not = formatters["%w[%l]={},"]
-local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq = JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq = formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
-local f_val_num = formatters["%w%s,"]
+local f_val_num = JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str = formatters["%w%Q,"]
local f_val_boo = formatters["%w%l,"]
local f_val_not = formatters["%w{},"]
@@ -573,8 +648,6 @@ local f_table_direct = formatters["{"]
local f_table_entry = formatters["[%Q]={"]
local f_table_finish = formatters["}"]
------ f_string = formatters["%q"]
-
local spaces = utilities.strings.newrepeater(" ")
local original_serialize = table.serialize -- the extensive one, the one we started with
diff --git a/tex/context/modules/common/s-abbreviations-logos.tex b/tex/context/modules/common/s-abbreviations-logos.tex
index 9f1d5599e..11c5b9725 100644
--- a/tex/context/modules/common/s-abbreviations-logos.tex
+++ b/tex/context/modules/common/s-abbreviations-logos.tex
@@ -97,6 +97,7 @@
\logo [DVIWINDO] {dviwindo}
\logo [EBCDIC] {ebcdic}
\logo [EC] {ec}
+\logo [ECMASCRIPT] {ecmascript}
\logo [EIFFEL] {Eiffel}
\logo [EMACS] {emacs}
\logo [EMTEX] {em\TeXsuffix}
diff --git a/tex/context/modules/mkiv/m-zint.mkiv b/tex/context/modules/mkiv/m-zint.mkiv
deleted file mode 100644
index 4957c8461..000000000
--- a/tex/context/modules/mkiv/m-zint.mkiv
+++ /dev/null
@@ -1,112 +0,0 @@
-%D \module
-%D [ file=m-zint,
-%D version=2010.12.07,
-%D title=\CONTEXT\ Extra Modules,
-%D subtitle=Zint Barcode Generator,
-%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.
-
-%D Using \type {zint} seems to be the easiest way to generate
-%D (PDF417) barcodes so therefore we now have this module. There
-%D are proper (also windows) binaries at:
-%D
-%D \starttyping
-%D http://www.zint.org.uk
-%D \stoptyping
-%D
-%D There is a bit more code than needed as we want to be able to
-%D feed names.
-
-\startluacode
-
-moduledata.zint = { }
-
-local format, lower, gsub = string.format, string.lower, string.gsub
-local patterns = lpeg.patterns
-
-local zint = "zint" -- '"c:/program files/zint/zint.exe"'
-local defaultcode = "PDF417"
-
-local whitespace = patterns.whitespace
-local spaces = whitespace^0
-local key = (spaces / "") * patterns.digit^0 * (patterns.colon * spaces / "")
-local value = (whitespace / "" + (1 - key))^1
-local pattern = lpeg.Cf(lpeg.Ct("") * (lpeg.Cg((lpeg.Cs(key) / tonumber) * (lpeg.Cs(value) / lower)) + patterns.anything)^0,rawset)
-
-local reverse
-
-local function cleancode(code)
- if not code or code == "" then
- code = defaultcode
- end
- return lower(gsub(code," ",""))
-end
-
-local function numberofcode(code)
- if not reverse then
- local types = os.resultof(format("%s --types",zint)) or ""
- local formats = lpeg.match(pattern,types)
- if not formats or not next(formats) then
- return code
- end
- reverse = table.swapped(formats) or { }
- end
- code = cleancode(code)
- return reverse[code] or code
-end
-
-function moduledata.zint.generate(code,data,suffix,options)
- if not data or data == "" then
- data = "unset"
- end
- local code = cleancode(code)
- local base = format("zint-%s-%s",code,md5.hex(data))
- local name = file.addsuffix(base,suffix or "eps")
- if not lfs.isfile(name) then
- local temp = file.addsuffix(base,"tmp")
- local code = numberofcode(code)
- logs.simple("using 'zint' to generate '%s'",base)
- io.savedata(temp,data)
- os.execute(format('%s --barcode=%s --output="%s" --input="%s" %s',zint,code,name,temp,options or ""))
- os.remove(temp)
- end
- return name
-end
-
-\stopluacode
-
-\unprotect
-
-\unexpanded\def\barcode[#1]% [alternative=,text=]
- {\bgroup
- \getdummyparameters
- [\c!alternative=,\c!text=,#1]%
- \externalfigure
- [\cldcontext{moduledata.zint.generate("\dummyparameter\c!alternative",\!!bs\dummyparameter\c!text\!!es)}]%
- [#1,\c!alternative=,\c!text=]%
- \egroup}
-
-\protect
-
-\continueifinputfile{m-zint.mkiv}
-
-\starttext
-
- \externalfigure[\cldcontext{moduledata.zint.generate("PDF417",[[Hans Hagen]])}]
- \blank
- \externalfigure[\cldcontext{moduledata.zint.generate("PDF417","Ton Otten")}]
- \blank
- \externalfigure[\cldcontext{moduledata.zint.generate("ISBN","9789490688011")}]
- \blank
- \barcode[text=Does It Work?,width=\textwidth]
- \blank
- \barcode[alternative=isbn,text=9789490688011,width=3cm]
-
-\stoptext
-
-
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index ce2794cf3..cc61d0a18 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 : 01/26/20 18:34:44
+-- merge date : 2020-02-11 16:36
do -- begin closure to overcome local limits and interference
@@ -1383,13 +1383,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -1408,6 +1408,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -1428,6 +1430,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -1499,6 +1503,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -1508,7 +1514,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -1536,12 +1542,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -1549,12 +1559,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -1563,6 +1577,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -1579,6 +1595,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -1591,11 +1609,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -1617,6 +1637,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -1636,6 +1658,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -1653,6 +1677,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -1676,6 +1702,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3493,9 +3520,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -9634,6 +9664,7 @@ hashmethods.normal=function(list)
m=m+1
t[m]=k..'='..tostring(v)
end
+ sort(t)
s[n]=k..'={'..concat(t,",").."}"
else
s[n]=k..'='..tostring(v)
@@ -20032,6 +20063,7 @@ function readers.sbix(f,fontdata,specification)
end
end)
local glyphs={}
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike=strikes[i]
local strikeppem=strike.ppem
@@ -20048,13 +20080,25 @@ function readers.sbix(f,fontdata,specification)
local datasize=nextoffset-glyphoffset
if datasize>0 then
setposition(f,strikeoffset+glyphoffset)
+ local x=readshort(f)
+ local y=readshort(f)
+ local tag=readtag(f)
+ local size=datasize-8
+ local data=nil
+ local offset=nil
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ data=readstring(f,size)
+ size=nil
+ end
shapes[i]={
- x=readshort(f),
- y=readshort(f),
- tag=readtag(f),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
+ x=x,
+ y=y,
+ o=offset,
+ s=size,
+ data=data,
}
done=done+1
if done==nofglyphs then
@@ -20233,29 +20277,46 @@ do
end
local default={ width=0,height=0 }
local glyphs=fontdata.glyphs
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for index,subtable in sortedhash(shapes) do
if type(subtable)=="table" then
local data=nil
+ local size=nil
local metrics=default
local format=subtable.format
local offset=subtable.offsets[index]
setposition(f,offset)
if format==17 then
metrics=getsmallmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==18 then
metrics=getbigmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==19 then
metrics=subtable.metrics
- data=readstring(f,readulong(f))
+ size=true
+ else
+ end
+ if size then
+ size=readulong(f)
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ offset=nil
+ data=readstring(f,size)
+ size=nil
+ end
else
+ offset=nil
end
local x=metrics.width
local y=metrics.height
shapes[index]={
x=x,
y=y,
+ o=offset,
+ s=size,
data=data,
}
local glyph=glyphs[index]
@@ -23251,7 +23312,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.110
+otf.version=3.111
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua
index 85fe1ae97..9f45408b1 100644
--- a/tex/generic/context/luatex/luatex-fonts.lua
+++ b/tex/generic/context/luatex/luatex-fonts.lua
@@ -257,7 +257,9 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-vfc.lua')
- -- This is the bulk of opentype code.
+ -- This is the bulk of opentype code. The color and variable font support (as for
+ -- emoji) can (and might) actually go away here because it has never been used
+ -- outside context so in retrospect there was no need for it being generic.
loadmodule('font-otr.lua')
loadmodule('font-oti.lua')
diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua
index 842401af7..ba6597bf3 100644
--- a/web2c/contextcnf.lua
+++ b/web2c/contextcnf.lua
@@ -103,7 +103,7 @@ return {
PYTHONINPUTS = ".;$TEXMF/scripts/context/python",
RUBYINPUTS = ".;$TEXMF/scripts/context/ruby",
LUAINPUTS = ".;$TEXINPUTS;$TEXMF/scripts/context/lua//;$TEXMF",
- CLUAINPUTS = ".;$SELFAUTOLOC/lib/{context,$engine,luatex}/lua//",
+ CLUAINPUTS = ".;$SELFAUTOLOC/lib/$engine//",
-- texmf-local/tex/generic/example/foo :
--