summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2019-10-28 20:03:50 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2019-10-28 20:03:50 +0100
commitf58a2cb5d22c5931581274db1f0ec85ac903b747 (patch)
treeba324713b8c0f2ee9465238d3cf867de3fb41dc5
parent24f6f7de245bdff10f21984a9a3c6af3d31fa1f1 (diff)
downloadcontext-f58a2cb5d22c5931581274db1f0ec85ac903b747.tar.gz
2019-10-28 18:22:00
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-metapost.lua2
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-tex.lua4
-rw-r--r--context/data/scite/context/scite-context-data-metapost.properties68
-rw-r--r--context/data/scite/context/scite-context-data-tex.properties84
-rw-r--r--context/data/scite/context/scite-context.properties8
-rw-r--r--context/data/textadept/context/data/scite-context-data-metapost.lua2
-rw-r--r--context/data/textadept/context/data/scite-context-data-tex.lua4
-rw-r--r--context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json2
-rw-r--r--context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json2
-rw-r--r--doc/context/documents/general/manuals/svg-lmtx.pdfbin0 -> 209324 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin887654 -> 887939 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin889378 -> 889388 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin893281 -> 893544 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin885609 -> 885675 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin891253 -> 891063 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin383549 -> 383510 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin383424 -> 383722 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin380151 -> 380342 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin383568 -> 383614 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin383260 -> 383095 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin382088 -> 381917 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin620214 -> 620123 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin880929 -> 880791 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin885587 -> 885357 bytes
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-groups.tex52
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun.tex1
-rw-r--r--doc/context/sources/general/manuals/svg/mozilla-tiger.svg1
-rw-r--r--doc/context/sources/general/manuals/svg/svg-lmtx-microsoft.lua113
-rw-r--r--doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua354
-rw-r--r--doc/context/sources/general/manuals/svg/svg-lmtx.tex547
-rw-r--r--doc/context/sources/general/manuals/svg/svglogo.svg261
-rw-r--r--metapost/context/base/mpiv/mp-lmtx.mpxl57
-rw-r--r--metapost/context/base/mpiv/mp-luas.mpxl6
-rw-r--r--scripts/context/lua/mtx-fonts.lua2
-rw-r--r--scripts/context/lua/mtx-install.lua6
-rw-r--r--scripts/context/lua/mtxrun.lua87
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua87
-rw-r--r--scripts/context/stubs/unix/mtxrun87
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua87
-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/anch-pos.lua2
-rw-r--r--tex/context/base/mkiv/attr-col.lua2
-rw-r--r--tex/context/base/mkiv/back-exp.lua8
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context-lmtx-error.pdfbin0 -> 4171 bytes
-rw-r--r--tex/context/base/mkiv/context-lmtx-error.tex8
-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-vir.lua17
-rw-r--r--tex/context/base/mkiv/font-age.lua13
-rw-r--r--tex/context/base/mkiv/font-agl.lua15
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-oup.lua20
-rw-r--r--tex/context/base/mkiv/grph-con.lua22
-rw-r--r--tex/context/base/mkiv/grph-img.lua181
-rw-r--r--tex/context/base/mkiv/grph-inc.lua34
-rw-r--r--tex/context/base/mkiv/grph-inc.mkiv19
-rw-r--r--tex/context/base/mkiv/grph-trf.mkiv10
-rw-r--r--tex/context/base/mkiv/l-unicode.lua84
-rw-r--r--tex/context/base/mkiv/lang-txt.lua129
-rw-r--r--tex/context/base/mkiv/lpdf-ano.lua188
-rw-r--r--tex/context/base/mkiv/lpdf-img.lua25
-rw-r--r--tex/context/base/mkiv/lpdf-ini.lua14
-rw-r--r--tex/context/base/mkiv/lpdf-lmt.lua195
-rw-r--r--tex/context/base/mkiv/lpdf-pde.lua2
-rw-r--r--tex/context/base/mkiv/lpdf-tag.lua158
-rw-r--r--tex/context/base/mkiv/lxml-css.lua152
-rw-r--r--tex/context/base/mkiv/math-ini.lua2
-rw-r--r--tex/context/base/mkiv/math-ini.mkiv5
-rw-r--r--tex/context/base/mkiv/math-stc.mkvi107
-rw-r--r--tex/context/base/mkiv/meta-tex.mkiv83
-rw-r--r--tex/context/base/mkiv/mlib-cnt.lua12
-rw-r--r--tex/context/base/mkiv/mlib-lmp.lua71
-rw-r--r--tex/context/base/mkiv/mlib-pdf.lua71
-rw-r--r--tex/context/base/mkiv/mlib-pps.lua93
-rw-r--r--tex/context/base/mkiv/mlib-run.lua2
-rw-r--r--tex/context/base/mkiv/mlib-scn.lua7
-rw-r--r--tex/context/base/mkiv/mlib-svg.lua3617
-rw-r--r--tex/context/base/mkiv/mult-mps.lua2
-rw-r--r--tex/context/base/mkiv/mult-prm.lua3
-rw-r--r--tex/context/base/mkiv/node-ini.lua5
-rw-r--r--tex/context/base/mkiv/page-cst.lua1
-rw-r--r--tex/context/base/mkiv/page-ffl.mkiv6
-rw-r--r--tex/context/base/mkiv/page-lin.mkvi21
-rw-r--r--tex/context/base/mkiv/page-mix.lua12
-rw-r--r--tex/context/base/mkiv/page-mix.mkiv3
-rw-r--r--tex/context/base/mkiv/page-not.mkiv26
-rw-r--r--tex/context/base/mkiv/page-run.mkiv6
-rw-r--r--tex/context/base/mkiv/regi-ini.lua35
-rw-r--r--tex/context/base/mkiv/regi-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26676 -> 26686 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin268444 -> 268844 bytes
-rw-r--r--tex/context/base/mkiv/strc-itm.mklx32
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi20
-rw-r--r--tex/context/base/mkiv/strc-tag.lua8
-rw-r--r--tex/context/base/mkiv/strc-tag.mkiv10
-rw-r--r--tex/context/base/mkiv/syst-ini.mkxl1
-rw-r--r--tex/context/base/mkiv/tabl-ntb.mkiv74
-rw-r--r--tex/context/base/mkiv/tabl-ntb.mkxl74
-rw-r--r--tex/context/base/mkiv/typo-chr.mkiv1
-rw-r--r--tex/context/base/mkiv/typo-del.mkiv15
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin893281 -> 893544 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin61165 -> 61165 bytes
-rw-r--r--tex/context/modules/common/s-abbreviations-logos.tex2
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua20
107 files changed, 5620 insertions, 2067 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-metapost.lua b/context/data/scite/context/lexers/data/scite-context-data-metapost.lua
index cd69aff8f..9304b2dd2 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-metapost.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-metapost.lua
@@ -3,7 +3,7 @@ return {
["disabled"]={ "verbatimtex", "troffmode" },
["internals"]={ "mitered", "rounded", "beveled", "butt", "squared", "eps", "epsilon", "infinity", "bboxmargin", "ahlength", "ahangle", "labeloffset", "dotlabeldiam", "defaultpen", "defaultscale", "join_radius", "charscale", "ditto", "EOF", "pen_lft", "pen_rt", "pen_top", "pen_bot" },
["metafont"]={ "autorounding", "beginchar", "blacker", "boundarychar", "capsule_def", "capsule_end", "change_width", "chardp", "chardx", "chardy", "charexists", "charext", "charht", "charic", "charlist", "charwd", "cull", "cullit", "currenttransform", "currentwindow", "define_blacker_pixels", "define_corrected_pixels", "define_good_x_pixels", "define_good_y_pixels", "define_horizontal_corrected_pixels", "define_pixels", "define_whole_blacker_pixels", "define_whole_pixels", "define_whole_vertical_blacker_pixels", "define_whole_vertical_pixels", "designsize", "display", "displaying", "endchar", "extensible", "extra_beginchar", "extra_endchar", "extra_setup", "fillin", "font_coding_scheme", "font_extra_space", "font_identifier", "font_normal_shrink", "font_normal_space", "font_normal_stretch", "font_quad", "font_size", "font_slant", "font_x_height", "fontdimen", "fontmaking", "gfcorners", "granularity", "grayfont", "headerbyte", "hppp", "hround", "imagerules", "italcorr", "kern", "labelfont", "ligtable", "lowres_fix", "makebox", "makegrid", "maketicks", "mode_def", "mode_setup", "nodisplays", "notransforms", "numspecial", "o_correction", "openit", "openwindow", "pixels_per_inch", "proofing", "proofoffset", "proofrule", "proofrulethickness", "rulepen", "screenchars", "screenrule", "screenstrokes", "screen_cols", "screen_rows", "showit", "slantfont", "smode", "smoothing", "titlefont", "totalweight", "tracingedges", "tracingpens", "turningcheck", "unitpixel", "vppp", "vround", "xoffset", "yoffset" },
- ["primitives"]={ "charcode", "day", "linecap", "linejoin", "miterlimit", "month", "pausing", "prologues", "showstopping", "time", "tracingcapsules", "tracingchoices", "mpprocset", "tracingcommands", "tracingequations", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingrestores", "tracingspecs", "tracingstats", "tracingtitles", "truecorners", "warningcheck", "year", "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", "hex", "infont", "intersectiontimes", "known", "void", "length", "llcorner", "lrcorner", "makepath", "makepen", "mexp", "mlog", "normaldeviate", "not", "numeric", "oct", "odd", "or", "path", "pair", "pen", "penoffset", "picture", "point", "postcontrol", "precontrol", "reverse", "rotated", "scaled", "shifted", "sind", "slanted", "sqrt", "str", "string", "subpath", "substring", "transform", "transformed", "ulcorner", "uniformdeviate", "unknown", "urcorner", "xpart", "xscaled", "xxpart", "xypart", "ypart", "yscaled", "yxpart", "yypart", "zscaled", "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds", "shipout", "show", "showdependencies", "showtoken", "showvariable", "special", "begingroup", "endgroup", "of", "curl", "tension", "and", "controls", "interpath", "on", "off", "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary", "tertiary", "primarydef", "secondarydef", "tertiarydef", "randomseed", "also", "contour", "doublepath", "withcolor", "withcmykcolor", "withpen", "dashed", "envelope", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif", "within", "forsuffixes", "step", "until", "charlist", "extensible", "fontdimen", "headerbyte", "kern", "ligtable", "boundarychar", "chardp", "charext", "charht", "charic", "charwd", "designsize", "fontmaking", "charexists", "cullit", "currenttransform", "gfcorners", "grayfont", "hround", "imagerules", "lowres_fix", "nodisplays", "notransforms", "openit", "displaying", "currentwindow", "screen_rows", "screen_cols", "pixels_per_inch", "cull", "display", "openwindow", "numspecial", "totalweight", "autorounding", "fillin", "proofing", "tracingpens", "xoffset", "chardx", "granularity", "smoothing", "turningcheck", "yoffset", "chardy", "hppp", "tracingedges", "vppp", "extra_beginfig", "extra_endfig", "mpxbreak", "endinput", "message", "delimiters", "turningnumber", "errmessage", "scantokens", "end", "outer", "inner", "write", "to", "readfrom", "closefrom", "withprescript", "withpostscript", "top", "bot", "lft", "rt", "ulft", "urt", "llft", "lrt", "redpart", "greenpart", "bluepart", "cyanpart", "magentapart", "yellowpart", "blackpart", "prescriptpart", "postscriptpart", "rgbcolor", "cmykcolor", "colormodel", "graypart", "greypart", "greycolor", "graycolor", "dashpart", "penpart", "stroked", "filled", "textual", "clipped", "bounded", "pathpart", "expandafter", "minute", "hour", "outputformat", "outputtemplate", "filenametemplate", "fontmapfile", "fontmapline", "fontpart", "fontsize", "glyph", "restoreclipcolor", "troffmode", "runscript", "maketext", "numbersystem" },
+ ["primitives"]={ "charcode", "day", "linecap", "linejoin", "miterlimit", "month", "pausing", "prologues", "showstopping", "time", "tracingcapsules", "tracingchoices", "mpprocset", "tracingcommands", "tracingequations", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingrestores", "tracingspecs", "tracingstats", "tracingtitles", "truecorners", "warningcheck", "year", "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", "hex", "infont", "intersectiontimes", "known", "void", "length", "llcorner", "lrcorner", "makepath", "makepen", "mexp", "mlog", "normaldeviate", "not", "numeric", "oct", "odd", "or", "path", "pair", "pen", "penoffset", "picture", "point", "postcontrol", "precontrol", "reverse", "rotated", "scaled", "shifted", "sind", "slanted", "sqrt", "str", "string", "subpath", "substring", "transform", "transformed", "ulcorner", "uniformdeviate", "unknown", "urcorner", "xpart", "xscaled", "xxpart", "xypart", "ypart", "yscaled", "yxpart", "yypart", "zscaled", "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds", "setgroup", "shipout", "show", "showdependencies", "showtoken", "showvariable", "special", "begingroup", "endgroup", "of", "curl", "tension", "and", "controls", "interpath", "on", "off", "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary", "tertiary", "primarydef", "secondarydef", "tertiarydef", "randomseed", "also", "contour", "doublepath", "withcolor", "withcmykcolor", "withpen", "dashed", "envelope", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif", "within", "forsuffixes", "step", "until", "charlist", "extensible", "fontdimen", "headerbyte", "kern", "ligtable", "boundarychar", "chardp", "charext", "charht", "charic", "charwd", "designsize", "fontmaking", "charexists", "cullit", "currenttransform", "gfcorners", "grayfont", "hround", "imagerules", "lowres_fix", "nodisplays", "notransforms", "openit", "displaying", "currentwindow", "screen_rows", "screen_cols", "pixels_per_inch", "cull", "display", "openwindow", "numspecial", "totalweight", "autorounding", "fillin", "proofing", "tracingpens", "xoffset", "chardx", "granularity", "smoothing", "turningcheck", "yoffset", "chardy", "hppp", "tracingedges", "vppp", "extra_beginfig", "extra_endfig", "mpxbreak", "endinput", "message", "delimiters", "turningnumber", "errmessage", "scantokens", "end", "outer", "inner", "write", "to", "readfrom", "closefrom", "withprescript", "withpostscript", "top", "bot", "lft", "rt", "ulft", "urt", "llft", "lrt", "redpart", "greenpart", "bluepart", "cyanpart", "magentapart", "yellowpart", "blackpart", "prescriptpart", "postscriptpart", "rgbcolor", "cmykcolor", "colormodel", "graypart", "greypart", "greycolor", "graycolor", "dashpart", "penpart", "stroked", "filled", "textual", "clipped", "bounded", "pathpart", "expandafter", "minute", "hour", "outputformat", "outputtemplate", "filenametemplate", "fontmapfile", "fontmapline", "fontpart", "fontsize", "glyph", "restoreclipcolor", "troffmode", "runscript", "maketext", "numbersystem" },
["shortcuts"]={ "..", "...", "--", "---", "&", "\\" },
["tex"]={ "btex", "etex", "verbatimtex" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/data/scite-context-data-tex.lua b/context/data/scite/context/lexers/data/scite-context-data-tex.lua
index 954c06e1c..1091cd2d5 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-tex.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-tex.lua
@@ -1,9 +1,9 @@
return {
["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" },
["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "readline", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracingnesting", "tracingscantokens", "unexpanded", "unless", "widowpenalties" },
- ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Umiddle", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "aftergrouped", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "boundary", "boxattr", "boxdirection", "boxorientation", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "breakafterdirmode", "catcodetable", "clearmarks", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "efcode", "endlocalcontrol", "etoksapp", "etokspre", "exceptionpenalty", "expanded", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "fixupboxesmode", "fontid", "formatname", "frozen", "futureexpand", "futureexpandis", "futureexpandisap", "gleaders", "glet", "glyphdatafield", "gtoksapp", "gtokspre", "hjcode", "hpack", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimval", "iffrozen", "ifincsname", "ifnumval", "ifprotected", "iftok", "ifusercmd", "immediateassigned", "immediateassignment", "initcatcodetable", "insertht", "internalcodesmode", "lastnamedcs", "lastnodesubtype", "leftghost", "leftmarginkern", "letcharcode", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathnolimitsmode", "matholdmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "noboundary", "nohrule", "nokerns", "noligs", "nospaces", "novrule", "outputbox", "pardirection", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitvmode", "rightghost", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "setfontid", "shapemode", "textdirection", "toksapp", "tokspre", "tpack", "tracingfonts", "vpack", "wordboundary", "xtoksapp", "xtokspre" },
+ ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Umiddle", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "aftergrouped", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "beginlocalcontrol", "boundary", "boxattr", "boxdirection", "boxorientation", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "breakafterdirmode", "catcodetable", "clearmarks", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "efcode", "endlocalcontrol", "etoksapp", "etokspre", "exceptionpenalty", "expanded", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "fixupboxesmode", "fontid", "formatname", "frozen", "futureexpand", "futureexpandis", "futureexpandisap", "gleaders", "glet", "glyphdatafield", "gtoksapp", "gtokspre", "hjcode", "hpack", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimval", "iffrozen", "ifincsname", "ifnumval", "ifprotected", "iftok", "ifusercmd", "immediateassigned", "immediateassignment", "initcatcodetable", "insertht", "internalcodesmode", "lastnamedcs", "lastnodesubtype", "leftghost", "leftmarginkern", "letcharcode", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathlimitsmode", "mathnolimitsmode", "matholdmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "noboundary", "nohrule", "nokerns", "noligs", "nospaces", "novrule", "outputbox", "pardirection", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitvmode", "rightghost", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "setfontid", "shapemode", "textdirection", "toksapp", "tokspre", "tpack", "tracingfonts", "vpack", "wordboundary", "xtoksapp", "xtokspre" },
["omega"]={ "Omegaminorversion", "Omegarevision", "Omegaversion" },
["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmajorversion", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfomitcharset", "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
- ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "or", "orelse", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" },
+ ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "or", "orelse", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "shownodedetails", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" },
["xetex"]={ "XeTeXversion" },
} \ No newline at end of file
diff --git a/context/data/scite/context/scite-context-data-metapost.properties b/context/data/scite/context/scite-context-data-metapost.properties
index 5810cb007..19bd711b0 100644
--- a/context/data/scite/context/scite-context-data-metapost.properties
+++ b/context/data/scite/context/scite-context-data-metapost.properties
@@ -84,40 +84,40 @@ transformed ulcorner uniformdeviate unknown urcorner \
xpart xscaled xxpart xypart ypart \
yscaled yxpart yypart zscaled addto \
clip input interim let newinternal \
-save setbounds shipout show showdependencies \
-showtoken showvariable special begingroup endgroup \
-of curl tension and controls \
-interpath on off def vardef \
-enddef expr suffix text primary \
-secondary tertiary primarydef secondarydef tertiarydef \
-randomseed also contour doublepath withcolor \
-withcmykcolor withpen dashed envelope if \
-else elseif fi for endfor \
-forever exitif within forsuffixes step \
-until charlist extensible fontdimen headerbyte \
-kern ligtable boundarychar chardp charext \
-charht charic charwd designsize fontmaking \
-charexists cullit currenttransform gfcorners grayfont \
-hround imagerules lowres_fix nodisplays notransforms \
-openit displaying currentwindow screen_rows screen_cols \
-pixels_per_inch cull display openwindow numspecial \
-totalweight autorounding fillin proofing tracingpens \
-xoffset chardx granularity smoothing turningcheck \
-yoffset chardy hppp tracingedges vppp \
-extra_beginfig extra_endfig mpxbreak endinput message \
-delimiters turningnumber errmessage scantokens end \
-outer inner write to readfrom \
-closefrom withprescript withpostscript top bot \
-lft rt ulft urt llft \
-lrt redpart greenpart bluepart cyanpart \
-magentapart yellowpart blackpart prescriptpart postscriptpart \
-rgbcolor cmykcolor colormodel graypart greypart \
-greycolor graycolor dashpart penpart stroked \
-filled textual clipped bounded pathpart \
-expandafter minute hour outputformat outputtemplate \
-filenametemplate fontmapfile fontmapline fontpart fontsize \
-glyph restoreclipcolor troffmode runscript maketext \
-numbersystem
+save setbounds setgroup shipout show \
+showdependencies showtoken showvariable special begingroup \
+endgroup of curl tension and \
+controls interpath on off def \
+vardef enddef expr suffix text \
+primary secondary tertiary primarydef secondarydef \
+tertiarydef randomseed also contour doublepath \
+withcolor withcmykcolor withpen dashed envelope \
+if else elseif fi for \
+endfor forever exitif within forsuffixes \
+step until charlist extensible fontdimen \
+headerbyte kern ligtable boundarychar chardp \
+charext charht charic charwd designsize \
+fontmaking charexists cullit currenttransform gfcorners \
+grayfont hround imagerules lowres_fix nodisplays \
+notransforms openit displaying currentwindow screen_rows \
+screen_cols pixels_per_inch cull display openwindow \
+numspecial totalweight autorounding fillin proofing \
+tracingpens xoffset chardx granularity smoothing \
+turningcheck yoffset chardy hppp tracingedges \
+vppp extra_beginfig extra_endfig mpxbreak endinput \
+message delimiters turningnumber errmessage scantokens \
+end outer inner write to \
+readfrom closefrom withprescript withpostscript top \
+bot lft rt ulft urt \
+llft lrt redpart greenpart bluepart \
+cyanpart magentapart yellowpart blackpart prescriptpart \
+postscriptpart rgbcolor cmykcolor colormodel graypart \
+greypart greycolor graycolor dashpart penpart \
+stroked filled textual clipped bounded \
+pathpart expandafter minute hour outputformat \
+outputtemplate filenametemplate fontmapfile fontmapline fontpart \
+fontsize glyph restoreclipcolor troffmode runscript \
+maketext numbersystem
keywordclass.metapost.shortcuts=\
.. ... -- --- \
diff --git a/context/data/scite/context/scite-context-data-tex.properties b/context/data/scite/context/scite-context-data-tex.properties
index 6f5822a2d..e597a8113 100644
--- a/context/data/scite/context/scite-context-data-tex.properties
+++ b/context/data/scite/context/scite-context-data-tex.properties
@@ -49,34 +49,34 @@ Uskewedwithdelims Ustack Ustartdisplaymath Ustartmath Ustopdisplaymath \
Ustopmath Usubscript Usuperscript Uunderdelimiter Uvextensible \
adjustspacing aftergrouped alignmark aligntab attribute \
attributedef automaticdiscretionary automatichyphenmode automatichyphenpenalty begincsname \
-boundary boxattr boxdirection boxorientation boxtotal \
-boxxmove boxxoffset boxymove boxyoffset breakafterdirmode \
-catcodetable clearmarks compoundhyphenmode crampeddisplaystyle crampedscriptscriptstyle \
-crampedscriptstyle crampedtextstyle csstring efcode endlocalcontrol \
-etoksapp etokspre exceptionpenalty expanded explicitdiscretionary \
-explicithyphenpenalty firstvalidlanguage fixupboxesmode fontid formatname \
-frozen futureexpand futureexpandis futureexpandisap gleaders \
-glet glyphdatafield gtoksapp gtokspre hjcode \
-hpack hyphenationbounds hyphenationmin hyphenpenaltymode ifabsdim \
-ifabsnum ifchkdim ifchknum ifcmpdim ifcmpnum \
-ifcondition ifcstok ifdimval iffrozen ifincsname \
-ifnumval ifprotected iftok ifusercmd immediateassigned \
-immediateassignment initcatcodetable insertht internalcodesmode lastnamedcs \
-lastnodesubtype leftghost leftmarginkern letcharcode linedirection \
-localbrokenpenalty localinterlinepenalty localleftbox localrightbox lpcode \
-luabytecode luabytecodecall luacopyinputnodes luadef luaescapestring \
-luafunction luafunctioncall luatexbanner luatexrevision luatexversion \
-mathdelimitersmode mathdirection mathdisplayskipmode matheqnogapstep mathflattenmode \
-mathitalicsmode mathnolimitsmode matholdmode mathpenaltiesmode mathrulesfam \
-mathrulesmode mathrulethicknessmode mathscriptboxmode mathscriptcharmode mathscriptsmode \
-mathstyle mathsurroundmode mathsurroundskip noboundary nohrule \
-nokerns noligs nospaces novrule outputbox \
-pardirection postexhyphenchar posthyphenchar prebinoppenalty predisplaygapfactor \
-preexhyphenchar prehyphenchar prerelpenalty protrudechars protrusionboundary \
-pxdimen quitvmode rightghost rightmarginkern rpcode \
-savecatcodetable scantextokens setfontid shapemode textdirection \
-toksapp tokspre tpack tracingfonts vpack \
-wordboundary xtoksapp xtokspre
+beginlocalcontrol boundary boxattr boxdirection boxorientation \
+boxtotal boxxmove boxxoffset boxymove boxyoffset \
+breakafterdirmode catcodetable clearmarks compoundhyphenmode crampeddisplaystyle \
+crampedscriptscriptstyle crampedscriptstyle crampedtextstyle csstring efcode \
+endlocalcontrol etoksapp etokspre exceptionpenalty expanded \
+explicitdiscretionary explicithyphenpenalty firstvalidlanguage fixupboxesmode fontid \
+formatname frozen futureexpand futureexpandis futureexpandisap \
+gleaders glet glyphdatafield gtoksapp gtokspre \
+hjcode hpack hyphenationbounds hyphenationmin hyphenpenaltymode \
+ifabsdim ifabsnum ifchkdim ifchknum ifcmpdim \
+ifcmpnum ifcondition ifcstok ifdimval iffrozen \
+ifincsname ifnumval ifprotected iftok ifusercmd \
+immediateassigned immediateassignment initcatcodetable insertht internalcodesmode \
+lastnamedcs lastnodesubtype leftghost leftmarginkern letcharcode \
+linedirection localbrokenpenalty localinterlinepenalty localleftbox localrightbox \
+lpcode luabytecode luabytecodecall luacopyinputnodes luadef \
+luaescapestring luafunction luafunctioncall luatexbanner luatexrevision \
+luatexversion mathdelimitersmode mathdirection mathdisplayskipmode matheqnogapstep \
+mathflattenmode mathitalicsmode mathlimitsmode mathnolimitsmode matholdmode \
+mathpenaltiesmode mathrulesfam mathrulesmode mathrulethicknessmode mathscriptboxmode \
+mathscriptcharmode mathscriptsmode mathstyle mathsurroundmode mathsurroundskip \
+noboundary nohrule nokerns noligs nospaces \
+novrule outputbox pardirection postexhyphenchar posthyphenchar \
+prebinoppenalty predisplaygapfactor preexhyphenchar prehyphenchar prerelpenalty \
+protrudechars protrusionboundary pxdimen quitvmode rightghost \
+rightmarginkern rpcode savecatcodetable scantextokens setfontid \
+shapemode textdirection toksapp tokspre tpack \
+tracingfonts vpack wordboundary xtoksapp xtokspre
keywordclass.tex.omega=\
Omegaminorversion Omegarevision Omegaversion
@@ -158,20 +158,20 @@ raise read relax relpenalty right \
righthyphenmin rightskip romannumeral scriptfont scriptscriptfont \
scriptscriptstyle scriptspace scriptstyle scrollmode setbox \
setlanguage sfcode shipout show showbox \
-showboxbreadth showboxdepth showlists showthe skewchar \
-skip skipdef spacefactor spaceskip span \
-splitbotmark splitfirstmark splitmaxdepth splittopskip string \
-tabskip textfont textstyle the thickmuskip \
-thinmuskip time toks toksdef tolerance \
-topmark topskip tracingcommands tracinglostchars tracingmacros \
-tracingonline tracingoutput tracingpages tracingparagraphs tracingrestores \
-tracingstats uccode uchyph underline unhbox \
-unhcopy unkern unpenalty unskip unvbox \
-unvcopy uppercase vadjust valign vbadness \
-vbox vcenter vfil vfill vfilneg \
-vfuzz voffset vrule vsize vskip \
-vsplit vss vtop wd widowpenalty \
-xdef xleaders xspaceskip year
+showboxbreadth showboxdepth showlists shownodedetails showthe \
+skewchar skip skipdef spacefactor spaceskip \
+span splitbotmark splitfirstmark splitmaxdepth splittopskip \
+string tabskip textfont textstyle the \
+thickmuskip thinmuskip time toks toksdef \
+tolerance topmark topskip tracingcommands tracinglostchars \
+tracingmacros tracingonline tracingoutput tracingpages tracingparagraphs \
+tracingrestores tracingstats uccode uchyph underline \
+unhbox unhcopy unkern unpenalty unskip \
+unvbox unvcopy uppercase vadjust valign \
+vbadness vbox vcenter vfil vfill \
+vfilneg vfuzz voffset vrule vsize \
+vskip vsplit vss vtop wd \
+widowpenalty xdef xleaders xspaceskip year
keywordclass.tex.xetex=\
XeTeXversion
diff --git a/context/data/scite/context/scite-context.properties b/context/data/scite/context/scite-context.properties
index 82e7f4c97..c50300128 100644
--- a/context/data/scite/context/scite-context.properties
+++ b/context/data/scite/context/scite-context.properties
@@ -553,11 +553,13 @@ if PLAT_WIN
clear.before.execute=1
wrap.output=0
-if PLAT_WIN
- eol.mode=CRLF
+#if PLAT_WIN
+# eol.mode=CRLF
+eol.mode=auto
ensure.final.line.end=1
-ensure.consistent.line.ends=1
+#~ $(file.patterns.context).ensure.consistent.line.ends=1
+#~ $(file.patterns.metafun).ensure.consistent.line.ends=1
# Editor: file type
diff --git a/context/data/textadept/context/data/scite-context-data-metapost.lua b/context/data/textadept/context/data/scite-context-data-metapost.lua
index cd69aff8f..9304b2dd2 100644
--- a/context/data/textadept/context/data/scite-context-data-metapost.lua
+++ b/context/data/textadept/context/data/scite-context-data-metapost.lua
@@ -3,7 +3,7 @@ return {
["disabled"]={ "verbatimtex", "troffmode" },
["internals"]={ "mitered", "rounded", "beveled", "butt", "squared", "eps", "epsilon", "infinity", "bboxmargin", "ahlength", "ahangle", "labeloffset", "dotlabeldiam", "defaultpen", "defaultscale", "join_radius", "charscale", "ditto", "EOF", "pen_lft", "pen_rt", "pen_top", "pen_bot" },
["metafont"]={ "autorounding", "beginchar", "blacker", "boundarychar", "capsule_def", "capsule_end", "change_width", "chardp", "chardx", "chardy", "charexists", "charext", "charht", "charic", "charlist", "charwd", "cull", "cullit", "currenttransform", "currentwindow", "define_blacker_pixels", "define_corrected_pixels", "define_good_x_pixels", "define_good_y_pixels", "define_horizontal_corrected_pixels", "define_pixels", "define_whole_blacker_pixels", "define_whole_pixels", "define_whole_vertical_blacker_pixels", "define_whole_vertical_pixels", "designsize", "display", "displaying", "endchar", "extensible", "extra_beginchar", "extra_endchar", "extra_setup", "fillin", "font_coding_scheme", "font_extra_space", "font_identifier", "font_normal_shrink", "font_normal_space", "font_normal_stretch", "font_quad", "font_size", "font_slant", "font_x_height", "fontdimen", "fontmaking", "gfcorners", "granularity", "grayfont", "headerbyte", "hppp", "hround", "imagerules", "italcorr", "kern", "labelfont", "ligtable", "lowres_fix", "makebox", "makegrid", "maketicks", "mode_def", "mode_setup", "nodisplays", "notransforms", "numspecial", "o_correction", "openit", "openwindow", "pixels_per_inch", "proofing", "proofoffset", "proofrule", "proofrulethickness", "rulepen", "screenchars", "screenrule", "screenstrokes", "screen_cols", "screen_rows", "showit", "slantfont", "smode", "smoothing", "titlefont", "totalweight", "tracingedges", "tracingpens", "turningcheck", "unitpixel", "vppp", "vround", "xoffset", "yoffset" },
- ["primitives"]={ "charcode", "day", "linecap", "linejoin", "miterlimit", "month", "pausing", "prologues", "showstopping", "time", "tracingcapsules", "tracingchoices", "mpprocset", "tracingcommands", "tracingequations", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingrestores", "tracingspecs", "tracingstats", "tracingtitles", "truecorners", "warningcheck", "year", "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", "hex", "infont", "intersectiontimes", "known", "void", "length", "llcorner", "lrcorner", "makepath", "makepen", "mexp", "mlog", "normaldeviate", "not", "numeric", "oct", "odd", "or", "path", "pair", "pen", "penoffset", "picture", "point", "postcontrol", "precontrol", "reverse", "rotated", "scaled", "shifted", "sind", "slanted", "sqrt", "str", "string", "subpath", "substring", "transform", "transformed", "ulcorner", "uniformdeviate", "unknown", "urcorner", "xpart", "xscaled", "xxpart", "xypart", "ypart", "yscaled", "yxpart", "yypart", "zscaled", "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds", "shipout", "show", "showdependencies", "showtoken", "showvariable", "special", "begingroup", "endgroup", "of", "curl", "tension", "and", "controls", "interpath", "on", "off", "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary", "tertiary", "primarydef", "secondarydef", "tertiarydef", "randomseed", "also", "contour", "doublepath", "withcolor", "withcmykcolor", "withpen", "dashed", "envelope", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif", "within", "forsuffixes", "step", "until", "charlist", "extensible", "fontdimen", "headerbyte", "kern", "ligtable", "boundarychar", "chardp", "charext", "charht", "charic", "charwd", "designsize", "fontmaking", "charexists", "cullit", "currenttransform", "gfcorners", "grayfont", "hround", "imagerules", "lowres_fix", "nodisplays", "notransforms", "openit", "displaying", "currentwindow", "screen_rows", "screen_cols", "pixels_per_inch", "cull", "display", "openwindow", "numspecial", "totalweight", "autorounding", "fillin", "proofing", "tracingpens", "xoffset", "chardx", "granularity", "smoothing", "turningcheck", "yoffset", "chardy", "hppp", "tracingedges", "vppp", "extra_beginfig", "extra_endfig", "mpxbreak", "endinput", "message", "delimiters", "turningnumber", "errmessage", "scantokens", "end", "outer", "inner", "write", "to", "readfrom", "closefrom", "withprescript", "withpostscript", "top", "bot", "lft", "rt", "ulft", "urt", "llft", "lrt", "redpart", "greenpart", "bluepart", "cyanpart", "magentapart", "yellowpart", "blackpart", "prescriptpart", "postscriptpart", "rgbcolor", "cmykcolor", "colormodel", "graypart", "greypart", "greycolor", "graycolor", "dashpart", "penpart", "stroked", "filled", "textual", "clipped", "bounded", "pathpart", "expandafter", "minute", "hour", "outputformat", "outputtemplate", "filenametemplate", "fontmapfile", "fontmapline", "fontpart", "fontsize", "glyph", "restoreclipcolor", "troffmode", "runscript", "maketext", "numbersystem" },
+ ["primitives"]={ "charcode", "day", "linecap", "linejoin", "miterlimit", "month", "pausing", "prologues", "showstopping", "time", "tracingcapsules", "tracingchoices", "mpprocset", "tracingcommands", "tracingequations", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingrestores", "tracingspecs", "tracingstats", "tracingtitles", "truecorners", "warningcheck", "year", "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", "hex", "infont", "intersectiontimes", "known", "void", "length", "llcorner", "lrcorner", "makepath", "makepen", "mexp", "mlog", "normaldeviate", "not", "numeric", "oct", "odd", "or", "path", "pair", "pen", "penoffset", "picture", "point", "postcontrol", "precontrol", "reverse", "rotated", "scaled", "shifted", "sind", "slanted", "sqrt", "str", "string", "subpath", "substring", "transform", "transformed", "ulcorner", "uniformdeviate", "unknown", "urcorner", "xpart", "xscaled", "xxpart", "xypart", "ypart", "yscaled", "yxpart", "yypart", "zscaled", "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds", "setgroup", "shipout", "show", "showdependencies", "showtoken", "showvariable", "special", "begingroup", "endgroup", "of", "curl", "tension", "and", "controls", "interpath", "on", "off", "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary", "tertiary", "primarydef", "secondarydef", "tertiarydef", "randomseed", "also", "contour", "doublepath", "withcolor", "withcmykcolor", "withpen", "dashed", "envelope", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif", "within", "forsuffixes", "step", "until", "charlist", "extensible", "fontdimen", "headerbyte", "kern", "ligtable", "boundarychar", "chardp", "charext", "charht", "charic", "charwd", "designsize", "fontmaking", "charexists", "cullit", "currenttransform", "gfcorners", "grayfont", "hround", "imagerules", "lowres_fix", "nodisplays", "notransforms", "openit", "displaying", "currentwindow", "screen_rows", "screen_cols", "pixels_per_inch", "cull", "display", "openwindow", "numspecial", "totalweight", "autorounding", "fillin", "proofing", "tracingpens", "xoffset", "chardx", "granularity", "smoothing", "turningcheck", "yoffset", "chardy", "hppp", "tracingedges", "vppp", "extra_beginfig", "extra_endfig", "mpxbreak", "endinput", "message", "delimiters", "turningnumber", "errmessage", "scantokens", "end", "outer", "inner", "write", "to", "readfrom", "closefrom", "withprescript", "withpostscript", "top", "bot", "lft", "rt", "ulft", "urt", "llft", "lrt", "redpart", "greenpart", "bluepart", "cyanpart", "magentapart", "yellowpart", "blackpart", "prescriptpart", "postscriptpart", "rgbcolor", "cmykcolor", "colormodel", "graypart", "greypart", "greycolor", "graycolor", "dashpart", "penpart", "stroked", "filled", "textual", "clipped", "bounded", "pathpart", "expandafter", "minute", "hour", "outputformat", "outputtemplate", "filenametemplate", "fontmapfile", "fontmapline", "fontpart", "fontsize", "glyph", "restoreclipcolor", "troffmode", "runscript", "maketext", "numbersystem" },
["shortcuts"]={ "..", "...", "--", "---", "&", "\\" },
["tex"]={ "btex", "etex", "verbatimtex" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/data/scite-context-data-tex.lua b/context/data/textadept/context/data/scite-context-data-tex.lua
index 954c06e1c..1091cd2d5 100644
--- a/context/data/textadept/context/data/scite-context-data-tex.lua
+++ b/context/data/textadept/context/data/scite-context-data-tex.lua
@@ -1,9 +1,9 @@
return {
["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" },
["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "readline", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracingnesting", "tracingscantokens", "unexpanded", "unless", "widowpenalties" },
- ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Umiddle", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "aftergrouped", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "boundary", "boxattr", "boxdirection", "boxorientation", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "breakafterdirmode", "catcodetable", "clearmarks", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "efcode", "endlocalcontrol", "etoksapp", "etokspre", "exceptionpenalty", "expanded", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "fixupboxesmode", "fontid", "formatname", "frozen", "futureexpand", "futureexpandis", "futureexpandisap", "gleaders", "glet", "glyphdatafield", "gtoksapp", "gtokspre", "hjcode", "hpack", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimval", "iffrozen", "ifincsname", "ifnumval", "ifprotected", "iftok", "ifusercmd", "immediateassigned", "immediateassignment", "initcatcodetable", "insertht", "internalcodesmode", "lastnamedcs", "lastnodesubtype", "leftghost", "leftmarginkern", "letcharcode", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathnolimitsmode", "matholdmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "noboundary", "nohrule", "nokerns", "noligs", "nospaces", "novrule", "outputbox", "pardirection", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitvmode", "rightghost", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "setfontid", "shapemode", "textdirection", "toksapp", "tokspre", "tpack", "tracingfonts", "vpack", "wordboundary", "xtoksapp", "xtokspre" },
+ ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Umiddle", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "aftergrouped", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "beginlocalcontrol", "boundary", "boxattr", "boxdirection", "boxorientation", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "breakafterdirmode", "catcodetable", "clearmarks", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "efcode", "endlocalcontrol", "etoksapp", "etokspre", "exceptionpenalty", "expanded", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "fixupboxesmode", "fontid", "formatname", "frozen", "futureexpand", "futureexpandis", "futureexpandisap", "gleaders", "glet", "glyphdatafield", "gtoksapp", "gtokspre", "hjcode", "hpack", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimval", "iffrozen", "ifincsname", "ifnumval", "ifprotected", "iftok", "ifusercmd", "immediateassigned", "immediateassignment", "initcatcodetable", "insertht", "internalcodesmode", "lastnamedcs", "lastnodesubtype", "leftghost", "leftmarginkern", "letcharcode", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathlimitsmode", "mathnolimitsmode", "matholdmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "noboundary", "nohrule", "nokerns", "noligs", "nospaces", "novrule", "outputbox", "pardirection", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitvmode", "rightghost", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "setfontid", "shapemode", "textdirection", "toksapp", "tokspre", "tpack", "tracingfonts", "vpack", "wordboundary", "xtoksapp", "xtokspre" },
["omega"]={ "Omegaminorversion", "Omegarevision", "Omegaversion" },
["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmajorversion", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfomitcharset", "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
- ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "or", "orelse", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" },
+ ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "or", "orelse", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "shownodedetails", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" },
["xetex"]={ "XeTeXversion" },
} \ No newline at end of file
diff --git a/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json b/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json
index c43e846d3..1581881eb 100644
--- a/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json
+++ b/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json
@@ -119,7 +119,7 @@
"name" : "context.plain.plain.mps"
},
"primitive" : {
- "match" : "(zscaled|yypart|yxpart|yscaled|ypart|yoffset|yellowpart|year|xypart|xxpart|xscaled|xpart|xoffset|write|withprescript|withpostscript|withpen|within|withcolor|withcmykcolor|warningcheck|vppp|void|vardef|urt|urcorner|until|unknown|uniformdeviate|ulft|ulcorner|turningnumber|turningcheck|truecorners|true|troffmode|transformed|transform|tracingtitles|tracingstats|tracingspecs|tracingrestores|tracingpens|tracingoutput|tracingonline|tracingmacros|tracinglostchars|tracingequations|tracingedges|tracingcommands|tracingchoices|tracingcapsules|totalweight|top|to|time|textual|text|tertiarydef|tertiary|tension|suffix|substring|subpath|stroked|string|str|step|sqrt|special|smoothing|slanted|sind|showvariable|showtoken|showstopping|showdependencies|show|shipout|shifted|setbounds|secondarydef|secondary|screen_rows|screen_cols|scantokens|scaled|save|runscript|rt|rotated|rgbcolor|reverse|restoreclipcolor|redpart|readfrom|randomseed|proofing|prologues|primarydef|primary|prescriptpart|precontrol|postscriptpart|postcontrol|point|pixels_per_inch|picture|penspec|penpart|penoffset|pencircle|pen|pausing|pathpart|path|pair|outputtemplate|outputformat|outer|or|openwindow|openit|on|off|of|odd|oct|numspecial|numeric|numbersystem|nullpicture|notransforms|not|normaldeviate|nodisplays|newinternal|mpxbreak|mpprocset|month|mlog|miterlimit|minute|mexp|message|maketext|makepen|makepath|magentapart|lrt|lrcorner|lowres_fix|llft|llcorner|linejoin|linecap|ligtable|lft|let|length|known|kern|intersectiontimes|interpath|interim|input|inner|infont|imagerules|if|hround|hppp|hour|hex|headerbyte|greypart|greycolor|greenpart|graypart|grayfont|graycolor|granularity|glyph|gfcorners|forsuffixes|forever|for|fontsize|fontsize|fontpart|fontmapline|fontmapfile|fontmaking|fontdimen|floor|fillin|filled|filenametemplate|fi|false|extra_endfig|extra_beginfig|extensible|expr|expandafter|exitif|errmessage|envelope|endinput|endgroup|endfor|enddef|end|elseif|else|doublepath|displaying|display|directiontime|designsize|delimiters|def|decimal|day|dashpart|dashed|cycle|cyanpart|currentwindow|currenttransform|curl|cullit|cull|cosd|controls|contour|colormodel|color|cmykcolor|closefrom|clipped|clip|charwd|charlist|charic|charht|charext|charexists|chardy|chardx|chardp|charcode|char|bounded|boundarychar|bot|bot|boolean|bluepart|blackpart|begingroup|autorounding|arctime|arclength|angle|and|and|also|addto|ASCII)(?=[^a-zA-Z\u005C_@!?-ÿ])",
+ "match" : "(zscaled|yypart|yxpart|yscaled|ypart|yoffset|yellowpart|year|xypart|xxpart|xscaled|xpart|xoffset|write|withprescript|withpostscript|withpen|within|withcolor|withcmykcolor|warningcheck|vppp|void|vardef|urt|urcorner|until|unknown|uniformdeviate|ulft|ulcorner|turningnumber|turningcheck|truecorners|true|troffmode|transformed|transform|tracingtitles|tracingstats|tracingspecs|tracingrestores|tracingpens|tracingoutput|tracingonline|tracingmacros|tracinglostchars|tracingequations|tracingedges|tracingcommands|tracingchoices|tracingcapsules|totalweight|top|to|time|textual|text|tertiarydef|tertiary|tension|suffix|substring|subpath|stroked|string|str|step|sqrt|special|smoothing|slanted|sind|showvariable|showtoken|showstopping|showdependencies|show|shipout|shifted|setgroup|setbounds|secondarydef|secondary|screen_rows|screen_cols|scantokens|scaled|save|runscript|rt|rotated|rgbcolor|reverse|restoreclipcolor|redpart|readfrom|randomseed|proofing|prologues|primarydef|primary|prescriptpart|precontrol|postscriptpart|postcontrol|point|pixels_per_inch|picture|penspec|penpart|penoffset|pencircle|pen|pausing|pathpart|path|pair|outputtemplate|outputformat|outer|or|openwindow|openit|on|off|of|odd|oct|numspecial|numeric|numbersystem|nullpicture|notransforms|not|normaldeviate|nodisplays|newinternal|mpxbreak|mpprocset|month|mlog|miterlimit|minute|mexp|message|maketext|makepen|makepath|magentapart|lrt|lrcorner|lowres_fix|llft|llcorner|linejoin|linecap|ligtable|lft|let|length|known|kern|intersectiontimes|interpath|interim|input|inner|infont|imagerules|if|hround|hppp|hour|hex|headerbyte|greypart|greycolor|greenpart|graypart|grayfont|graycolor|granularity|glyph|gfcorners|forsuffixes|forever|for|fontsize|fontsize|fontpart|fontmapline|fontmapfile|fontmaking|fontdimen|floor|fillin|filled|filenametemplate|fi|false|extra_endfig|extra_beginfig|extensible|expr|expandafter|exitif|errmessage|envelope|endinput|endgroup|endfor|enddef|end|elseif|else|doublepath|displaying|display|directiontime|designsize|delimiters|def|decimal|day|dashpart|dashed|cycle|cyanpart|currentwindow|currenttransform|curl|cullit|cull|cosd|controls|contour|colormodel|color|cmykcolor|closefrom|clipped|clip|charwd|charlist|charic|charht|charext|charexists|chardy|chardx|chardp|charcode|char|bounded|boundarychar|bot|bot|boolean|bluepart|blackpart|begingroup|autorounding|arctime|arclength|angle|and|and|also|addto|ASCII)(?=[^a-zA-Z\u005C_@!?-ÿ])",
"name" : "context.primitive.primitive.mps"
},
"quoted" : {
diff --git a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
index f0667d033..f262324ce 100644
--- a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
+++ b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
@@ -215,7 +215,7 @@
]
},
"primitive" : {
- "match" : "\u005C\u005C(year|xtokspre|xtoksapp|xspaceskip|xleaders|xdef|wordboundary|widowpenalty|widowpenalties|wd|vtop|vss|vsplit|vskip|vsize|vrule|vpack|voffset|vfuzz|vfilneg|vfill|vfil|vcenter|vbox|vbadness|valign|vadjust|uppercase|unvcopy|unvbox|unskip|unpenalty|unless|unkern|unhcopy|unhbox|underline|uchyph|uccode|tracingstats|tracingscantokens|tracingrestores|tracingparagraphs|tracingpages|tracingoutput|tracingonline|tracingnesting|tracingmacros|tracinglostchars|tracingifs|tracinggroups|tracingfonts|tracingcommands|tracingassigns|tpack|topskip|topmarks|topmark|tolerance|tokspre|toksdef|toksapp|toks|time|thinmuskip|thickmuskip|the|textstyle|textfont|textdirection|tabskip|string|splittopskip|splitmaxdepth|splitfirstmarks|splitfirstmark|splitdiscards|splitbotmarks|splitbotmark|span|spaceskip|spacefactor|skipdef|skip|skewchar|showtokens|showthe|showlists|showifs|showgroups|showboxdepth|showboxbreadth|showbox|show|shipout|shapemode|sfcode|setlanguage|setfontid|setbox|scrollmode|scriptstyle|scriptspace|scriptscriptstyle|scriptscriptfont|scriptfont|scantokens|scantextokens|savingvdiscards|savinghyphcodes|savecatcodetable|rpcode|romannumeral|rightskip|rightmarginkern|righthyphenmin|rightghost|right|relpenalty|relax|readline|read|raise|radical|quitvmode|pxdimen|protrusionboundary|protrudechars|prevgraf|prevdepth|pretolerance|prerelpenalty|prehyphenchar|preexhyphenchar|predisplaysize|predisplaypenalty|predisplaygapfactor|predisplaydirection|prebinoppenalty|posthyphenchar|postexhyphenchar|postdisplaypenalty|penalty|pdfximage|pdfxformresources|pdfxformname|pdfxformmargin|pdfxformattr|pdfxform|pdfvorigin|pdfuniqueresname|pdfuniformdeviate|pdftrailerid|pdftrailer|pdftracingfonts|pdfthreadmargin|pdfthread|pdftexversion|pdftexrevision|pdftexbanner|pdfsuppressptexinfo|pdfsuppressoptionalinfo|pdfstartthread|pdfstartlink|pdfsetrandomseed|pdfsetmatrix|pdfsavepos|pdfsave|pdfretval|pdfrestore|pdfreplacefont|pdfrefximage|pdfrefxform|pdfrefobj|pdfrecompress|pdfrandomseed|pdfpxdimen|pdfprotrudechars|pdfprimitive|pdfpkresolution|pdfpkmode|pdfpkfixeddpi|pdfpagewidth|pdfpagesattr|pdfpageresources|pdfpageref|pdfpageheight|pdfpagebox|pdfpageattr|pdfoutput|pdfoutline|pdfomitcidset|pdfomitcharset|pdfobjcompresslevel|pdfobj|pdfnormaldeviate|pdfnoligatures|pdfnames|pdfminorversion|pdfmapline|pdfmapfile|pdfmajorversion|pdfliteral|pdflinkmargin|pdflastypos|pdflastxpos|pdflastximagepages|pdflastximage|pdflastxform|pdflastobj|pdflastlink|pdflastlinedepth|pdflastannot|pdfinsertht|pdfinfoomitdate|pdfinfo|pdfinclusionerrorlevel|pdfinclusioncopyfonts|pdfincludechars|pdfimageresolution|pdfimagehicolor|pdfimagegamma|pdfimageapplygamma|pdfimageaddfilename|pdfignoreunknownimages|pdfignoreddimen|pdfhorigin|pdfglyphtounicode|pdfgentounicode|pdfgamma|pdffontsize|pdffontobjnum|pdffontname|pdffontexpand|pdffontattr|pdffirstlineheight|pdfendthread|pdfendlink|pdfeachlineheight|pdfeachlinedepth|pdfdraftmode|pdfdestmargin|pdfdest|pdfdecimaldigits|pdfcreationdate|pdfcopyfont|pdfcompresslevel|pdfcolorstackinit|pdfcolorstack|pdfcatalog|pdfannot|pdfadjustspacing|pausing|patterns|parskip|parshapelength|parshapeindent|parshapedimen|parshape|parindent|parfillskip|pardirection|par|pagetotal|pagestretch|pageshrink|pagegoal|pagefilstretch|pagefillstretch|pagefilllstretch|pagediscards|pagedepth|overwithdelims|overline|overfullrule|over|outputpenalty|outputbox|output|outer|orelse|or|openin|omit|numexpr|number|nullfont|nulldelimiterspace|novrule|nospaces|normalyear|normalxtokspre|normalxtoksapp|normalxspaceskip|normalxleaders|normalxdef|normalwordboundary|normalwidowpenalty|normalwidowpenalties|normalwd|normalvtop|normalvss|normalvsplit|normalvskip|normalvsize|normalvrule|normalvpack|normalvoffset|normalvfuzz|normalvfilneg|normalvfill|normalvfil|normalvcenter|normalvbox|normalvbadness|normalvalign|normalvadjust|normaluppercase|normalunvcopy|normalunvbox|normalunskip|normalunpenalty|normalunless|normalunkern|normalunhcopy|normalunhbox|normalunexpanded|normalunderline|normaluchyph|normaluccode|normaltracingstats|normaltracingscantokens|normaltracingrestores|normaltracingparagraphs|normaltracingpages|normaltracingoutput|normaltracingonline|normaltracingnesting|normaltracingmacros|normaltracinglostchars|normaltracingifs|normaltracinggroups|normaltracingfonts|normaltracingcommands|normaltracingassigns|normaltpack|normaltopskip|normaltopmarks|normaltopmark|normaltolerance|normaltokspre|normaltoksdef|normaltoksapp|normaltoks|normaltime|normalthinmuskip|normalthickmuskip|normalthe|normaltextstyle|normaltextfont|normaltextdirection|normaltabskip|normalstring|normalsplittopskip|normalsplitmaxdepth|normalsplitfirstmarks|normalsplitfirstmark|normalsplitdiscards|normalsplitbotmarks|normalsplitbotmark|normalspan|normalspaceskip|normalspacefactor|normalskipdef|normalskip|normalskewchar|normalshowtokens|normalshowthe|normalshowlists|normalshowifs|normalshowgroups|normalshowboxdepth|normalshowboxbreadth|normalshowbox|normalshow|normalshipout|normalshapemode|normalsfcode|normalsetlanguage|normalsetfontid|normalsetbox|normalscrollmode|normalscriptstyle|normalscriptspace|normalscriptscriptstyle|normalscriptscriptfont|normalscriptfont|normalscantokens|normalscantextokens|normalsavingvdiscards|normalsavinghyphcodes|normalsavecatcodetable|normalrpcode|normalromannumeral|normalrightskip|normalrightmarginkern|normalrighthyphenmin|normalrightghost|normalright|normalrelpenalty|normalrelax|normalreadline|normalread|normalraise|normalradical|normalquitvmode|normalpxdimen|normalprotrusionboundary|normalprotrudechars|normalprotected|normalprevgraf|normalprevdepth|normalpretolerance|normalprerelpenalty|normalprehyphenchar|normalpreexhyphenchar|normalpredisplaysize|normalpredisplaypenalty|normalpredisplaygapfactor|normalpredisplaydirection|normalprebinoppenalty|normalposthyphenchar|normalpostexhyphenchar|normalpostdisplaypenalty|normalpenalty|normalpdfximage|normalpdfxformresources|normalpdfxformname|normalpdfxformmargin|normalpdfxformattr|normalpdfxform|normalpdfvorigin|normalpdfuniqueresname|normalpdfuniformdeviate|normalpdftrailerid|normalpdftrailer|normalpdftracingfonts|normalpdfthreadmargin|normalpdfthread|normalpdftexversion|normalpdftexrevision|normalpdftexbanner|normalpdfsuppressptexinfo|normalpdfsuppressoptionalinfo|normalpdfstartthread|normalpdfstartlink|normalpdfsetrandomseed|normalpdfsetmatrix|normalpdfsavepos|normalpdfsave|normalpdfretval|normalpdfrestore|normalpdfreplacefont|normalpdfrefximage|normalpdfrefxform|normalpdfrefobj|normalpdfrecompress|normalpdfrandomseed|normalpdfpxdimen|normalpdfprotrudechars|normalpdfprimitive|normalpdfpkresolution|normalpdfpkmode|normalpdfpkfixeddpi|normalpdfpagewidth|normalpdfpagesattr|normalpdfpageresources|normalpdfpageref|normalpdfpageheight|normalpdfpagebox|normalpdfpageattr|normalpdfoutput|normalpdfoutline|normalpdfomitcidset|normalpdfomitcharset|normalpdfobjcompresslevel|normalpdfobj|normalpdfnormaldeviate|normalpdfnoligatures|normalpdfnames|normalpdfminorversion|normalpdfmapline|normalpdfmapfile|normalpdfmajorversion|normalpdfliteral|normalpdflinkmargin|normalpdflastypos|normalpdflastxpos|normalpdflastximagepages|normalpdflastximage|normalpdflastxform|normalpdflastobj|normalpdflastlink|normalpdflastlinedepth|normalpdflastannot|normalpdfinsertht|normalpdfinfoomitdate|normalpdfinfo|normalpdfinclusionerrorlevel|normalpdfinclusioncopyfonts|normalpdfincludechars|normalpdfimageresolution|normalpdfimagehicolor|normalpdfimagegamma|normalpdfimageapplygamma|normalpdfimageaddfilename|normalpdfignoreunknownimages|normalpdfignoreddimen|normalpdfhorigin|normalpdfglyphtounicode|normalpdfgentounicode|normalpdfgamma|normalpdffontsize|normalpdffontobjnum|normalpdffontname|normalpdffontexpand|normalpdffontattr|normalpdffirstlineheight|normalpdfendthread|normalpdfendlink|normalpdfeachlineheight|normalpdfeachlinedepth|normalpdfdraftmode|normalpdfdestmargin|normalpdfdest|normalpdfdecimaldigits|normalpdfcreationdate|normalpdfcopyfont|normalpdfcompresslevel|normalpdfcolorstackinit|normalpdfcolorstack|normalpdfcatalog|normalpdfannot|normalpdfadjustspacing|normalpausing|normalpatterns|normalparskip|normalparshapelength|normalparshapeindent|normalparshapedimen|normalparshape|normalparindent|normalparfillskip|normalpardirection|normalpar|normalpagetotal|normalpagestretch|normalpageshrink|normalpagegoal|normalpagefilstretch|normalpagefillstretch|normalpagefilllstretch|normalpagediscards|normalpagedepth|normaloverwithdelims|normaloverline|normaloverfullrule|normalover|normaloutputpenalty|normaloutputbox|normaloutput|normalouter|normalorelse|normalor|normalopenin|normalomit|normalnumexpr|normalnumber|normalnullfont|normalnulldelimiterspace|normalnovrule|normalnospaces|normalnonstopmode|normalnonscript|normalnolimits|normalnoligs|normalnokerns|normalnoindent|normalnohrule|normalnoexpand|normalnoboundary|normalnoalign|normalnewlinechar|normalmutoglue|normalmuskipdef|normalmuskip|normalmultiply|normalmuexpr|normalmskip|normalmoveright|normalmoveleft|normalmonth|normalmkern|normalmiddle|normalmessage|normalmedmuskip|normalmeaning|normalmaxdepth|normalmaxdeadcycles|normalmathsurroundskip|normalmathsurroundmode|normalmathsurround|normalmathstyle|normalmathscriptsmode|normalmathscriptcharmode|normalmathscriptboxmode|normalmathrulethicknessmode|normalmathrulesmode|normalmathrulesfam|normalmathrel|normalmathpunct|normalmathpenaltiesmode|normalmathord|normalmathopen|normalmathop|normalmatholdmode|normalmathnolimitsmode|normalmathitalicsmode|normalmathinner|normalmathflattenmode|normalmatheqnogapstep|normalmathdisplayskipmode|normalmathdirection|normalmathdelimitersmode|normalmathcode|normalmathclose|normalmathchoice|normalmathchardef|normalmathchar|normalmathbin|normalmathaccent|normalmarks|normalmark|normalmag|normalluatexversion|normalluatexrevision|normalluatexbanner|normalluafunctioncall|normalluafunction|normalluaescapestring|normalluadef|normalluacopyinputnodes|normalluabytecodecall|normalluabytecode|normallpcode|normallowercase|normallower|normallooseness|normallong|normallocalrightbox|normallocalleftbox|normallocalinterlinepenalty|normallocalbrokenpenalty|normallinepenalty|normallinedirection|normallimits|normalletcharcode|normallet|normalleqno|normalleftskip|normalleftmarginkern|normallefthyphenmin|normalleftghost|normalleft|normalleaders|normallccode|normallastskip|normallastpenalty|normallastnodetype|normallastnodesubtype|normallastnamedcs|normallastlinefit|normallastkern|normallastbox|normallanguage|normalkern|normaljobname|normalinternalcodesmode|normalinterlinepenalty|normalinterlinepenalties|normalinteractionmode|normalinsertpenalties|normalinsertht|normalinsert|normalinputlineno|normalinput|normalinitcatcodetable|normalindent|normalimmediateassignment|normalimmediateassigned|normalignorespaces|normalifx|normalifvoid|normalifvmode|normalifvbox|normalifusercmd|normaliftrue|normaliftok|normalifprotected|normalifpdfprimitive|normalifpdfabsnum|normalifpdfabsdim|normalifodd|normalifnumval|normalifnum|normalifmmode|normalifinner|normalifincsname|normalifhmode|normalifhbox|normaliffrozen|normaliffontchar|normaliffalse|normalifeof|normalifdimval|normalifdim|normalifdefined|normalifcstok|normalifcsname|normalifcondition|normalifcmpnum|normalifcmpdim|normalifchknum|normalifchkdim|normalifcat|normalifcase|normalifabsnum|normalifabsdim|normalif|normalhyphenpenaltymode|normalhyphenpenalty|normalhyphenchar|normalhyphenationmin|normalhyphenationbounds|normalhyphenation|normalht|normalhss|normalhskip|normalhsize|normalhrule|normalhpack|normalholdinginserts|normalhoffset|normalhjcode|normalhfuzz|normalhfilneg|normalhfill|normalhfil|normalhbox|normalhbadness|normalhangindent|normalhangafter|normalhalign|normalgtokspre|normalgtoksapp|normalglyphdatafield|normalgluetomu|normalgluestretchorder|normalgluestretch|normalglueshrinkorder|normalglueshrink|normalglueexpr|normalglobaldefs|normalglobal|normalglet|normalgleaders|normalgdef|normalfuturelet|normalfutureexpandisap|normalfutureexpandis|normalfutureexpand|normalfrozen|normalformatname|normalfontname|normalfontid|normalfontdimen|normalfontcharwd|normalfontcharic|normalfontcharht|normalfontchardp|normalfont|normalfloatingpenalty|normalfixupboxesmode|normalfirstvalidlanguage|normalfirstmarks|normalfirstmark|normalfinalhyphendemerits|normalfi|normalfam|normalexplicithyphenpenalty|normalexplicitdiscretionary|normalexpanded|normalexpandafter|normalexhyphenpenalty|normalexhyphenchar|normalexceptionpenalty|normaleveryvbox|normaleverypar|normaleverymath|normaleveryjob|normaleveryhbox|normaleveryeof|normaleverydisplay|normaleverycr|normaletokspre|normaletoksapp|normalescapechar|normalerrorstopmode|normalerrorcontextlines|normalerrmessage|normalerrhelp|normaleqno|normalendlocalcontrol|normalendlinechar|normalendinput|normalendgroup|normalendcsname|normalend|normalemergencystretch|normalelse|normalefcode|normaledef|normaleTeXversion|normaleTeXrevision|normaleTeXminorversion|normaleTeXVersion|normaldump|normaldp|normaldoublehyphendemerits|normaldivide|normaldisplaywidth|normaldisplaywidowpenalty|normaldisplaywidowpenalties|normaldisplaystyle|normaldisplaylimits|normaldisplayindent|normaldiscretionary|normaldirectlua|normaldimexpr|normaldimendef|normaldimen|normaldetokenize|normaldelimitershortfall|normaldelimiterfactor|normaldelimiter|normaldelcode|normaldefaultskewchar|normaldefaulthyphenchar|normaldef|normaldeadcycles|normalday|normalcurrentiftype|normalcurrentiflevel|normalcurrentifbranch|normalcurrentgrouptype|normalcurrentgrouplevel|normalcsstring|normalcsname|normalcrcr|normalcrampedtextstyle|normalcrampedscriptstyle|normalcrampedscriptscriptstyle|normalcrampeddisplaystyle|normalcr|normalcountdef|normalcount|normalcopy|normalcompoundhyphenmode|normalclubpenalty|normalclubpenalties|normalclosein|normalclearmarks|normalcleaders|normalchardef|normalchar|normalcatcodetable|normalcatcode|normalbrokenpenalty|normalbreakafterdirmode|normalboxyoffset|normalboxymove|normalboxxoffset|normalboxxmove|normalboxtotal|normalboxorientation|normalboxmaxdepth|normalboxdirection|normalboxattr|normalbox|normalboundary|normalbotmarks|normalbotmark|normalbinoppenalty|normalbelowdisplayskip|normalbelowdisplayshortskip|normalbegingroup|normalbegincsname|normalbatchmode|normalbadness|normalautomatichyphenpenalty|normalautomatichyphenmode|normalautomaticdiscretionary|normalattributedef|normalattribute|normalatopwithdelims|normalatop|normalaligntab|normalalignmark|normalaftergrouped|normalaftergroup|normalafterassignment|normaladvance|normaladjustspacing|normaladjdemerits|normalaccent|normalabovewithdelims|normalabovedisplayskip|normalabovedisplayshortskip|normalabove|normalXeTeXversion|normalUvextensible|normalUunderdelimiter|normalUsuperscript|normalUsubscript|normalUstopmath|normalUstopdisplaymath|normalUstartmath|normalUstartdisplaymath|normalUstack|normalUskewedwithdelims|normalUskewed|normalUroot|normalUright|normalUradical|normalUoverdelimiter|normalUnosuperscript|normalUnosubscript|normalUmiddle|normalUmathunderdelimitervgap|normalUmathunderdelimiterbgap|normalUmathunderbarvgap|normalUmathunderbarrule|normalUmathunderbarkern|normalUmathsupsubbottommax|normalUmathsupshiftup|normalUmathsupshiftdrop|normalUmathsupbottommin|normalUmathsubtopmax|normalUmathsubsupvgap|normalUmathsubsupshiftdown|normalUmathsubshiftdrop|normalUmathsubshiftdown|normalUmathstackvgap|normalUmathstacknumup|normalUmathstackdenomdown|normalUmathspaceafterscript|normalUmathskewedfractionvgap|normalUmathskewedfractionhgap|normalUmathrelrelspacing|normalUmathrelpunctspacing|normalUmathrelordspacing|normalUmathrelopspacing|normalUmathrelopenspacing|normalUmathrelinnerspacing|normalUmathrelclosespacing|normalUmathrelbinspacing|normalUmathradicalvgap|normalUmathradicalrule|normalUmathradicalkern|normalUmathradicaldegreeraise|normalUmathradicaldegreebefore|normalUmathradicaldegreeafter|normalUmathquad|normalUmathpunctrelspacing|normalUmathpunctpunctspacing|normalUmathpunctordspacing|normalUmathpunctopspacing|normalUmathpunctopenspacing|normalUmathpunctinnerspacing|normalUmathpunctclosespacing|normalUmathpunctbinspacing|normalUmathoverdelimitervgap|normalUmathoverdelimiterbgap|normalUmathoverbarvgap|normalUmathoverbarrule|normalUmathoverbarkern|normalUmathordrelspacing|normalUmathordpunctspacing|normalUmathordordspacing|normalUmathordopspacing|normalUmathordopenspacing|normalUmathordinnerspacing|normalUmathordclosespacing|normalUmathordbinspacing|normalUmathoprelspacing|normalUmathoppunctspacing|normalUmathopordspacing|normalUmathopopspacing|normalUmathopopenspacing|normalUmathopinnerspacing|normalUmathoperatorsize|normalUmathopenrelspacing|normalUmathopenpunctspacing|normalUmathopenordspacing|normalUmathopenopspacing|normalUmathopenopenspacing|normalUmathopeninnerspacing|normalUmathopenclosespacing|normalUmathopenbinspacing|normalUmathopclosespacing|normalUmathopbinspacing|normalUmathnolimitsupfactor|normalUmathnolimitsubfactor|normalUmathlimitbelowvgap|normalUmathlimitbelowkern|normalUmathlimitbelowbgap|normalUmathlimitabovevgap|normalUmathlimitabovekern|normalUmathlimitabovebgap|normalUmathinnerrelspacing|normalUmathinnerpunctspacing|normalUmathinnerordspacing|normalUmathinneropspacing|normalUmathinneropenspacing|normalUmathinnerinnerspacing|normalUmathinnerclosespacing|normalUmathinnerbinspacing|normalUmathfractionrule|normalUmathfractionnumvgap|normalUmathfractionnumup|normalUmathfractiondenomvgap|normalUmathfractiondenomdown|normalUmathfractiondelsize|normalUmathconnectoroverlapmin|normalUmathcodenum|normalUmathcode|normalUmathcloserelspacing|normalUmathclosepunctspacing|normalUmathcloseordspacing|normalUmathcloseopspacing|normalUmathcloseopenspacing|normalUmathcloseinnerspacing|normalUmathcloseclosespacing|normalUmathclosebinspacing|normalUmathcharslot|normalUmathcharnumdef|normalUmathcharnum|normalUmathcharfam|normalUmathchardef|normalUmathcharclass|normalUmathchar|normalUmathbinrelspacing|normalUmathbinpunctspacing|normalUmathbinordspacing|normalUmathbinopspacing|normalUmathbinopenspacing|normalUmathbininnerspacing|normalUmathbinclosespacing|normalUmathbinbinspacing|normalUmathaxis|normalUmathaccent|normalUleft|normalUhextensible|normalUdelimiterunder|normalUdelimiterover|normalUdelimiter|normalUdelcodenum|normalUdelcode|normalUchar|normalOmegaversion|normalOmegarevision|normalOmegaminorversion|normalAlephversion|normalAlephrevision|normalAlephminorversion|normal |nonstopmode|nonscript|nolimits|noligs|nokerns|noindent|nohrule|noexpand|noboundary|noalign|newlinechar|mutoglue|muskipdef|muskip|multiply|muexpr|mskip|moveright|moveleft|month|mkern|middle|message|medmuskip|meaning|maxdepth|maxdeadcycles|mathsurroundskip|mathsurroundmode|mathsurround|mathstyle|mathscriptsmode|mathscriptcharmode|mathscriptboxmode|mathrulethicknessmode|mathrulesmode|mathrulesfam|mathrel|mathpunct|mathpenaltiesmode|mathord|mathopen|mathop|matholdmode|mathnolimitsmode|mathitalicsmode|mathinner|mathflattenmode|matheqnogapstep|mathdisplayskipmode|mathdirection|mathdelimitersmode|mathcode|mathclose|mathchoice|mathchardef|mathchar|mathbin|mathaccent|marks|mark|mag|luatexversion|luatexrevision|luatexbanner|luafunctioncall|luafunction|luaescapestring|luadef|luacopyinputnodes|luabytecodecall|luabytecode|lpcode|lowercase|lower|looseness|long|localrightbox|localleftbox|localinterlinepenalty|localbrokenpenalty|lineskiplimit|lineskip|linepenalty|linedirection|limits|letcharcode|let|leqno|leftskip|leftmarginkern|lefthyphenmin|leftghost|left|leaders|lccode|lastskip|lastpenalty|lastnodetype|lastnodesubtype|lastnamedcs|lastlinefit|lastkern|lastbox|language|kern|jobname|internalcodesmode|interlinepenalty|interlinepenalties|interactionmode|insertpenalties|insertht|insert|inputlineno|input|initcatcodetable|indent|immediateassignment|immediateassigned|ignorespaces|ifx|ifvoid|ifvmode|ifvbox|ifusercmd|iftrue|iftok|ifprotected|ifpdfprimitive|ifpdfabsnum|ifpdfabsdim|ifodd|ifnumval|ifnum|ifmmode|ifinner|ifincsname|ifhmode|ifhbox|iffrozen|iffontchar|iffalse|ifeof|ifdimval|ifdim|ifdefined|ifcstok|ifcsname|ifcondition|ifcmpnum|ifcmpdim|ifchknum|ifchkdim|ifcat|ifcase|ifabsnum|ifabsdim|if|hyphenpenaltymode|hyphenpenalty|hyphenchar|hyphenationmin|hyphenationbounds|hyphenation|ht|hss|hskip|hsize|hrule|hpack|holdinginserts|hoffset|hjcode|hfuzz|hfilneg|hfill|hfil|hbox|hbadness|hangindent|hangafter|halign|gtokspre|gtoksapp|glyphdatafield|gluetomu|gluestretchorder|gluestretch|glueshrinkorder|glueshrink|glueexpr|globaldefs|global|gleaders|gdef|futurelet|futureexpandisap|futureexpandis|futureexpand|frozen|formatname|fontname|fontid|fontdimen|fontcharwd|fontcharic|fontcharht|fontchardp|font|floatingpenalty|fixupboxesmode|firstvalidlanguage|firstmarks|firstmark|finalhyphendemerits|fi|fam|explicithyphenpenalty|explicitdiscretionary|expandafter|exhyphenpenalty|exhyphenchar|exceptionpenalty|everyvbox|everypar|everymath|everyjob|everyhbox|everyeof|everydisplay|everycr|etokspre|etoksapp|escapechar|errorstopmode|errorcontextlines|errmessage|errhelp|eqno|endlocalcontrol|endlinechar|endinput|endgroup|endcsname|end|emergencystretch|else|efcode|edef|eTeXversion|eTeXrevision|eTeXminorversion|eTeXVersion|dump|dp|doublehyphendemerits|divide|displaywidth|displaywidowpenalty|displaywidowpenalties|displaystyle|displaylimits|displayindent|discretionary|directlua|dimexpr|dimendef|dimen|detokenize|delimitershortfall|delimiterfactor|delimiter|delcode|defaultskewchar|defaulthyphenchar|def|deadcycles|day|currentiftype|currentiflevel|currentifbranch|currentgrouptype|currentgrouplevel|csstring|csname|crcr|crampedtextstyle|crampedscriptstyle|crampedscriptscriptstyle|crampeddisplaystyle|cr|countdef|count|copy|compoundhyphenmode|clubpenalty|clubpenalties|closein|clearmarks|cleaders|chardef|char|catcodetable|catcode|brokenpenalty|breakafterdirmode|boxyoffset|boxymove|boxxoffset|boxxmove|boxtotal|boxorientation|boxmaxdepth|boxdirection|boxattr|box|boundary|botmarks|botmark|binoppenalty|belowdisplayskip|belowdisplayshortskip|begingroup|begincsname|batchmode|baselineskip|badness|automatichyphenpenalty|automatichyphenmode|automaticdiscretionary|attributedef|attribute|atopwithdelims|atop|aligntab|alignmark|aftergrouped|aftergroup|afterassignment|advance|adjustspacing|adjdemerits|accent|abovewithdelims|abovedisplayskip|abovedisplayshortskip|above|XeTeXversion|Uvextensible|Uunderdelimiter|Usuperscript|Usubscript|Ustopmath|Ustopdisplaymath|Ustartmath|Ustartdisplaymath|Ustack|Uskewedwithdelims|Uskewed|Uroot|Uright|Uradical|Uoverdelimiter|Unosuperscript|Unosubscript|Umiddle|Umathunderdelimitervgap|Umathunderdelimiterbgap|Umathunderbarvgap|Umathunderbarrule|Umathunderbarkern|Umathsupsubbottommax|Umathsupshiftup|Umathsupshiftdrop|Umathsupbottommin|Umathsubtopmax|Umathsubsupvgap|Umathsubsupshiftdown|Umathsubshiftdrop|Umathsubshiftdown|Umathstackvgap|Umathstacknumup|Umathstackdenomdown|Umathspaceafterscript|Umathskewedfractionvgap|Umathskewedfractionhgap|Umathrelrelspacing|Umathrelpunctspacing|Umathrelordspacing|Umathrelopspacing|Umathrelopenspacing|Umathrelinnerspacing|Umathrelclosespacing|Umathrelbinspacing|Umathradicalvgap|Umathradicalrule|Umathradicalkern|Umathradicaldegreeraise|Umathradicaldegreebefore|Umathradicaldegreeafter|Umathquad|Umathpunctrelspacing|Umathpunctpunctspacing|Umathpunctordspacing|Umathpunctopspacing|Umathpunctopenspacing|Umathpunctinnerspacing|Umathpunctclosespacing|Umathpunctbinspacing|Umathoverdelimitervgap|Umathoverdelimiterbgap|Umathoverbarvgap|Umathoverbarrule|Umathoverbarkern|Umathordrelspacing|Umathordpunctspacing|Umathordordspacing|Umathordopspacing|Umathordopenspacing|Umathordinnerspacing|Umathordclosespacing|Umathordbinspacing|Umathoprelspacing|Umathoppunctspacing|Umathopordspacing|Umathopopspacing|Umathopopenspacing|Umathopinnerspacing|Umathoperatorsize|Umathopenrelspacing|Umathopenpunctspacing|Umathopenordspacing|Umathopenopspacing|Umathopenopenspacing|Umathopeninnerspacing|Umathopenclosespacing|Umathopenbinspacing|Umathopclosespacing|Umathopbinspacing|Umathnolimitsupfactor|Umathnolimitsubfactor|Umathlimitbelowvgap|Umathlimitbelowkern|Umathlimitbelowbgap|Umathlimitabovevgap|Umathlimitabovekern|Umathlimitabovebgap|Umathinnerrelspacing|Umathinnerpunctspacing|Umathinnerordspacing|Umathinneropspacing|Umathinneropenspacing|Umathinnerinnerspacing|Umathinnerclosespacing|Umathinnerbinspacing|Umathfractionrule|Umathfractionnumvgap|Umathfractionnumup|Umathfractiondenomvgap|Umathfractiondenomdown|Umathfractiondelsize|Umathconnectoroverlapmin|Umathcodenum|Umathcode|Umathcloserelspacing|Umathclosepunctspacing|Umathcloseordspacing|Umathcloseopspacing|Umathcloseopenspacing|Umathcloseinnerspacing|Umathcloseclosespacing|Umathclosebinspacing|Umathcharslot|Umathcharnumdef|Umathcharnum|Umathcharfam|Umathchardef|Umathcharclass|Umathchar|Umathbinrelspacing|Umathbinpunctspacing|Umathbinordspacing|Umathbinopspacing|Umathbinopenspacing|Umathbininnerspacing|Umathbinclosespacing|Umathbinbinspacing|Umathaxis|Umathaccent|Uleft|Uhextensible|Udelimiterunder|Udelimiterover|Udelimiter|Udelcodenum|Udelcode|Uchar|Omegaversion|Omegarevision|Omegaminorversion|Alephversion|Alephrevision|Alephminorversion| )(?=[^a-zA-Z])",
+ "match" : "\u005C\u005C(year|xtokspre|xtoksapp|xspaceskip|xleaders|xdef|wordboundary|widowpenalty|widowpenalties|wd|vtop|vss|vsplit|vskip|vsize|vrule|vpack|voffset|vfuzz|vfilneg|vfill|vfil|vcenter|vbox|vbadness|valign|vadjust|uppercase|unvcopy|unvbox|unskip|unpenalty|unless|unkern|unhcopy|unhbox|underline|uchyph|uccode|tracingstats|tracingscantokens|tracingrestores|tracingparagraphs|tracingpages|tracingoutput|tracingonline|tracingnesting|tracingmacros|tracinglostchars|tracingifs|tracinggroups|tracingfonts|tracingcommands|tracingassigns|tpack|topskip|topmarks|topmark|tolerance|tokspre|toksdef|toksapp|toks|time|thinmuskip|thickmuskip|the|textstyle|textfont|textdirection|tabskip|string|splittopskip|splitmaxdepth|splitfirstmarks|splitfirstmark|splitdiscards|splitbotmarks|splitbotmark|span|spaceskip|spacefactor|skipdef|skip|skewchar|showtokens|showthe|shownodedetails|showlists|showifs|showgroups|showboxdepth|showboxbreadth|showbox|show|shipout|shapemode|sfcode|setlanguage|setfontid|setbox|scrollmode|scriptstyle|scriptspace|scriptscriptstyle|scriptscriptfont|scriptfont|scantokens|scantextokens|savingvdiscards|savinghyphcodes|savecatcodetable|rpcode|romannumeral|rightskip|rightmarginkern|righthyphenmin|rightghost|right|relpenalty|relax|readline|read|raise|radical|quitvmode|pxdimen|protrusionboundary|protrudechars|prevgraf|prevdepth|pretolerance|prerelpenalty|prehyphenchar|preexhyphenchar|predisplaysize|predisplaypenalty|predisplaygapfactor|predisplaydirection|prebinoppenalty|posthyphenchar|postexhyphenchar|postdisplaypenalty|penalty|pdfximage|pdfxformresources|pdfxformname|pdfxformmargin|pdfxformattr|pdfxform|pdfvorigin|pdfuniqueresname|pdfuniformdeviate|pdftrailerid|pdftrailer|pdftracingfonts|pdfthreadmargin|pdfthread|pdftexversion|pdftexrevision|pdftexbanner|pdfsuppressptexinfo|pdfsuppressoptionalinfo|pdfstartthread|pdfstartlink|pdfsetrandomseed|pdfsetmatrix|pdfsavepos|pdfsave|pdfretval|pdfrestore|pdfreplacefont|pdfrefximage|pdfrefxform|pdfrefobj|pdfrecompress|pdfrandomseed|pdfpxdimen|pdfprotrudechars|pdfprimitive|pdfpkresolution|pdfpkmode|pdfpkfixeddpi|pdfpagewidth|pdfpagesattr|pdfpageresources|pdfpageref|pdfpageheight|pdfpagebox|pdfpageattr|pdfoutput|pdfoutline|pdfomitcidset|pdfomitcharset|pdfobjcompresslevel|pdfobj|pdfnormaldeviate|pdfnoligatures|pdfnames|pdfminorversion|pdfmapline|pdfmapfile|pdfmajorversion|pdfliteral|pdflinkmargin|pdflastypos|pdflastxpos|pdflastximagepages|pdflastximage|pdflastxform|pdflastobj|pdflastlink|pdflastlinedepth|pdflastannot|pdfinsertht|pdfinfoomitdate|pdfinfo|pdfinclusionerrorlevel|pdfinclusioncopyfonts|pdfincludechars|pdfimageresolution|pdfimagehicolor|pdfimagegamma|pdfimageapplygamma|pdfimageaddfilename|pdfignoreunknownimages|pdfignoreddimen|pdfhorigin|pdfglyphtounicode|pdfgentounicode|pdfgamma|pdffontsize|pdffontobjnum|pdffontname|pdffontexpand|pdffontattr|pdffirstlineheight|pdfendthread|pdfendlink|pdfeachlineheight|pdfeachlinedepth|pdfdraftmode|pdfdestmargin|pdfdest|pdfdecimaldigits|pdfcreationdate|pdfcopyfont|pdfcompresslevel|pdfcolorstackinit|pdfcolorstack|pdfcatalog|pdfannot|pdfadjustspacing|pausing|patterns|parskip|parshapelength|parshapeindent|parshapedimen|parshape|parindent|parfillskip|pardirection|par|pagetotal|pagestretch|pageshrink|pagegoal|pagefilstretch|pagefillstretch|pagefilllstretch|pagediscards|pagedepth|overwithdelims|overline|overfullrule|over|outputpenalty|outputbox|output|outer|orelse|or|openin|omit|numexpr|number|nullfont|nulldelimiterspace|novrule|nospaces|normalyear|normalxtokspre|normalxtoksapp|normalxspaceskip|normalxleaders|normalxdef|normalwordboundary|normalwidowpenalty|normalwidowpenalties|normalwd|normalvtop|normalvss|normalvsplit|normalvskip|normalvsize|normalvrule|normalvpack|normalvoffset|normalvfuzz|normalvfilneg|normalvfill|normalvfil|normalvcenter|normalvbox|normalvbadness|normalvalign|normalvadjust|normaluppercase|normalunvcopy|normalunvbox|normalunskip|normalunpenalty|normalunless|normalunkern|normalunhcopy|normalunhbox|normalunexpanded|normalunderline|normaluchyph|normaluccode|normaltracingstats|normaltracingscantokens|normaltracingrestores|normaltracingparagraphs|normaltracingpages|normaltracingoutput|normaltracingonline|normaltracingnesting|normaltracingmacros|normaltracinglostchars|normaltracingifs|normaltracinggroups|normaltracingfonts|normaltracingcommands|normaltracingassigns|normaltpack|normaltopskip|normaltopmarks|normaltopmark|normaltolerance|normaltokspre|normaltoksdef|normaltoksapp|normaltoks|normaltime|normalthinmuskip|normalthickmuskip|normalthe|normaltextstyle|normaltextfont|normaltextdirection|normaltabskip|normalstring|normalsplittopskip|normalsplitmaxdepth|normalsplitfirstmarks|normalsplitfirstmark|normalsplitdiscards|normalsplitbotmarks|normalsplitbotmark|normalspan|normalspaceskip|normalspacefactor|normalskipdef|normalskip|normalskewchar|normalshowtokens|normalshowthe|normalshownodedetails|normalshowlists|normalshowifs|normalshowgroups|normalshowboxdepth|normalshowboxbreadth|normalshowbox|normalshow|normalshipout|normalshapemode|normalsfcode|normalsetlanguage|normalsetfontid|normalsetbox|normalscrollmode|normalscriptstyle|normalscriptspace|normalscriptscriptstyle|normalscriptscriptfont|normalscriptfont|normalscantokens|normalscantextokens|normalsavingvdiscards|normalsavinghyphcodes|normalsavecatcodetable|normalrpcode|normalromannumeral|normalrightskip|normalrightmarginkern|normalrighthyphenmin|normalrightghost|normalright|normalrelpenalty|normalrelax|normalreadline|normalread|normalraise|normalradical|normalquitvmode|normalpxdimen|normalprotrusionboundary|normalprotrudechars|normalprotected|normalprevgraf|normalprevdepth|normalpretolerance|normalprerelpenalty|normalprehyphenchar|normalpreexhyphenchar|normalpredisplaysize|normalpredisplaypenalty|normalpredisplaygapfactor|normalpredisplaydirection|normalprebinoppenalty|normalposthyphenchar|normalpostexhyphenchar|normalpostdisplaypenalty|normalpenalty|normalpdfximage|normalpdfxformresources|normalpdfxformname|normalpdfxformmargin|normalpdfxformattr|normalpdfxform|normalpdfvorigin|normalpdfuniqueresname|normalpdfuniformdeviate|normalpdftrailerid|normalpdftrailer|normalpdftracingfonts|normalpdfthreadmargin|normalpdfthread|normalpdftexversion|normalpdftexrevision|normalpdftexbanner|normalpdfsuppressptexinfo|normalpdfsuppressoptionalinfo|normalpdfstartthread|normalpdfstartlink|normalpdfsetrandomseed|normalpdfsetmatrix|normalpdfsavepos|normalpdfsave|normalpdfretval|normalpdfrestore|normalpdfreplacefont|normalpdfrefximage|normalpdfrefxform|normalpdfrefobj|normalpdfrecompress|normalpdfrandomseed|normalpdfpxdimen|normalpdfprotrudechars|normalpdfprimitive|normalpdfpkresolution|normalpdfpkmode|normalpdfpkfixeddpi|normalpdfpagewidth|normalpdfpagesattr|normalpdfpageresources|normalpdfpageref|normalpdfpageheight|normalpdfpagebox|normalpdfpageattr|normalpdfoutput|normalpdfoutline|normalpdfomitcidset|normalpdfomitcharset|normalpdfobjcompresslevel|normalpdfobj|normalpdfnormaldeviate|normalpdfnoligatures|normalpdfnames|normalpdfminorversion|normalpdfmapline|normalpdfmapfile|normalpdfmajorversion|normalpdfliteral|normalpdflinkmargin|normalpdflastypos|normalpdflastxpos|normalpdflastximagepages|normalpdflastximage|normalpdflastxform|normalpdflastobj|normalpdflastlink|normalpdflastlinedepth|normalpdflastannot|normalpdfinsertht|normalpdfinfoomitdate|normalpdfinfo|normalpdfinclusionerrorlevel|normalpdfinclusioncopyfonts|normalpdfincludechars|normalpdfimageresolution|normalpdfimagehicolor|normalpdfimagegamma|normalpdfimageapplygamma|normalpdfimageaddfilename|normalpdfignoreunknownimages|normalpdfignoreddimen|normalpdfhorigin|normalpdfglyphtounicode|normalpdfgentounicode|normalpdfgamma|normalpdffontsize|normalpdffontobjnum|normalpdffontname|normalpdffontexpand|normalpdffontattr|normalpdffirstlineheight|normalpdfendthread|normalpdfendlink|normalpdfeachlineheight|normalpdfeachlinedepth|normalpdfdraftmode|normalpdfdestmargin|normalpdfdest|normalpdfdecimaldigits|normalpdfcreationdate|normalpdfcopyfont|normalpdfcompresslevel|normalpdfcolorstackinit|normalpdfcolorstack|normalpdfcatalog|normalpdfannot|normalpdfadjustspacing|normalpausing|normalpatterns|normalparskip|normalparshapelength|normalparshapeindent|normalparshapedimen|normalparshape|normalparindent|normalparfillskip|normalpardirection|normalpar|normalpagetotal|normalpagestretch|normalpageshrink|normalpagegoal|normalpagefilstretch|normalpagefillstretch|normalpagefilllstretch|normalpagediscards|normalpagedepth|normaloverwithdelims|normaloverline|normaloverfullrule|normalover|normaloutputpenalty|normaloutputbox|normaloutput|normalouter|normalorelse|normalor|normalopenin|normalomit|normalnumexpr|normalnumber|normalnullfont|normalnulldelimiterspace|normalnovrule|normalnospaces|normalnonstopmode|normalnonscript|normalnolimits|normalnoligs|normalnokerns|normalnoindent|normalnohrule|normalnoexpand|normalnoboundary|normalnoalign|normalnewlinechar|normalmutoglue|normalmuskipdef|normalmuskip|normalmultiply|normalmuexpr|normalmskip|normalmoveright|normalmoveleft|normalmonth|normalmkern|normalmiddle|normalmessage|normalmedmuskip|normalmeaning|normalmaxdepth|normalmaxdeadcycles|normalmathsurroundskip|normalmathsurroundmode|normalmathsurround|normalmathstyle|normalmathscriptsmode|normalmathscriptcharmode|normalmathscriptboxmode|normalmathrulethicknessmode|normalmathrulesmode|normalmathrulesfam|normalmathrel|normalmathpunct|normalmathpenaltiesmode|normalmathord|normalmathopen|normalmathop|normalmatholdmode|normalmathnolimitsmode|normalmathlimitsmode|normalmathitalicsmode|normalmathinner|normalmathflattenmode|normalmatheqnogapstep|normalmathdisplayskipmode|normalmathdirection|normalmathdelimitersmode|normalmathcode|normalmathclose|normalmathchoice|normalmathchardef|normalmathchar|normalmathbin|normalmathaccent|normalmarks|normalmark|normalmag|normalluatexversion|normalluatexrevision|normalluatexbanner|normalluafunctioncall|normalluafunction|normalluaescapestring|normalluadef|normalluacopyinputnodes|normalluabytecodecall|normalluabytecode|normallpcode|normallowercase|normallower|normallooseness|normallong|normallocalrightbox|normallocalleftbox|normallocalinterlinepenalty|normallocalbrokenpenalty|normallinepenalty|normallinedirection|normallimits|normalletcharcode|normallet|normalleqno|normalleftskip|normalleftmarginkern|normallefthyphenmin|normalleftghost|normalleft|normalleaders|normallccode|normallastskip|normallastpenalty|normallastnodetype|normallastnodesubtype|normallastnamedcs|normallastlinefit|normallastkern|normallastbox|normallanguage|normalkern|normaljobname|normalinternalcodesmode|normalinterlinepenalty|normalinterlinepenalties|normalinteractionmode|normalinsertpenalties|normalinsertht|normalinsert|normalinputlineno|normalinput|normalinitcatcodetable|normalindent|normalimmediateassignment|normalimmediateassigned|normalignorespaces|normalifx|normalifvoid|normalifvmode|normalifvbox|normalifusercmd|normaliftrue|normaliftok|normalifprotected|normalifpdfprimitive|normalifpdfabsnum|normalifpdfabsdim|normalifodd|normalifnumval|normalifnum|normalifmmode|normalifinner|normalifincsname|normalifhmode|normalifhbox|normaliffrozen|normaliffontchar|normaliffalse|normalifeof|normalifdimval|normalifdim|normalifdefined|normalifcstok|normalifcsname|normalifcondition|normalifcmpnum|normalifcmpdim|normalifchknum|normalifchkdim|normalifcat|normalifcase|normalifabsnum|normalifabsdim|normalif|normalhyphenpenaltymode|normalhyphenpenalty|normalhyphenchar|normalhyphenationmin|normalhyphenationbounds|normalhyphenation|normalht|normalhss|normalhskip|normalhsize|normalhrule|normalhpack|normalholdinginserts|normalhoffset|normalhjcode|normalhfuzz|normalhfilneg|normalhfill|normalhfil|normalhbox|normalhbadness|normalhangindent|normalhangafter|normalhalign|normalgtokspre|normalgtoksapp|normalglyphdatafield|normalgluetomu|normalgluestretchorder|normalgluestretch|normalglueshrinkorder|normalglueshrink|normalglueexpr|normalglobaldefs|normalglobal|normalglet|normalgleaders|normalgdef|normalfuturelet|normalfutureexpandisap|normalfutureexpandis|normalfutureexpand|normalfrozen|normalformatname|normalfontname|normalfontid|normalfontdimen|normalfontcharwd|normalfontcharic|normalfontcharht|normalfontchardp|normalfont|normalfloatingpenalty|normalfixupboxesmode|normalfirstvalidlanguage|normalfirstmarks|normalfirstmark|normalfinalhyphendemerits|normalfi|normalfam|normalexplicithyphenpenalty|normalexplicitdiscretionary|normalexpanded|normalexpandafter|normalexhyphenpenalty|normalexhyphenchar|normalexceptionpenalty|normaleveryvbox|normaleverypar|normaleverymath|normaleveryjob|normaleveryhbox|normaleveryeof|normaleverydisplay|normaleverycr|normaletokspre|normaletoksapp|normalescapechar|normalerrorstopmode|normalerrorcontextlines|normalerrmessage|normalerrhelp|normaleqno|normalendlocalcontrol|normalendlinechar|normalendinput|normalendgroup|normalendcsname|normalend|normalemergencystretch|normalelse|normalefcode|normaledef|normaleTeXversion|normaleTeXrevision|normaleTeXminorversion|normaleTeXVersion|normaldump|normaldp|normaldoublehyphendemerits|normaldivide|normaldisplaywidth|normaldisplaywidowpenalty|normaldisplaywidowpenalties|normaldisplaystyle|normaldisplaylimits|normaldisplayindent|normaldiscretionary|normaldirectlua|normaldimexpr|normaldimendef|normaldimen|normaldetokenize|normaldelimitershortfall|normaldelimiterfactor|normaldelimiter|normaldelcode|normaldefaultskewchar|normaldefaulthyphenchar|normaldef|normaldeadcycles|normalday|normalcurrentiftype|normalcurrentiflevel|normalcurrentifbranch|normalcurrentgrouptype|normalcurrentgrouplevel|normalcsstring|normalcsname|normalcrcr|normalcrampedtextstyle|normalcrampedscriptstyle|normalcrampedscriptscriptstyle|normalcrampeddisplaystyle|normalcr|normalcountdef|normalcount|normalcopy|normalcompoundhyphenmode|normalclubpenalty|normalclubpenalties|normalclosein|normalclearmarks|normalcleaders|normalchardef|normalchar|normalcatcodetable|normalcatcode|normalbrokenpenalty|normalbreakafterdirmode|normalboxyoffset|normalboxymove|normalboxxoffset|normalboxxmove|normalboxtotal|normalboxorientation|normalboxmaxdepth|normalboxdirection|normalboxattr|normalbox|normalboundary|normalbotmarks|normalbotmark|normalbinoppenalty|normalbelowdisplayskip|normalbelowdisplayshortskip|normalbeginlocalcontrol|normalbegingroup|normalbegincsname|normalbatchmode|normalbadness|normalautomatichyphenpenalty|normalautomatichyphenmode|normalautomaticdiscretionary|normalattributedef|normalattribute|normalatopwithdelims|normalatop|normalaligntab|normalalignmark|normalaftergrouped|normalaftergroup|normalafterassignment|normaladvance|normaladjustspacing|normaladjdemerits|normalaccent|normalabovewithdelims|normalabovedisplayskip|normalabovedisplayshortskip|normalabove|normalXeTeXversion|normalUvextensible|normalUunderdelimiter|normalUsuperscript|normalUsubscript|normalUstopmath|normalUstopdisplaymath|normalUstartmath|normalUstartdisplaymath|normalUstack|normalUskewedwithdelims|normalUskewed|normalUroot|normalUright|normalUradical|normalUoverdelimiter|normalUnosuperscript|normalUnosubscript|normalUmiddle|normalUmathunderdelimitervgap|normalUmathunderdelimiterbgap|normalUmathunderbarvgap|normalUmathunderbarrule|normalUmathunderbarkern|normalUmathsupsubbottommax|normalUmathsupshiftup|normalUmathsupshiftdrop|normalUmathsupbottommin|normalUmathsubtopmax|normalUmathsubsupvgap|normalUmathsubsupshiftdown|normalUmathsubshiftdrop|normalUmathsubshiftdown|normalUmathstackvgap|normalUmathstacknumup|normalUmathstackdenomdown|normalUmathspaceafterscript|normalUmathskewedfractionvgap|normalUmathskewedfractionhgap|normalUmathrelrelspacing|normalUmathrelpunctspacing|normalUmathrelordspacing|normalUmathrelopspacing|normalUmathrelopenspacing|normalUmathrelinnerspacing|normalUmathrelclosespacing|normalUmathrelbinspacing|normalUmathradicalvgap|normalUmathradicalrule|normalUmathradicalkern|normalUmathradicaldegreeraise|normalUmathradicaldegreebefore|normalUmathradicaldegreeafter|normalUmathquad|normalUmathpunctrelspacing|normalUmathpunctpunctspacing|normalUmathpunctordspacing|normalUmathpunctopspacing|normalUmathpunctopenspacing|normalUmathpunctinnerspacing|normalUmathpunctclosespacing|normalUmathpunctbinspacing|normalUmathoverdelimitervgap|normalUmathoverdelimiterbgap|normalUmathoverbarvgap|normalUmathoverbarrule|normalUmathoverbarkern|normalUmathordrelspacing|normalUmathordpunctspacing|normalUmathordordspacing|normalUmathordopspacing|normalUmathordopenspacing|normalUmathordinnerspacing|normalUmathordclosespacing|normalUmathordbinspacing|normalUmathoprelspacing|normalUmathoppunctspacing|normalUmathopordspacing|normalUmathopopspacing|normalUmathopopenspacing|normalUmathopinnerspacing|normalUmathoperatorsize|normalUmathopenrelspacing|normalUmathopenpunctspacing|normalUmathopenordspacing|normalUmathopenopspacing|normalUmathopenopenspacing|normalUmathopeninnerspacing|normalUmathopenclosespacing|normalUmathopenbinspacing|normalUmathopclosespacing|normalUmathopbinspacing|normalUmathnolimitsupfactor|normalUmathnolimitsubfactor|normalUmathlimitbelowvgap|normalUmathlimitbelowkern|normalUmathlimitbelowbgap|normalUmathlimitabovevgap|normalUmathlimitabovekern|normalUmathlimitabovebgap|normalUmathinnerrelspacing|normalUmathinnerpunctspacing|normalUmathinnerordspacing|normalUmathinneropspacing|normalUmathinneropenspacing|normalUmathinnerinnerspacing|normalUmathinnerclosespacing|normalUmathinnerbinspacing|normalUmathfractionrule|normalUmathfractionnumvgap|normalUmathfractionnumup|normalUmathfractiondenomvgap|normalUmathfractiondenomdown|normalUmathfractiondelsize|normalUmathconnectoroverlapmin|normalUmathcodenum|normalUmathcode|normalUmathcloserelspacing|normalUmathclosepunctspacing|normalUmathcloseordspacing|normalUmathcloseopspacing|normalUmathcloseopenspacing|normalUmathcloseinnerspacing|normalUmathcloseclosespacing|normalUmathclosebinspacing|normalUmathcharslot|normalUmathcharnumdef|normalUmathcharnum|normalUmathcharfam|normalUmathchardef|normalUmathcharclass|normalUmathchar|normalUmathbinrelspacing|normalUmathbinpunctspacing|normalUmathbinordspacing|normalUmathbinopspacing|normalUmathbinopenspacing|normalUmathbininnerspacing|normalUmathbinclosespacing|normalUmathbinbinspacing|normalUmathaxis|normalUmathaccent|normalUleft|normalUhextensible|normalUdelimiterunder|normalUdelimiterover|normalUdelimiter|normalUdelcodenum|normalUdelcode|normalUchar|normalOmegaversion|normalOmegarevision|normalOmegaminorversion|normalAlephversion|normalAlephrevision|normalAlephminorversion|normal |nonstopmode|nonscript|nolimits|noligs|nokerns|noindent|nohrule|noexpand|noboundary|noalign|newlinechar|mutoglue|muskipdef|muskip|multiply|muexpr|mskip|moveright|moveleft|month|mkern|middle|message|medmuskip|meaning|maxdepth|maxdeadcycles|mathsurroundskip|mathsurroundmode|mathsurround|mathstyle|mathscriptsmode|mathscriptcharmode|mathscriptboxmode|mathrulethicknessmode|mathrulesmode|mathrulesfam|mathrel|mathpunct|mathpenaltiesmode|mathord|mathopen|mathop|matholdmode|mathnolimitsmode|mathlimitsmode|mathitalicsmode|mathinner|mathflattenmode|matheqnogapstep|mathdisplayskipmode|mathdirection|mathdelimitersmode|mathcode|mathclose|mathchoice|mathchardef|mathchar|mathbin|mathaccent|marks|mark|mag|luatexversion|luatexrevision|luatexbanner|luafunctioncall|luafunction|luaescapestring|luadef|luacopyinputnodes|luabytecodecall|luabytecode|lpcode|lowercase|lower|looseness|long|localrightbox|localleftbox|localinterlinepenalty|localbrokenpenalty|lineskiplimit|lineskip|linepenalty|linedirection|limits|letcharcode|let|leqno|leftskip|leftmarginkern|lefthyphenmin|leftghost|left|leaders|lccode|lastskip|lastpenalty|lastnodetype|lastnodesubtype|lastnamedcs|lastlinefit|lastkern|lastbox|language|kern|jobname|internalcodesmode|interlinepenalty|interlinepenalties|interactionmode|insertpenalties|insertht|insert|inputlineno|input|initcatcodetable|indent|immediateassignment|immediateassigned|ignorespaces|ifx|ifvoid|ifvmode|ifvbox|ifusercmd|iftrue|iftok|ifprotected|ifpdfprimitive|ifpdfabsnum|ifpdfabsdim|ifodd|ifnumval|ifnum|ifmmode|ifinner|ifincsname|ifhmode|ifhbox|iffrozen|iffontchar|iffalse|ifeof|ifdimval|ifdim|ifdefined|ifcstok|ifcsname|ifcondition|ifcmpnum|ifcmpdim|ifchknum|ifchkdim|ifcat|ifcase|ifabsnum|ifabsdim|if|hyphenpenaltymode|hyphenpenalty|hyphenchar|hyphenationmin|hyphenationbounds|hyphenation|ht|hss|hskip|hsize|hrule|hpack|holdinginserts|hoffset|hjcode|hfuzz|hfilneg|hfill|hfil|hbox|hbadness|hangindent|hangafter|halign|gtokspre|gtoksapp|glyphdatafield|gluetomu|gluestretchorder|gluestretch|glueshrinkorder|glueshrink|glueexpr|globaldefs|global|gleaders|gdef|futurelet|futureexpandisap|futureexpandis|futureexpand|frozen|formatname|fontname|fontid|fontdimen|fontcharwd|fontcharic|fontcharht|fontchardp|font|floatingpenalty|fixupboxesmode|firstvalidlanguage|firstmarks|firstmark|finalhyphendemerits|fi|fam|explicithyphenpenalty|explicitdiscretionary|expandafter|exhyphenpenalty|exhyphenchar|exceptionpenalty|everyvbox|everypar|everymath|everyjob|everyhbox|everyeof|everydisplay|everycr|etokspre|etoksapp|escapechar|errorstopmode|errorcontextlines|errmessage|errhelp|eqno|endlocalcontrol|endlinechar|endinput|endgroup|endcsname|end|emergencystretch|else|efcode|edef|eTeXversion|eTeXrevision|eTeXminorversion|eTeXVersion|dump|dp|doublehyphendemerits|divide|displaywidth|displaywidowpenalty|displaywidowpenalties|displaystyle|displaylimits|displayindent|discretionary|directlua|dimexpr|dimendef|dimen|detokenize|delimitershortfall|delimiterfactor|delimiter|delcode|defaultskewchar|defaulthyphenchar|def|deadcycles|day|currentiftype|currentiflevel|currentifbranch|currentgrouptype|currentgrouplevel|csstring|csname|crcr|crampedtextstyle|crampedscriptstyle|crampedscriptscriptstyle|crampeddisplaystyle|cr|countdef|count|copy|compoundhyphenmode|clubpenalty|clubpenalties|closein|clearmarks|cleaders|chardef|char|catcodetable|catcode|brokenpenalty|breakafterdirmode|boxyoffset|boxymove|boxxoffset|boxxmove|boxtotal|boxorientation|boxmaxdepth|boxdirection|boxattr|box|boundary|botmarks|botmark|binoppenalty|belowdisplayskip|belowdisplayshortskip|beginlocalcontrol|begingroup|begincsname|batchmode|baselineskip|badness|automatichyphenpenalty|automatichyphenmode|automaticdiscretionary|attributedef|attribute|atopwithdelims|atop|aligntab|alignmark|aftergrouped|aftergroup|afterassignment|advance|adjustspacing|adjdemerits|accent|abovewithdelims|abovedisplayskip|abovedisplayshortskip|above|XeTeXversion|Uvextensible|Uunderdelimiter|Usuperscript|Usubscript|Ustopmath|Ustopdisplaymath|Ustartmath|Ustartdisplaymath|Ustack|Uskewedwithdelims|Uskewed|Uroot|Uright|Uradical|Uoverdelimiter|Unosuperscript|Unosubscript|Umiddle|Umathunderdelimitervgap|Umathunderdelimiterbgap|Umathunderbarvgap|Umathunderbarrule|Umathunderbarkern|Umathsupsubbottommax|Umathsupshiftup|Umathsupshiftdrop|Umathsupbottommin|Umathsubtopmax|Umathsubsupvgap|Umathsubsupshiftdown|Umathsubshiftdrop|Umathsubshiftdown|Umathstackvgap|Umathstacknumup|Umathstackdenomdown|Umathspaceafterscript|Umathskewedfractionvgap|Umathskewedfractionhgap|Umathrelrelspacing|Umathrelpunctspacing|Umathrelordspacing|Umathrelopspacing|Umathrelopenspacing|Umathrelinnerspacing|Umathrelclosespacing|Umathrelbinspacing|Umathradicalvgap|Umathradicalrule|Umathradicalkern|Umathradicaldegreeraise|Umathradicaldegreebefore|Umathradicaldegreeafter|Umathquad|Umathpunctrelspacing|Umathpunctpunctspacing|Umathpunctordspacing|Umathpunctopspacing|Umathpunctopenspacing|Umathpunctinnerspacing|Umathpunctclosespacing|Umathpunctbinspacing|Umathoverdelimitervgap|Umathoverdelimiterbgap|Umathoverbarvgap|Umathoverbarrule|Umathoverbarkern|Umathordrelspacing|Umathordpunctspacing|Umathordordspacing|Umathordopspacing|Umathordopenspacing|Umathordinnerspacing|Umathordclosespacing|Umathordbinspacing|Umathoprelspacing|Umathoppunctspacing|Umathopordspacing|Umathopopspacing|Umathopopenspacing|Umathopinnerspacing|Umathoperatorsize|Umathopenrelspacing|Umathopenpunctspacing|Umathopenordspacing|Umathopenopspacing|Umathopenopenspacing|Umathopeninnerspacing|Umathopenclosespacing|Umathopenbinspacing|Umathopclosespacing|Umathopbinspacing|Umathnolimitsupfactor|Umathnolimitsubfactor|Umathlimitbelowvgap|Umathlimitbelowkern|Umathlimitbelowbgap|Umathlimitabovevgap|Umathlimitabovekern|Umathlimitabovebgap|Umathinnerrelspacing|Umathinnerpunctspacing|Umathinnerordspacing|Umathinneropspacing|Umathinneropenspacing|Umathinnerinnerspacing|Umathinnerclosespacing|Umathinnerbinspacing|Umathfractionrule|Umathfractionnumvgap|Umathfractionnumup|Umathfractiondenomvgap|Umathfractiondenomdown|Umathfractiondelsize|Umathconnectoroverlapmin|Umathcodenum|Umathcode|Umathcloserelspacing|Umathclosepunctspacing|Umathcloseordspacing|Umathcloseopspacing|Umathcloseopenspacing|Umathcloseinnerspacing|Umathcloseclosespacing|Umathclosebinspacing|Umathcharslot|Umathcharnumdef|Umathcharnum|Umathcharfam|Umathchardef|Umathcharclass|Umathchar|Umathbinrelspacing|Umathbinpunctspacing|Umathbinordspacing|Umathbinopspacing|Umathbinopenspacing|Umathbininnerspacing|Umathbinclosespacing|Umathbinbinspacing|Umathaxis|Umathaccent|Uleft|Uhextensible|Udelimiterunder|Udelimiterover|Udelimiter|Udelcodenum|Udelcode|Uchar|Omegaversion|Omegarevision|Omegaminorversion|Alephversion|Alephrevision|Alephminorversion| )(?=[^a-zA-Z])",
"name" : "context.primitive.commands.primitive.tex"
},
"reserved" : {
diff --git a/doc/context/documents/general/manuals/svg-lmtx.pdf b/doc/context/documents/general/manuals/svg-lmtx.pdf
new file mode 100644
index 000000000..0f08cae51
--- /dev/null
+++ b/doc/context/documents/general/manuals/svg-lmtx.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index 9afba8474..caf2193a7 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index 81eb95dc7..2e0e1be0a 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index df76d474e..966b2ae73 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 47b5faa5d..74725cd28 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index 972f19247..b5bbee3e9 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 3f065838b..9ff2fbd6e 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index fbb1d15b8..8b4fb09bf 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index 4d978e994..277389453 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index a83319ca9..7b5884e6f 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index 13000e4c7..d28239ff7 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index 926f30eb7..6d4ecc600 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index 87921a227..b50d51950 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 6f8fe824e..7ad98be3e 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 1549cf712..a12c87f72 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-groups.tex b/doc/context/sources/general/manuals/luametafun/luametafun-groups.tex
new file mode 100644
index 000000000..b29ab3cbf
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-groups.tex
@@ -0,0 +1,52 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-groups
+
+\startchapter[title={Groups}]
+
+This is just a quick example of an experimental features.
+
+\startbuffer
+\startMPcode
+ fill fullcircle scaled 2cm shifted ( 5mm,2cm) withcolor "darkblue" ;
+ fill fullcircle scaled 2cm shifted (15mm,2cm) withcolor "darkblue" ;
+
+ fill fullcircle scaled 2cm shifted ( 5mm,-2cm) withcolor "darkgreen" ;
+ fill fullcircle scaled 2cm shifted (15mm,-2cm) withcolor "darkgreen" ;
+
+ draw image (
+ fill fullcircle scaled 4cm withcolor "darkred" ;
+ fill fullcircle scaled 4cm shifted (2cm,0) withcolor "darkred" ;
+
+ setgroup currentpicture to boundingbox currentpicture
+ withtransparency (1,.5) ;
+ ) ;
+
+ draw image (
+ fill fullcircle scaled 3cm withcolor "darkyellow"
+ withtransparency (1,.5) ;
+ fill fullcircle scaled 3cm shifted (2cm,0) withcolor "darkyellow"
+ withtransparency (1,.5) ;
+ ) ;
+
+ addbackground withcolor "darkgray" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+A group create an object that when transparency is applied is treated as
+a group.
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+(Groups might become more powerful in the future, like reusable components but
+then some more juggling is needed.)
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun.tex b/doc/context/sources/general/manuals/luametafun/luametafun.tex
index 52b7a6800..2dd917cdf 100644
--- a/doc/context/sources/general/manuals/luametafun/luametafun.tex
+++ b/doc/context/sources/general/manuals/luametafun/luametafun.tex
@@ -27,6 +27,7 @@
\component luametafun-chart
\component luametafun-svg
\component luametafun-fonts
+ \component luametafun-groups
\component luametafun-interface
\stopbodymatter
diff --git a/doc/context/sources/general/manuals/svg/mozilla-tiger.svg b/doc/context/sources/general/manuals/svg/mozilla-tiger.svg
new file mode 100644
index 000000000..f74af7dd1
--- /dev/null
+++ b/doc/context/sources/general/manuals/svg/mozilla-tiger.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"><path fill="#d87512" d="M17.786 44.63c-.606.115-1.23.173-1.854.173-2.444 0-4.644-.864-6.04-2.375-.855-.92-1.394-2.147-1.517-3.47-.126-1.243.067-2.638.58-4.163.325-1.016.83-2.01 1.365-3.064.216-.426.437-.858.65-1.302.702-1.454 1.504-3.164 2.11-5.05.715-2.188.943-4.287.682-6.23-.267-2.102-.994-3.972-1.74-5.685a2.992 2.992 0 0 0-4.15-1.446c-.71.375-1.23 1-1.467 1.77a2.983 2.983 0 0 0 .218 2.292c.632 1.19 1.314 2.596 1.592 3.977.238 1.137.18 2.41-.184 3.897-.37 1.538-.976 3.143-1.522 4.518-.16.406-.33.816-.507 1.234-.507 1.215-1.032 2.47-1.364 3.838-.55 2.14-.666 4.152-.348 5.97.36 2.163 1.41 4.14 2.955 5.567 2.027 1.88 4.808 2.914 7.826 2.914 1.14 0 2.274-.146 3.375-.437l-.66-2.923"/><g fill="#bc600d"><path d="M11.585 43.742s.387 1.248.104 3.05c0 0 2.045-.466 1.898-2.27 0 0-.815-.29-2-.78M9.19 41.484S8.98 42.94 7.93 44.43c0 0 2.103.42 2.774-1.265 0 0-.696-.66-1.515-1.68M8.398 37.21s-.926 1.432-3.23 2.322c0 0 1.514 2.303 3.53.904 0 0-.237-1.388-.3-3.226M12.964 15.833s-1.685.798-3.783 3.45c0 0 2.1 1.55 4.663 2.228 0 0 .285-3.093-.88-5.677M13.5 23.873s-2.988.544-5.57 2.794c0 0 1.615 1.708 3.583 2.62 0 0 1.678-3.39 1.987-5.414M10.32 31.73s-1.483 0-4.483.812c0 0-.01 2.873 2.94 2.823 0 0 .747-1.75 1.544-3.635"/></g><g fill="#d87512"><path d="M53.33 39.37c0-4.484-35.622-4.484-35.622 0 0 10.16.05 10.25 17.81 10.25 17.762 0 17.812-.09 17.812-10.25"/><path d="M42.645 56.04c1.688 2.02 9.275.043 10.504-2.28 5.01-9.482-.006-13.58-.006-13.58l-10.5 1.313s-2.154 11.977 0 14.547"/></g><g fill="#bc600d"><path d="M54.2 41.496s-.336 4.246-4.657 9.573c0 0 4.38-1.7 5.808-4.3 0 0 .448-3.02-1.15-5.274M55.08 48.69s-1.065 1.88-3.563 3.872c0 0 1.78-.03 2.576-.785 0 0 .77-1.41.987-3.086"/></g><path fill="#f29a2e" d="M35.484 60.38c1.87 2.23 8.547 2.09 10.574 0 2.904-2.995 2.78-16.656 2.904-23.314l-12.418-1.053s-3.444 21.52-1.06 24.367"/><g fill="#bc600d"><path d="M48.21 53.53s-3.578-3.443-8.738-.013c0 0 5.754 2.455 7.365 5.672 0 0 1.126-2.245 1.373-5.66M48.775 46.06s-3.852-3.09-7.938 1.43c0 0 4.452-.47 7.632 3.635 0 0 .493-3.05.305-5.065"/></g><g fill="#3e4347"><path d="M43.847 61.57l-.397-2.765 1.344 2.445zM40.41 61.996l.502-3.294.498 3.294zM36.713 61.3l1.317-2.26-.372 2.59z"/></g><path fill="#d87512" d="M28.388 56.04c-1.688 2.02-9.277.043-10.504-2.28-5.01-9.482.004-13.58.004-13.58l10.5 1.313s2.154 11.977 0 14.547"/><g fill="#bc600d"><path d="M16.833 41.496s.336 4.246 4.657 9.573c0 0-4.38-1.7-5.807-4.3 0 0-.448-3.02 1.15-5.274M15.957 48.69s1.066 1.88 3.563 3.872c0 0-1.782-.03-2.576-.785 0 0-.772-1.41-.987-3.086"/></g><path fill="#f29a2e" d="M35.548 60.38c-1.87 2.23-8.548 2.09-10.575 0-2.904-2.995-2.78-16.656-2.904-23.314l12.417-1.053s3.446 21.52 1.06 24.367"/><g fill="#bc600d"><path d="M22.822 53.53s3.58-3.443 8.74-.013c0 0-5.754 2.455-7.367 5.672 0 0-1.125-2.245-1.373-5.66M22.255 46.06s3.852-3.09 7.94 1.43c0 0-4.453-.47-7.633 3.635 0 0-.493-3.05-.307-5.065"/></g><g fill="#3e4347"><path d="M26.24 61.25l1.345-2.445-.395 2.765zM29.62 61.996l.5-3.294.5 3.294zM33.375 61.63L33 59.04l1.32 2.26zM35.516 60.46c-.395-2.48-.482-4.96-.5-7.438.015-2.48.104-4.96.5-7.44.396 2.48.485 4.96.5 7.44-.018 2.48-.106 4.96-.5 7.438"/></g><path fill="#f29a2e" d="M27.777 6.994c0 3.82-2.727 6.987-6.086 6.915C11.83 13.7 15.893 2 15.893 2c3.36 0 11.885 1.176 11.885 4.994"/><path fill="#af5a31" d="M24.05 7.752c0 2.037-1.454 3.727-3.248 3.688-5.26-.11-3.093-6.353-3.093-6.353 1.792 0 6.34.628 6.34 2.665"/><path fill="#f29a2e" d="M43.26 6.994c0 3.82 2.726 6.987 6.086 6.915 9.86-.21 5.8-11.91 5.8-11.91C51.782 2 43.26 3.176 43.26 6.994"/><path fill="#af5a31" d="M46.983 7.752c0 2.037 1.455 3.727 3.247 3.688 5.26-.11 3.094-6.353 3.094-6.353-1.794 0-6.34.628-6.34 2.665"/><path fill="#f29a2e" d="M55.806 33.378c0 7.155-9.517 8.13-20.288 8.13-10.776 0-20.29-.975-20.29-8.13 0-29.96 11.596-29.14 20.29-29.14 8.69 0 20.288-.82 20.288 29.14"/><g fill="#3e4347"><path d="M35.54 7.59c3.24 0 6.15 1.084 8.156 2.81-.77-2.945-4.135-5.16-8.173-5.16-4.06 0-7.442 2.238-8.186 5.204 2.01-1.753 4.938-2.855 8.204-2.855"/><path d="M35.535 11.193c2.217 0 4.21.744 5.584 1.925-.528-2.02-2.835-3.534-5.6-3.534-2.78 0-5.095 1.533-5.605 3.564 1.376-1.198 3.383-1.955 5.62-1.955"/></g><path fill="#ffe8bb" d="M29.553 43.727l-18.408-7.01 4.24-9.06s2.704 3.85 13.29 6.82l.878 9.243"/><path fill="#3e4347" d="M29.37 39.77c-7.462-1.27-16.325-6.673-16.48-6.75l.992-2.168c.184.092 8.806 5.342 15.853 6.544l-.366 2.374"/><path fill="#ffe8bb" d="M41.48 43.727l18.406-7.01-4.24-9.06s-2.704 3.85-13.29 6.82l-.876 9.243"/><path fill="#3e4347" d="M41.663 39.77c7.46-1.27 16.325-6.673 16.48-6.75l-.993-2.168c-.184.092-8.808 5.342-15.852 6.544l.365 2.374"/><g fill="#ffe8bb"><path d="M43.524 45.57C38.752 42.023 41.4 33.86 41.4 33.86c-5.657 5.906-12.662 8.74-12.662 8.74 1.608 5.446 5.77 6.412 5.77 6.412-.34-1.835.663-3.302.663-3.302 1.68 2.22 5.03 2.986 5.03 2.986-1.287-1.508-.948-3.835-.948-3.835 2.326.875 4.27.71 4.27.71"/><path d="M42.29 42.97c-2.634 2.247-10.917 2.247-13.553 0-2.856-2.435-2.495-7.144.1-9.884 2.397-2.527 10.958-2.527 13.355 0 2.595 2.74 2.956 7.45.098 9.883"/></g><g fill="#3e4347"><path d="M36.18 40.48a.69.69 0 0 1-.644-.477c-.227-.67-.77-3.293-.71-5.498.01-.398.325-.71.7-.698.38.01.674.343.663.74-.057 2.01.46 4.466.633 4.974.127.375-.06.786-.414.92a.607.607 0 0 1-.23.04"/><path d="M30.504 43.25c.21-.202.394-.408.582-.61.188-.204.378-.405.57-.604.385-.396.782-.78 1.2-1.145a14.125 14.125 0 0 1 2.745-1.9c.504-.263 1.032-.49 1.59-.654s1.153-.273 1.772-.253c.31.01.623.055.928.146.307.088.602.23.86.416.263.19.485.422.652.684.17.257.287.54.35.83a4.247 4.247 0 0 0-.677-.448 2.567 2.567 0 0 0-.68-.237c-.447-.088-.887-.04-1.33.06-.89.216-1.786.65-2.69 1.114-.905.466-1.818.983-2.776 1.466-.48.24-.97.473-1.48.682-.256.103-.517.202-.783.285-.27.078-.546.155-.833.167"/></g><path fill="#f15a61" d="M41.34 31.743c-1.17-.528-4.757-.57-5.83-.57-1.07 0-4.66.042-5.83.57-.832.376-.187 1.31 2.027 2.116 1.397.506 2.733.666 3.803.666 1.07 0 2.405-.16 3.805-.667 2.213-.808 2.856-1.74 2.025-2.117"/><g fill="#3e4347"><path d="M29.917 23.48l1.61 5.292L26.954 26z"/><path d="M22.645 31.828c-.522 0-.932-.056-1.17-.098-2.986-.52-4.632-1.996-6.09-4.067l.185-2.472c1.52 1.446 3.953 3.76 6.28 4.167 1.156.2 2.853-.016 4.15-1.234 1.537-1.44 2.263-4.05 2.1-7.547l1.635.132c.2 4.312-.116 7.244-2.212 9.212-1.692 1.59-3.613 1.908-4.878 1.908M41.12 23.48l-1.613 5.292L44.08 26z"/><path d="M48.39 31.828c.52 0 .93-.056 1.167-.098 2.99-.52 4.637-1.996 6.09-4.067l-.182-2.472c-1.52 1.446-3.955 3.76-6.28 4.167-1.156.2-2.855-.016-4.154-1.234-1.532-1.44-2.258-4.05-2.095-7.547l-1.636.132c-.202 4.312.114 7.244 2.213 9.212 1.69 1.59 3.61 1.908 4.877 1.908"/></g><path fill="#ffe8bb" d="M30.25 22.09c-.852 5.282-3.728 5.87-6.696 5.577-2.986-.294-5.396-2.667-5.396-6.743 0-4.28 0-4.28 6.647-5.752 6.728-1.49 6 3.437 5.445 6.918"/><path fill="#3e4347" d="M29.16 22.547c-.244 2.534-2.61 4.357-5.287 4.072-2.674-.286-4.645-2.57-4.402-5.102s.28-2.75 5.108-2.237c4.83.514 4.824.737 4.582 3.267"/><path fill="#fff" d="M27.59 21.884c-.16 1.688-1.74 2.903-3.522 2.714-1.785-.19-3.096-1.712-2.936-3.4.163-1.69.186-1.835 3.406-1.493 3.22.344 3.215.49 3.053 2.18"/><g fill="#3e4347"><ellipse cx="25.5" cy="21.08" rx="1.45" ry="1.647"/><path d="M31.27 17.896c.42 0 .807-.284.936-.728.16-.546-.133-1.122-.65-1.29l-5.98-1.924c-.516-.166-1.065.14-1.225.685-.155.543.136 1.12.652 1.287l5.98 1.924a.95.95 0 0 0 .288.046"/></g><path fill="#ffe8bb" d="M40.78 22.09c.855 5.282 3.73 5.87 6.7 5.577 2.984-.294 5.395-2.667 5.395-6.743 0-4.28-.002-4.28-6.646-5.752-6.73-1.49-6.01 3.437-5.45 6.918"/><path fill="#3e4347" d="M41.873 22.547c.243 2.534 2.61 4.357 5.287 4.072 2.674-.286 4.646-2.57 4.402-5.102-.242-2.533-.28-2.75-5.107-2.237-4.83.514-4.824.737-4.582 3.267"/><path fill="#fff" d="M43.44 21.884c.16 1.688 1.737 2.903 3.522 2.714 1.783-.19 3.098-1.712 2.936-3.4-.16-1.69-.188-1.835-3.404-1.493-3.22.344-3.217.49-3.054 2.18"/><g fill="#3e4347"><ellipse cx="47.722" cy="20.932" rx="1.45" ry="1.647"/><path d="M39.76 17.896a.982.982 0 0 1-.935-.728c-.16-.546.132-1.122.65-1.29l5.98-1.924c.517-.166 1.063.14 1.224.685.155.543-.136 1.12-.653 1.287l-5.98 1.924a.96.96 0 0 1-.287.046"/></g></svg>
diff --git a/doc/context/sources/general/manuals/svg/svg-lmtx-microsoft.lua b/doc/context/sources/general/manuals/svg/svg-lmtx-microsoft.lua
new file mode 100644
index 000000000..9b55e87ca
--- /dev/null
+++ b/doc/context/sources/general/manuals/svg/svg-lmtx-microsoft.lua
@@ -0,0 +1,113 @@
+return {
+ [[
+ <svg id="glyph7" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <rect x="100" y="-430" width="200" height="430" fill="darkred" />
+ <rect x="100" y="-635" width="200" height="135" fill="darkblue" />
+ </svg>
+ ]],
+ [[
+ <svg id="glyph7" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 1000 1000 1000">
+ <rect x="100" y="570" width="200" height="430" fill="darkgreen" />
+ <rect x="100" y="365" width="200" height="135" fill="darkblue" />
+ </svg>
+ ]],
+ [[
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <g id="i-base">
+ <rect x="100" y="570" width="200" height="430" fill="darkblue" />
+ </g>
+ </defs>
+ <g id="glyph2" transform="translate(0,-1000)">
+ <use xlink:href="#i-base" />
+ </g>
+ </svg>
+ ]],
+ [[
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <g id="i-base">
+ <rect x="100" y="570" width="200" height="430" fill="darkred" />
+ </g>
+ </defs>
+ <g id="glyph13" transform="translate(0,-1000)">
+ <use xlink:href="#i-base" />
+ <rect x="100" y="365" width="200" height="135" fill="darkblue" />
+ </g>
+ </svg>
+ ]],
+ [[
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <g id="i-base">
+ <rect x="100" y="570" width="200" height="430" fill="darkgreen" />
+ </g>
+ </defs>
+ <g id="glyph14" transform="translate(0,-1000)">
+ <use xlink:href="#i-base" />
+ <polygon fill="darkblue" points="120,500 280,500 435,342 208,342"/>
+ </g>
+ </svg>
+ ]],
+ [[
+ <svg id="glyph7" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 1000 1000 1000">
+ <defs>
+ <linearGradient id="grad" x1="0%" y1="0%" x2="0%" y2="100%">
+ <stop offset="0%" stop-color="darkblue" stop-opacity="1" />
+ <stop offset="100%" stop-color="#00aab3" stop-opacity="1" />
+ </linearGradient>
+ </defs>
+ <rect x="100" y="570" width="200" height="430" fill="blue" xfill="url(#grad)" />
+ <rect x="100" y="365" width="200" height="135" fill="green" xfill="currentColor" />
+ </svg>
+ ]],
+ [[
+ <svg id="glyph7" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 1000 1000 1000">
+ <defs>
+ <linearGradient id="grad" x1="0%" y1="0%" x2="0%" y2="100%">
+ <stop offset="0%" stop-color="var(--color0,darkblue)" stop-opacity="1" />
+ <stop offset="100%" stop-color="var(--color1,#00aab3)" stop-opacity="1" />
+ </linearGradient>
+ </defs>
+ <rect x="100" y="570" width="200" height="430" fill="blue" xfill="url(#grad)" />
+ <rect x="100" y="365" width="200" height="135" fill="darkblue" />
+ </svg>
+ ]],
+ [[
+ <svg id="glyph2" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 1000 1000 1000">
+ <image x="100" y="365" width="200" height="635"
+ xlink:href="data:image/png;base64,
+ iVBORw0KGgoAAAANSUhEUgAAAMgAAAJ7CAYAAACmmd5sAAAFZklEQVR42u3XsQ3D
+ MBAEQUpw9ypahrMPGGwiwcFMCQQW9zzWuu4FbJ2eAAQCAgGBgEBAICAQEAgIBAQC
+ CAQEAgIBgYBAQCAgEBAICAQEAggEBAICAYGAQEAgIBAQCAgEEAgIBAQCAgGBgEBA
+ ICAQEAgIBBAICAQEAgIBgYBAQCAgEBAIIBAQCAgEBAICAYGAQEAgIBAQCCAQEAgI
+ BAQCAgGBgEBAICAQQCAgEBAICAQEAgIBgYBAQCAgEEAgIBAQCAgEBAICAYGAQEAg
+ IBBPAAIBgYBAQCAgEBAICAQEAgIBBAICAYGAQEAgIBAQCAgEBAICAQQCAgGBgEBA
+ ICAQEAgIBAQCCAQEAgIBgYBAQCAgEBAICAQEAggEBAICAYGAQEAgIBAQCAgEAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAA4DHHWtftGWDv80sE2Ds9AQgEBAL+IPBuIAoBJxYIBAQCPukgEHBigUBAIOAP
+ AlgQiAtiQsCCgEDAJx0sCFgQsCAgEHBigQUB5oKYELAgIBDwSQcLAhYELAgIBJxY
+ YEEACwItEIWAEwucWGBBwIKABQGBgBMLLAhYEMCCQFwQEwJOLHBigQUBCwICAScW
+ WBCwIGBBAIFAPbHcWGBBwCcdLAgIBJxYYEHAgoAFAYEA88RyY4EFAZ90sCAgEBAI
+ +IOAQMCJBQIBBALxD+ITAj7p4MQCgYBAwB8EBAJOLBAICATwB4EYiELAiQUCAYGA
+ TzoIBJxYIBAQCPiDABYE4oKYELAgIBDwSQcLAhYELAgIBJxYYEGAuSAmBCwICAR8
+ 0sGCgAUBCwICAScWWBDAgkALRCHgxAInFlgQsCBgQUAg4MQCCwIWBLAgEBfEhIAT
+ C5xYYEHAgoBAwIkFFgQsCFgQQCBQTyw3FlgQ8EkHCwICAScWWBCwIGBBQCDAPLHc
+ WGBBwCcdLAgIBAQC/iAgEHBigUAAgUD8g/iEgE86OLFAICAQ8AcBgYATCwQCAgH8
+ QSAGohBwYoFAQCDgkw4CAScWCAQEAv4ggAWBuCAmBCwICAR80sGCgAUBCwICAScW
+ WBBgLogJAQsCAgGfdLAgYEHAgoBAwIkFFgSwINACUQg4scCJBRYELAhYEBAIOLHA
+ goAFASwIxAUxIeDEAicWWBCwICAQcGKBBQELAhYEEAjUE8uNBRYEfNLBgoBAwIkF
+ FgQsCFgQEAgwTyw3FlgQ8EkHCwICAYGAPwgIBJxYIBBAIBD/ID4h4JMOTiwQCAgE
+ /EFAIODEAoGAQAB/EIiBKAScWCAQEAj4pINAwIkFAgGBgD8IYEEgLogJAQsCAgGf
+ dLAgYEHAgoBAwIkFFgSYC2JCwIKAQMAnHSwIWBCwICAQcGKBBQEsCLRAFAJOLHBi
+ gQUBCwIWBAQCTiywIGBBAAsCcUFMCDixwIkFFgQsCAgEnFhgQcCCgAUBBAL1xHJj
+ gQUBn3SwICAQcGKBBQELAhYEBALME8uNBRYEfNLBgoBAQCDgDwICAScWCAQQCMQ/
+ iE8I+KSDEwsEAgIBfxAQCDixQCAgEMAfBGIgCgEnFggEBAI+6SAQcGKBQEAg4A8C
+ WBCIC2JCwIKAQMAnHSwIWBCwICAQcGKBBQHmgpgQsCAgEPBJBwsCFgQsCAgEnFhg
+ QQALAi0QhYATC5xYYEHAgoAFAYGAEwssCFgQwIJAXBATAk4scGKBBQELAgIBJxZY
+ ELAgYEEAgUA9sdxYYEHAJx0sCAgEnFhgQcCCgAUBgQDzxHJjgQUBn3SwICAQEAj4
+ g4BAwIkFAgEEAvEP4hMCPungxAKBgEDgH3wBrUwJtCBGuc0AAAAASUVORK5CYII=
+ "/>
+ </svg>
+ ]],
+}
diff --git a/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua b/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua
new file mode 100644
index 000000000..0797f6406
--- /dev/null
+++ b/doc/context/sources/general/manuals/svg/svg-lmtx-mozilla.lua
@@ -0,0 +1,354 @@
+return {
+ [[
+ <svg width="160" height="140" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <rect x="10" y="10" width="100" height="100" stroke="blue" fill="purple" fill-opacity="0.5" stroke-opacity="0.8"/>
+ </svg>
+ ]],
+ [[
+ <svg width="160" height="140" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <line x1="40" x2="120" y1="20" y2="20" stroke="black" stroke-width="20" stroke-linecap="butt"/>
+ <line x1="40" x2="120" y1="60" y2="60" stroke="black" stroke-width="20" stroke-linecap="square"/>
+ <line x1="40" x2="120" y1="100" y2="100" stroke="black" stroke-width="20" stroke-linecap="round"/>
+ </svg>
+ ]],
+ [[
+ <svg width="160" height="280" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <polyline points="40 60 80 20 120 60" stroke="black" stroke-width="20" stroke-linecap="butt" fill="none" stroke-linejoin="miter"/>
+ <polyline points="40 140 80 100 120 140" stroke="black" stroke-width="20" stroke-linecap="round" fill="none" stroke-linejoin="round"/>
+ <polyline points="40 220 80 180 120 220" stroke="black" stroke-width="20" stroke-linecap="square" fill="none" stroke-linejoin="bevel"/>
+ </svg>
+ ]],
+ [[
+ <svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <path d="M 10 75 Q 50 10 100 75 T 190 75" stroke="black" stroke-linecap="round" stroke-dasharray="5,10,5" fill="none"/>
+ <path d="M 10 75 L 190 75" stroke="red" stroke-linecap="round" stroke-width="1" stroke-dasharray="5,5" fill="none"/>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="5" cy="5" r="3" stroke="green" />
+ <circle cx="15" cy="5" r="3" stroke="green" stroke-width="3" />
+ <circle cx="25" cy="5" r="3" stroke="green" stroke-width="2%" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 38 30" xmlns="http://www.w3.org/2000/svg">
+ <path stroke="black" fill="none" stroke-linejoin="miter" id="p1"
+ d="M1,9 l7 ,-3 l7 ,3
+ m2,0 l3.5 ,-3 l3.5 ,3
+ m2,0 l2 ,-3 l2 ,3
+ m2,0 l0.75,-3 l0.75,3
+ m2,0 l0.5 ,-3 l0.5 ,3" />
+ <path stroke="black" fill="none" stroke-linejoin="miter" stroke-miterlimit="1" id="p2"
+ d="M1,19 l7 ,-3 l7 ,3
+ m2, 0 l3.5 ,-3 l3.5 ,3
+ m2, 0 l2 ,-3 l2 ,3
+ m2, 0 l0.75,-3 l0.75,3
+ m2, 0 l0.5 ,-3 l0.5 ,3" />
+ <path stroke="black" fill="none" stroke-linejoin="miter" stroke-miterlimit="8" id="p3"
+ d="M1,29 l7 ,-3 l7 ,3
+ m2, 0 l3.5 ,-3 l3.5 ,3
+ m2, 0 l2 ,-3 l2 ,3
+ m2, 0 l0.75,-3 l0.75,3
+ m2, 0 l0.5 ,-3 l0.5 ,3" />
+ <path stroke="pink" fill="none" stroke-width="0.05"
+ d="M1, 9 l7,-3 l7,3 m2,0 l3.5,-3 l3.5,3 m2,0 l2,-3 l2,3 m2,0 l0.75,-3 l0.75,3 m2,0 l0.5,-3 l0.5,3
+ M1,19 l7,-3 l7,3 m2,0 l3.5,-3 l3.5,3 m2,0 l2,-3 l2,3 m2,0 l0.75,-3 l0.75,3 m2,0 l0.5,-3 l0.5,3
+ M1,29 l7,-3 l7,3 m2,0 l3.5,-3 l3.5,3 m2,0 l2,-3 l2,3 m2,0 l0.75,-3 l0.75,3 m2,0 l0.5,-3 l0.5,3" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-3 0 33 10" xmlns="http://www.w3.org/2000/svg">
+ <line x1="0" y1="1" x2="30" y2="1" stroke="black" />
+ <line x1="0" y1="3" x2="30" y2="3" stroke="black" stroke-dasharray="3 1" />
+ <line x1="0" y1="5" x2="30" y2="5" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="3" />
+ <line x1="0" y1="7" x2="30" y2="7" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="-3" />
+ <line x1="0" y1="9" x2="30" y2="9" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="1" />
+ <path d="M0,5 h-3 M0,7 h3 M0,9 h-1" stroke="rgba(255,0,0,.5)" />
+ </svg>
+ ]],
+ [[
+ <svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <path d="M 10 75 Q 50 10 100 75 T 190 75" stroke="black" stroke-linecap="round" stroke-dasharray="5,10,5" fill="none"/>
+ <path d="M 10 75 L 190 75" stroke="red" stroke-linecap="round" stroke-dasharray="5,5" fill="none" stroke-width="1"/>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <path fill="none" stroke="red"
+ d="M 10,10 h 10
+ m 0,10 h 10
+ m 0,10 h 10
+ M 40,20 h 10
+ m 0,10 h 10
+ m 0,10 h 10
+ m 0,10 h 10
+ M 50,50 h 10
+ m-20,10 h 10
+ m-20,10 h 10
+ m-20,10 h 10" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
+ <path fill="none" stroke="red" d="M 10,10 L 90,90 V 10 H 50" />
+ <path fill="none" stroke="red" d="M 110,10 l 80,80 v -80 h -40" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <path fill="none" stroke="red" d="M 10,90 C 30,90 25,10 50,10 S 70,90 90,90" />
+ <path fill="none" stroke="red" d="M 110,90 c 20,0 15,-80 40,-80 s 20,80 40,80" />
+ <g id="ControlPoints">
+ <line x1="10" y1="90" x2="30" y2="90" stroke="lightgrey" />
+ <circle cx="30" cy="90" r="1.5"/>
+ <line x1="50" y1="10" x2="25" y2="10" stroke="lightgrey" />
+ <circle cx="25" cy="10" r="1.5"/>
+ <line x1="50" y1="10" x2="75" y2="10" stroke="lightgrey" stroke-dasharray="2" />
+ <circle cx="75" cy="10" r="1.5" fill="lightgrey"/>
+ <line x1="90" y1="90" x2="70" y2="90" stroke="lightgrey" />
+ <circle cx="70" cy="90" r="1.5"/>
+ <circle cx="10" cy="90" r="1.5"/>
+ <circle cx="50" cy="10" r="1.5"/>
+ <circle cx="90" cy="90" r="1.5"/>
+ </g>
+ <use xlink:href="#ControlPoints" x="100" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <path fill="none" stroke="red" d="M 10,50 Q 25,25 40,50 t 30,0 30,0 30,0 30,0 30,0" />
+ <g>
+ <polyline points="10,50 25,25 40,50" stroke="rgba(0,0,0,.2)" fill="none" />
+ <circle cx="25" cy="25" r="1.5" />
+ <circle cx="10" cy="50" r="1.5"/>
+ <circle cx="40" cy="50" r="1.5"/>
+ <g id="SmoothQuadraticDown">
+ <polyline points="40,50 55,75 70,50" stroke="rgba(0,0,0,.2)" stroke-dasharray="2" fill="none" />
+ <circle cx="55" cy="75" r="1.5" fill="lightgrey" />
+ <circle cx="70" cy="50" r="1.5" />
+ </g>
+ <g id="SmoothQuadraticUp">
+ <polyline points="70,50 85,25 100,50" stroke="rgba(0,0,0,.2)" stroke-dasharray="2" fill="none" />
+ <circle cx="85" cy="25" r="1.5" fill="lightgrey" />
+ <circle cx="100" cy="50" r="1.5" />
+ </g>
+ <use xlink:href="#SmoothQuadraticDown" x="60" />
+ <use xlink:href="#SmoothQuadraticUp" x="60" />
+ <use xlink:href="#SmoothQuadraticDown" x="120" />
+ </g>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
+ <path fill="none" stroke="red" d="M 6,10 A 6 4 10 1 0 14,10" />
+ <path fill="none" stroke="lime" d="M 6,10 A 6 4 10 1 1 14,10" />
+ <path fill="none" stroke="purple" d="M 6,10 A 6 4 10 0 1 14,10" />
+ <path fill="none" stroke="pink" d="M 6,10 A 6 4 10 0 0 14,10" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 -1 30 11" xmlns="http://www.w3.org/2000/svg">
+ <path stroke="red" d="M 5,1 l -4,8 8,0" />
+ <path stroke="red" d="M 15,1 l -4,8 8,0 -4,-8" />
+ <path stroke="red" d="M 25,1 l -4,8 8,0 z" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
+ <ellipse cx="100" cy="50" rx="100" ry="50" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <line x1="0" y1="80" x2="100" y2="20" stroke="black" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
+ <polygon points="0,100 50,25 50,75 100,0" />
+ <polygon points="100,100 150,25 150,75 200,0" fill="none" stroke="black" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
+ <polyline points="0,100 50,25 50,75 100,0" />
+ <polyline points="100,100 150,25 150,75 200,0" fill="none" stroke="black" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
+ <rect width="100" height="100" />
+ <rect x="120" width="100" height="100" rx="15" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <path fill="none" stroke="red"
+ d="M 10,30
+ A 20,20 0,0,1 50,30
+ A 20,20 0,0,1 90,30
+ Q 90,60 50,90
+ Q 10,60 10,30 z" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-10 -10 220 120" xmlns="http://www.w3.org/2000/svg">
+ <polygon fill-rule="nonzero" stroke="red" points="50,0 21,90 98,35 2,35 79,90"/>
+ <polygon fill-rule="evenodd" stroke="red" points="150,0 121,90 198,35 102,35 179,90"/>
+ </svg>
+ ]],
+ [[
+ <svg x="0" width="10" height="10" clip="auto">
+ <circle cx="5" cy="5" r="4" stroke="green" />
+ </svg>
+ ]],
+ [[
+ <svg x="10" width="10" height="10" clip="rect(1, 9, 8, 2)">
+ <circle cx="5" cy="5" r="4" stroke="green" />
+ </svg>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <rect x="0" y="0" width="100%" height="100%" fill="red"/>
+ <circle cx="50%" cy="50%" r="4" fill="yellow"/>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
+ <rect x="0" y="0" width="100%" height="100%" fill="green"/>
+ <circle cx="50%" cy="50%" r="4" fill="yellow"/>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg">
+ <rect x="0" y="0" width="100%" height="100%" fill="blue"/>
+ <circle cx="50%" cy="50%" r="4" fill="yellow"/>
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
+ <rect x="10" y="10" width="30" height="20" fill="green" />
+ <rect x="10" y="10" width="30" height="20" fill="red" transform="matrix(3 1 -1 3 30 40)" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <rect x="5" y="5" width="40" height="40" fill="green" />
+ <rect x="5" y="5" width="40" height="40" fill="blue" transform="translate(50)" />
+ <rect x="5" y="5" width="40" height="40" fill="red" transform="translate(0 50)" />
+ <rect x="5" y="5" width="40" height="40" fill="yellow" transform="translate(50,50)" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-50 -50 100 100" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="0" cy="0" r="10" fill="red" transform="scale(4)" />
+ <circle cx="0" cy="0" r="10" fill="yellow" transform="scale(1,4)" />
+ <circle cx="0" cy="0" r="10" fill="pink" transform="scale(4,1)" />
+ <circle cx="0" cy="0" r="10" fill="black" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-12 -2 34 14" xmlns="http://www.w3.org/2000/svg">
+ <rect x="0" y="0" width="10" height="10" />
+ <rect x="0" y="0" width="10" height="10" fill="red" transform="rotate(100)" />
+ <rect x="0" y="0" width="10" height="10" fill="green" transform="rotate(100,10,10)" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg">
+ <rect x="-3" y="-3" width="6" height="6" />
+ <rect x="-3" y="-3" width="6" height="6" fill="red" transform="skewX(30)" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg">
+ <rect x="-3" y="-3" width="6" height="6" />
+ <rect x="-3" y="-3" width="6" height="6" fill="red" transform="skewY(30)" />
+ </svg>
+ ]],
+ [[
+ <svg width="100" viewBox="0 0 100 90" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <defs>
+ <path d="M50,0 21,90 98,35 2,35 79,90z" id="star" />
+ </defs>
+ <clipPath id="emptyStar">
+ <use xlink:href="#star" clip-rule="evenodd" />
+ </clipPath>
+ <rect clip-path="url(#emptyStar)" width="50" height="90" fill="blue" />
+ <clipPath id="filledStar">
+ <use xlink:href="#star" clip-rule="nonzero" />
+ </clipPath>
+ <rect clip-path="url(#filledStar)" width="50" height="90" x="50" fill="red" />
+ </svg>
+ ]],
+-- [[
+-- <svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
+-- <style>
+-- .small { font: italic 13px sans-serif; }
+-- .heavy { font: bold 30px sans-serif; }
+-- .Rrrrr { font: italic 40px serif; fill: red; }
+-- </style>
+-- <text x="20" y="35" class="small">My</text>
+-- <text x="40" y="35" class="heavy">cat</text>
+-- <text x="55" y="55" class="small">is</text>
+-- <text x="65" y="55" class="Rrrrr">Grumpy!</text>
+-- </svg>
+-- ]],
+ [[
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
+ <path d="M 0 0 L 10 5 L 0 10 z" />
+ </marker>
+ <marker id="dot" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="5" markerHeight="5">
+ <circle cx="5" cy="5" r="5" fill="red" />
+ </marker>
+ </defs>
+ <polyline points="10,10 10,90 90,90" fill="none" stroke="black" marker-start="url(#arrow)" marker-end="url(#arrow)" />
+ <polyline points="15,80 29,50 43,60 57,30 71,40 85,15" fill="none" stroke="grey" marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)" />
+ </svg>
+ ]],
+ -- from the attributes section
+ [[
+ <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <linearGradient id="gradient" x1="0%" y1="0%" x2="0" y2="100%">
+ <stop offset="0%" style="stop-color:skyblue;" />
+ <stop offset="100%" style="stop-color:seagreen;" />
+ </linearGradient>
+ </defs>
+ <rect x="0" y="0" width="100%" height="100%" fill="url(#gradient)" />
+ <circle cx="50" cy="50" r="40" fill="black" />
+ <circle cx="150" cy="50" r="40" fill="black" opacity="0.3" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 400 100" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="50" cy="50" r="40" />
+ <circle cx="150" cy="50" r="40" fill-opacity="0.7" />
+ <circle cx="250" cy="50" r="40" fill-opacity="50%" />
+ <circle cx="350" cy="50" r="40" style="fill-opacity: .25;" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
+ <line x1="0" y1="1" x2="30" y2="1" stroke="black" />
+ <line x1="0" y1="3" x2="30" y2="3" stroke="black" stroke-dasharray="4" />
+ <line x1="0" y1="5" x2="30" y2="5" stroke="black" stroke-dasharray="4 1" />
+ <line x1="0" y1="7" x2="30" y2="7" stroke="black" stroke-dasharray="4 1 2" />
+ <line x1="0" y1="9" x2="30" y2="9" stroke="black" stroke-dasharray="4 1 2 3" />
+ </svg>
+ ]],
+ [[
+ <svg viewBox="-3 0 33 10" xmlns="http://www.w3.org/2000/svg">
+ <line x1="0" y1="1" x2="30" y2="1" stroke="black" />
+ <line x1="0" y1="3" x2="30" y2="3" stroke="black" stroke-dasharray="3 1" />
+ <line x1="0" y1="5" x2="30" y2="5" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="3" />
+ <line x1="0" y1="7" x2="30" y2="7" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="-3" />
+ <line x1="0" y1="9" x2="30" y2="9" stroke="black" stroke-dasharray="3 1" stroke-dashoffset="1" />
+ <path d="M0,5 h-3 M0,7 h3 M0,9 h-1" stroke="rgba(255,0,0,.5)" />
+ </svg>
+ ]],
+}
diff --git a/doc/context/sources/general/manuals/svg/svg-lmtx.tex b/doc/context/sources/general/manuals/svg/svg-lmtx.tex
new file mode 100644
index 000000000..11cf33895
--- /dev/null
+++ b/doc/context/sources/general/manuals/svg/svg-lmtx.tex
@@ -0,0 +1,547 @@
+% language=us
+
+% \enabletrackers[metapost.svg.result]
+% \enabletrackers[metapost.svg.path]
+
+\enabledirectives[pdf.compact]
+
+% \nopdfcompression
+
+\def\showSVGcode#1#2%
+ {\ctxlua{metapost.showsvgpage{
+ filename = "#1",
+ index = tonumber(#2),
+ method = "code"
+ }}}
+
+\def\showSVGcodeG#1#2%
+ {\ctxlua{metapost.showsvgpage{
+ filename = "#1",
+ index = tonumber(#2),
+ method = "code",
+ x = 0,
+ y = 1000,
+ width = 1000,
+ height = 1000,
+ noclip = true
+ }}}
+
+\def\typeSVGcode#1#2%
+ {\ctxlua{metapost.typesvgpage{
+ filename = "#1",
+ index = tonumber(#2)
+ }}}
+
+\usemodule[abbreviations-logos]
+\usemodule[scite]
+
+\setuppapersize
+ [A4,landscape]
+
+\setuplayout
+ [backspace=1cm,
+ cutspace=2cm,
+ topspace=1cm,
+ width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt]
+
+\setupbodyfont
+ [dejavu,12pt]
+
+\setupwhitespace
+ [big]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ color=darkblue]
+
+\setuphead
+ [section]
+ [style=\bfb,
+ color=darkblue]
+
+\starttext
+
+\startMPpage
+ drawlineoptions (withpen pencircle scaled 0.4 withcolor darkgray) ;
+ drawpointoptions (withpen pencircle scaled 0.8 withcolor darkred) ;
+ drawcontroloptions(withpen pencircle scaled 0.6 withcolor darkgreen) ;
+ drawpathoptions (withpen pencircle scaled 1.0 withcolor darkblue) ;
+
+ drawoptionsfactor := .5 ;
+ detailpaths ;
+
+ StartPage ;
+
+ fill Page withcolor darkblue ;
+
+ draw lmt_svg [
+ filename = "svglogo.svg",
+ origin = true,
+ ]
+ ysized (PaperHeight -64mm)
+ shifted (12mm,52mm) ;
+
+ draw textext.llft ("\strut in context")
+ ysized 34mm
+ shifted lrcorner Page
+ shifted (-8mm,84mm)
+ withcolor white ;
+
+ draw textext.llft ("\strut and metafun xl")
+ ysized 34mm
+ shifted lrcorner Page
+ shifted (-8mm,44mm)
+ withcolor white ;
+
+
+ StopPage ;
+\stopMPpage
+
+\starttitle[title=Introduction]
+
+This document is about using \SVG, an \XML\ based format for describing graphics
+and colorful font shapes in \CONTEXT. It's one of the external figure formats.
+Where we can use \METAPOST\ for all kind of systematic graphics, bitmap images
+and artistic outlines come from outside. Inclusion of \SVG\ using the methods
+discussed here is quite efficient and will work for many graphics, but when it
+doesn't you can always fall back on a conversion by \INKSCAPE. It's work in
+progress anyway.
+
+The document is made for viewing on the screen and has a bunch of examples taken
+from websites. We might add more in due time. The cover page has the \SVG\ logo
+taken from \WIKIPEDIA\ but with some details added. It's not a nice cover image
+but it will do for our purpose. Feel free to suggest additional examples.
+
+\startlines
+Hans Hagen
+Hasselt NL
+October 2019\high{+}
+\stoplines
+
+\stoptitle
+
+\starttitle[title=The \SVG\ format]
+
+\startsection[title=What it is]
+
+The Scalable Vector Graphics format (\SVG) showed up around the turn of this
+century. I remember looking into it and wondering to what extent it was a fresh
+development and not some kind of application format turned \XML. Most elements
+are empty elements and data lives in attributes. What I found most puzzling is
+that a path definition was an attribute and not just content, especially because
+it can be a pretty large blob of numbers and commands. Anyway, at that time I
+played a bit with conversion but in the end decided to just consider it an
+external format for which conversion to (say) \PDF\ by an external program was a
+reasonable. At some point that external program became \INKSCAPE\ and \CONTEXT\
+uses that to convert \SVG\ images to \PDF\ runtime (with caching).
+
+In the meantime edition one turned edition two and the advance of \HTML\ and
+\CSS\ has crept features into the format, thereby not making it look better. But,
+because viewers support rendering \SVG, we now also see graphics showing up. The
+ones that I have to deal with are educational graphics, and when you look into
+the files, they can be curiously inconsistent in the way parts of graphics are
+made. For instance, the numbers along an axis of a mathematical graphic can be a
+mix of references to a font (\type {<text/>}), references to symbols \type
+{<symbol/>} that have paths (\type {<path/>}) or just paths \type {<path/>}.
+Using a tool that can spit out something structured doesn't mean that all its
+users will structure.
+
+The \SVG\ format provides lines, rectangles, circles, ellipses, polylines,
+polygons and paths. Paths are defines as a sequence of moves, lines, cubic and
+quadratic curves, arcs, collected in the \type {d} attribute (a funny short name
+compared to the length of its content and the verbosity of other attribute
+names). They can be open or closed, and use different winding rules. Positions
+are absolute or relative. This all leaves a lot of room for error and confusion.
+When a path looks bad, it can be produced bad, or the interpretation can be bad.
+Interpretation can even be such that errors are catched which makes it hard to
+figure out what is really wrong. And as usual, bugs (and supposed catches) can
+become features in the end. So it might take a while before this kind of support
+in \CONTEXT\ becomes stable but once it is, normally we're okay for a while. And,
+one nice side effect of \XML\ is that it can't really crash processing as it's
+just data.
+
+\stopsection
+
+\startsection[title=Color fonts]
+
+Then color fonts showed up in \OPENTYPE\ and \SVG\ is one of the used
+sub|-|formats in that. Again it was convenient enough to rely on \INKSCAPE\ to do
+the conversion to \PDF\ blobs, but after a while I decided that a more native
+(built|-|in) support start making sense. A lot had happened since 2000, most
+noticeably the arrival of \LUATEX\ and \CONTEXT\ \MKIV\ followed by \LUAMETATEX\
+and \CONTEXT\ \LMTX, so a more direct support because more feasible. A more
+direct support has the advantage that we don't need to call an external program
+and cache the results (think of Emoji fonts with thousands of glyphs in \SVG\
+format). Also, direct conversion makes it possible to tweak colors and such,
+simply because the data goes through the \CONTEXT\ internals as part of the
+typesetting process. So, as a prelude to the \CONTEXT\ 2019 meeting a preliminary
+converter was made, color font support was partially redone, and afterward the
+converter got completed to the level needed for embedding more fancy graphics,
+including relabeling.
+
+\stopsection
+
+\startsection[title=In practice]
+
+In the end all is about paths or glyphs, plus some optional clipping and
+transformations. The rendering is controlled by attributes: color, transparency,
+line thickness, the way lines join and end, etc. Now, in the original
+specification that was done only with attributes, which is a clean and robust way
+of doing it, but later styles and classes were introduced and we now have a whole
+chain to consider when resolving a to be used attribute.
+
+\startitemize[packed]
+ \startitem attributes explicitly set by keys to an element \stopitem
+ \startitem attributes set in the \type {style} attribute \stopitem
+ \startitem attributes set via one or more \type {class} assignments \stopitem
+ \startitem attributes set for the specific element \stopitem
+ \startitem attributes inherited from an ancestor (somewhat vague) \stopitem
+ \startitem redundant (nested) attributes (text styling) \stopitem
+\stopitemize
+
+Where examples are often hand codes and therefore look ok, graphics that get
+generated can look quite horrible: the same parameters being set with different
+methods, even inconsistently, to mention one. But also, graphics can be read in,
+tweaked and saved again which in itself generates artifacts, etc. One can of
+course argue that \XML\ is not for human consumption but personally I tend to
+conclude that when a source file looks bad, the likelyhood is great that what it
+encodes looks bad too. And for instance \INKSCAPE\ provides ways to inspect and
+tweak the \XML\ in the editor.
+
+\stopsection
+
+\startsection[title=The conversion]
+
+This brings us to the conversion. As we need \PDF\ operators one method is to
+directly go from \SVG\ to \PDF. There is the issue of fonts, but as we delegate
+that to \TEX\ anyway, because that is kind of an abstraction. Such a conversion
+is comparable with going from \METAPOST\ to \PDF. However, for practical reasons
+an intermediate step has been chosen: we go from \SVG\ to \METAPOST\ first. This
+has the benefit that we need little code for color and transparency because
+\METAPOST\ (read: \METAFUN) already deals with that. We also don't need that much
+for text, as we deal with that in \METAPOST\ too, and that way we can even
+overload and reposition for instance labels in graphics relatively easy.
+
+Another advantage of the intermediate step is that we can combine \SVG\ graphics
+with \METAPOST\ code. Of course we can already combine external graphics with
+\METAPOST, but there is a big advantage here: the output is quite efficient. When
+we transform paths and pens in \METAPOST, the end result is often just a path,
+but where we to do a direct conversion to \PDF, we would either have to do
+calculations on our own, or we would have to use lots of transformation
+directives. In the end, especially because \METAPOST\ is so fast, the indirect
+route pays of well (and I haven't even optimized it yet).
+
+\stopsection
+
+\startsection[title=Remark]
+
+In the perspective if using \TEX\ and \METAPOST\ it makes sense to keep an eye on
+consistency. You can make quite structured \SVG\ images if you want to. When you
+use a graphical editor you can even consider using a normal text editor to clean
+up the code occasionally. The cleaner the code, the more predictable the outcome
+will become. Looking at the code might also give an impression of what features
+not to use of use differently. Of course this makes most sense in situations
+where there are many graphics and long|-|term (re)use is needed.
+
+\stopsection
+
+\stoptitle
+
+\starttitle[title=Embedding graphics]
+
+\startsection[title=External figures]
+
+At least for now, the default \SVG\ inclusions is done via an external converter
+but you can use the internal one by specifying a conversion. The next example
+demonstrates that it works like any external figure:
+
+\startbuffer
+\startcombination[4*1]
+ {\externalfigure[mozilla-tiger.svg][conversion=mp]} {1}
+ {\externalfigure[mozilla-tiger.svg][conversion=mp,height=1cm]} {2}
+ {\externalfigure[mozilla-tiger.svg][conversion=mp,height=3cm,width=1cm]} {3}
+ {\externalfigure[mozilla-tiger.svg][conversion=mp,height=1cm,width=8cm]} {4}
+\stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get:
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Internal figures]
+
+You can put some \SVG\ code in a buffer:
+
+\startbuffer
+\startbuffer[svgtest]
+ <svg>
+ <rect
+ x="0" y="0" width="80" height="20"
+ fill="blue" stroke="red" stroke-width="3"
+ stroke-linejoin="miter"
+ transform="rotate(10)"
+ />
+ </svg>
+\stopbuffer
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+In the future more options might be added but for now there's only an offset
+possible:
+
+\startbuffer
+\startcombination[2*1]
+ {\framed[offset=overlay]{\includesvgbuffer[svgtest]}} {default}
+ {\framed[offset=overlay]{\includesvgbuffer[svgtest][offset=2bp]}} {some offset}
+\stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+There is a companion command \type {\includesvgfile} which accepts a filename
+and also supports offsets. Sometimes the offset is needed to prevent unwanted
+clipping.
+
+\stopsection
+
+\startsection[title=Mixing in \METAFUN]
+
+An \SVG\ image can be directly included in an \METAFUN\ image. This makes it
+possible to enhance (or manipulate) such an image, as in:
+
+\startbuffer
+\startMPcode
+ draw lmt_svg [
+ filename = "mozilla-tiger.svg",
+ origin = true,
+ ] rotated 45 slanted .75 ysized 2cm ;
+
+ setbounds currentpicture to
+ boundingbox currentpicture
+ enlarged 1mm ;
+
+ addbackground
+ withcolor "darkgray" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+An \SVG\ image included this way becomes a regular \METAPOST\ picture, so a
+collection of paths. Because \METAPOST\ on the average produces rather compact
+output the \SVG\ image normally also is efficiently embedded. You don't need to
+worry about loosing quality, because \METAPOST\ is quite accurate and we use so
+called \quote {double} number mode anyway.
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+Another trick is to inline the code:
+
+\startbuffer
+\startMPcode
+ draw svg "<svg>
+ <circle
+ cx='50' cy='50' r='40'
+ stroke='green' stroke-width='10' stroke-opacity='0.3'
+ fill='red' fill-opacity='0.3'
+ />
+ <circle
+ cx='150' cy='50' r='40'
+ stroke='green' stroke-width='10'
+ fill='red'
+ opacity='0.3'
+ />
+ </svg>" ;
+\stopMPcode
+\stopbuffer
+
+It doesn't really make sense as \METAPOST\ code is just as simple but
+it looks cool:
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+And actually it's less code (which internally of course expands to
+more):
+
+\startbuffer
+\startMPcode
+ pickup pencircle scaled 10;
+ path p ; p := fullcircle scaled 80 ;
+ fill p shifted (50,50) withcolor blue
+ withtransparency(1,0.3) ;
+ draw p shifted (50,50) withcolor yellow
+ withtransparency(1,0.3) ;
+ draw image (
+ fill p shifted (150,50) withcolor blue ;
+ draw p shifted (150,50) withcolor yellow ;
+ setgroup currentpicture to boundingbox currentpicture
+ withtransparency(1,0.3) ;
+ ) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+It's all a matter of taste. Watch the grouping trick!
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Fonts]
+
+{\em This is still experimental.}
+
+\stopsection
+
+\startsection[title=Labels]
+
+{\em This is still experimental.}
+
+\stopsection
+
+\startsection[title=Tracing]
+
+{\em This is still experimental.}
+
+\stopsection
+
+\stoptitle
+
+\starttitle[title=Mozilla test snippets]
+
+The Mozilla documentation pages for \SVG\ are pretty good and contain snippets
+that can be used for testing. More examples might be added in due time.
+
+\dorecurse{38}{
+ \page
+ \startsection[title=Snippet #1]
+ \framed
+ [offset=overlay]
+ {\scale[height=4cm]{\showSVGcode{svg-lmtx-mozilla.lua}{#1}}}
+ \blank
+ \start
+ \switchtobodyfont[10pt]
+ \setupalign[flushleft,verytolerant,broad]
+ \typeSVGcode{svg-lmtx-mozilla.lua}{#1}
+ \par
+ \stop
+ \stopsection
+ \page
+}
+
+\stoptitle
+
+\starttitle[title=Microsoft test snippets]
+
+These snippets come from the \MICROSOFT\ typography pages that discuss \OPENTYPE\
+and \SVG. Because these are actually examples of glyphs, we need to set some
+defaults:
+
+\starttabulate[|cT|rT|]
+\NC x \NC 0 \NC \NR
+\NC y \NC 1000 \NC \NR
+\NC width \NC 1000 \NC \NR
+\NC height \NC 1000 \NC \NR
+\stoptabulate
+
+in order to get the right placement. This has to do with the fact that the
+vertical \SVG\ coordinates go in the other direction compared to \METAPOST\ and
+\PDF.
+
+\dorecurse{8}{
+ \page
+ \startsection[title=Snippet #1]
+ \framed
+ [offset=overlay]
+ {\scale[height=4cm]{\showSVGcodeG{svg-lmtx-microsoft.lua}{#1}}}
+ \blank
+ \start
+ \switchtobodyfont[10pt]
+ \setupalign[flushleft,verytolerant,broad]
+ \typeSVGcode{svg-lmtx-microsoft.lua}{#1}
+ \par
+ \stop
+ \page
+ \stopsection
+ \page
+}
+
+\stoptitle
+
+\starttitle[title=Xah Lee test snippets]
+
+These snippets come from the \type {http://xahlee.info/js/svg_path_spec.html},
+which gives a nice overview of \SVG. Not all examples are here. There are some
+nice interactive examples there plus info about using fonts.
+
+\dorecurse{38}{
+ \page
+ \startsection[title=Snippet #1]
+ \framed
+ [offset=overlay]
+ {\scale[height=4cm]{\showSVGcodeG{svg-lmtx-xahlee.lua}{#1}}}
+ \blank
+ \start
+ \switchtobodyfont[10pt]
+ \setupalign[flushleft,verytolerant,broad]
+ \typeSVGcode{svg-lmtx-xahlee.lua}{#1}
+ \par
+ \stop
+ \page
+ \stopsection
+ \page
+}
+
+\stoptitle
+
+\starttitle[title=Our own snippets]
+
+These snippets were made as part if testing. I had some 1500 \SVG\ graphics that
+internally were quite messy (it's surprising what some applications export) so I
+sometimes had to extract bits and pieces and make my own tests to figure out how
+to deal with it.
+
+\dorecurse{2}{
+ \page
+ \startsection[title=Snippet #1]
+ \framed
+ [offset=overlay]
+ {\scale[height=4cm]{\showSVGcode{svg-lmtx-context.lua}{#1}}}
+ \blank
+ \start
+ \switchtobodyfont[10pt]
+ \setupalign[flushleft,verytolerant,broad]
+ \typeSVGcode{svg-lmtx-context.lua}{#1}
+ \par
+ \stop
+ \page
+ \stopsection
+ \page
+}
+
+\stoptitle
+
+\stoptext
+
+% After some contemplating, while listening to Benmont Tench's solo album (2014),
+% after first listening to a nice long interview, which I hit after following some
+% Hammond links, I finally decided that it made sense to write this manual. Life is
+% too short for delays.
diff --git a/doc/context/sources/general/manuals/svg/svglogo.svg b/doc/context/sources/general/manuals/svg/svglogo.svg
new file mode 100644
index 000000000..c23d92b82
--- /dev/null
+++ b/doc/context/sources/general/manuals/svg/svglogo.svg
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 100 100">
+
+ <title>SVG Logo</title>
+
+ <a xlink:href="http://www.w3.org/Graphics/SVG/"
+ xlink:title="W3C SVG Working Group home page">
+
+ <rect
+ id="background"
+ fill="#FF9900"
+ width="100"
+ height="100"
+ rx="4"
+ ry="4"/>
+
+ <rect
+ id="top-left"
+ fill="#FFB13B"
+ width="50"
+ height="50"
+ rx="4"
+ ry="4"/>
+
+ <rect
+ id="bottom-right"
+ x="50"
+ y="50"
+ fill="#DE8500"
+ width="50"
+ height="50"
+ rx="4"
+ ry="4"/>
+
+ <g id="circles" fill="#FF9900">
+ <circle
+ id="n"
+ cx="50"
+ cy="18.4"
+ r="18.4"/>
+
+ <circle
+ id="ne"
+ cx="72.4"
+ cy="27.6"
+ r="18.4"/>
+
+ <circle
+ id="e"
+ cx="81.6"
+ cy="50"
+ r="18.4"/>
+
+ <circle
+ id="se"
+ cx="72.4"
+ cy="72.4"
+ r="18.4"/>
+
+ <circle
+ id="s"
+ cx="50"
+ cy="81.6"
+ r="18.4"/>
+
+ <circle
+ id="sw"
+ cx="27.6"
+ cy="72.4"
+ r="18.4"/>
+
+ <circle
+ id="w"
+ cx="18.4"
+ cy="50"
+ r="18.4"/>
+
+ <circle
+ id="nw"
+ cx="27.6"
+ cy="27.6"
+ r="18.4"/>
+ </g>
+
+ <g id="stars">
+ <path
+ id="black-star"
+ d="M 63.086, 18.385
+ c 0.000, -7.227 -5.859,-13.086 -13.100,-13.086
+ c -7.235, 0.000 -13.096, 5.859 -13.096, 13.086
+ c -5.100, -5.110 -13.395, -5.110 -18.497, 0.000
+ c -5.119, 5.120 -5.119, 13.408 0.000, 18.524
+ c -7.234, 0.000 -13.103, 5.859 -13.103, 13.085
+ c 0.000, 7.230 5.870, 13.098 13.103, 13.098
+ c -5.119, 5.110 -5.119, 13.395 0.000, 18.515
+ c 5.102, 5.104 13.397, 5.104 18.497, 0.000
+ c 0.000, 7.228 5.860, 13.083 13.096, 13.083
+ c 7.240, 0.000 13.100, -5.855 13.100,-13.083
+ c 5.118, 5.104 13.416, 5.104 18.513, 0.000
+ c 5.101, -5.120 5.101,-13.410 0.000,-18.515
+ c 7.216, 0.000 13.081, -5.869 13.081,-13.098
+ c 0.000, -7.227 -5.865,-13.085 -13.081,-13.085
+ c 5.101, -5.119 5.101,-13.406 0.000,-18.524
+ C 76.502, 13.275 68.206, 13.275 63.086, 18.385 z"/>
+
+ <path
+ id="white-star"
+ fill="#FFFFFF"
+ d="M 55.003, 23.405
+ v 14.488
+ L 65.260, 27.640
+ c 0.000, -1.812 0.691,-3.618 2.066, -5.005
+ c 2.780, -2.771 7.275,-2.771 10.024, 0.000
+ c 2.771, 2.766 2.771, 7.255 0.000, 10.027
+ c -1.377, 1.375 -3.195, 2.072 -5.015, 2.072
+ L 62.101, 44.982
+ H 76.590
+ c 1.290, -1.280 3.054,-2.076 5.011, -2.076
+ c 3.900, 0.000 7.078, 3.179 7.078, 7.087
+ c 0.000, 3.906 -3.178, 7.088 -7.078, 7.088
+ c -1.957, 0.000 -3.721,-0.798 -5.011, -2.072
+ H 62.100
+ l 10.229, 10.244
+ c 1.824, 0.000 3.642, 0.694 5.015, 2.086
+ c 2.774, 2.759 2.774, 7.250 0.000, 10.010
+ c -2.750, 2.774 -7.239, 2.774 -10.025, 0.000
+ c -1.372, -1.372 -2.064,-3.192 -2.064, -5.003
+ L 55.000, 62.094
+ v 14.499
+ c 1.271, 1.276 2.084, 3.054 2.084, 5.013
+ c 0.000, 3.906 -3.177, 7.077 -7.098, 7.077
+ c -3.919, 0.000 -7.094,-3.167 -7.094, -7.077
+ c 0.000, -1.959 0.811,-3.732 2.081, -5.013
+ V 62.094
+ L 34.738, 72.346
+ c 0.000, 1.812 -0.705, 3.627 -2.084, 5.003
+ c -2.769, 2.772 -7.251, 2.772 -10.024, 0.000
+ c -2.775, -2.764 -2.775,-7.253 0.000,-10.012
+ c 1.377, -1.390 3.214,-2.086 5.012, -2.086
+ l 10.257,-10.242
+ H 23.414
+ c -1.289, 1.276 -3.072, 2.072 -5.015, 2.072
+ c -3.917, 0.000 -7.096,-3.180 -7.096, -7.088
+ s 3.177, -7.087 7.096,-7.087
+ c 1.940, 0.000 3.725, 0.796 5.015, 2.076
+ h 14.488
+ L 27.646, 34.736
+ c -1.797, 0.000 -3.632,-0.697 -5.012, -2.071
+ c -2.775, -2.772 -2.775,-7.260 0.000,-10.027
+ c 2.773, -2.771 7.256,-2.771 10.027, 0.000
+ c 1.375, 1.386 2.083, 3.195 2.083, 5.005
+ l 10.235, 10.252
+ V 23.407
+ c -1.270, -1.287 -2.082,-3.053 -2.082, -5.023
+ c 0.000, -3.908 3.175,-7.079 7.096, -7.079
+ c 3.919, 0.000 7.097, 3.168 7.097, 7.079
+ C 57.088, 20.356 56.274,22.119 55.003, 23.405 z"/>
+ </g>
+
+ <g id="svg-textbox">
+ <path
+ id="text-backdrop"
+ fill="black"
+ d="M 5.30,50.00
+ H 94.68
+ V 90.00
+ Q 94.68,95.00 89.68,95.00
+ H 10.30
+ Q 5.30,95.00 5.30,90.00 Z"/>
+
+ <path
+ id="shine"
+ fill="#3F3F3F"
+ d="M 14.657,54.211
+ h 71.394
+ c 2.908, 0.000 5.312, 2.385 5.312, 5.315
+ v 17.910
+ c -27.584,-3.403 -54.926,-8.125 -82.011,-7.683
+ V 59.526
+ C 9.353,56.596 11.743,54.211 14.657,54.211
+ L 14.657,54.211 z"/>
+
+ <g id="svg-text">
+ <title>SVG</title>
+ <path
+ id="S"
+ fill="#FFFFFF"
+ stroke="#000000"
+ stroke-width="0.5035"
+ d="M 18.312,72.927
+ c -2.103,-2.107 -3.407, -5.028 -3.407, -8.253
+ c 0.000,-6.445 5.223,-11.672 11.666,-11.672
+ c 6.446, 0.000 11.667, 5.225 11.667, 11.672
+ h -6.832
+ c 0.000,-2.674 -2.168, -4.837 -4.835, -4.837
+ c -2.663, 0.000 -4.838, 2.163 -4.838, 4.837
+ c 0.000, 1.338 0.549, 2.536 1.415, 3.420
+ l 0.000, 0.000
+ c 0.883, 0.874 2.101, 1.405 3.423, 1.405
+ v 0.012
+ c 3.232, 0.000 6.145, 1.309 8.243, 3.416
+ l 0.000, 0.000
+ c 2.118, 2.111 3.424, 5.034 3.424, 8.248
+ c 0.000, 6.454 -5.221, 11.680 -11.667, 11.680
+ c -6.442, 0.000 -11.666, -5.222 -11.666,-11.680
+ h 6.828
+ c 0.000, 2.679 2.175, 4.835 4.838, 4.835
+ c 2.667, 0.000 4.835, -2.156 4.835, -4.835
+ c 0.000,-1.329 -0.545, -2.527 -1.429, -3.407
+ l 0.000, 0.000
+ c -0.864,-0.880 -2.082, -1.418 -3.406, -1.418
+ l 0.000, 0.000
+ C 23.341,76.350 20.429, 75.036 18.312, 72.927
+ L 18.312,72.927
+ L 18.312,72.927 z"/>
+ <polygon
+ id="V"
+ fill="#FFFFFF"
+ stroke="#000000"
+ stroke-width="0.5035"
+ points="61.588,53.005
+ 53.344,92.854
+ 46.494,92.854
+ 38.236,53.005
+ 45.082,53.005
+ 49.920,76.342
+ 54.755,53.005"/>
+
+ <path
+ id="G"
+ fill="#FFFFFF"
+ stroke="#000000"
+ stroke-width="0.5035"
+ d="M 73.255,69.513
+ h 11.683
+ v 11.664
+ l 0.000, 0.000
+ c 0.000, 6.452 -5.226,11.678 -11.669, 11.678
+ c -6.441, 0.000 -11.666,-5.226 -11.666,-11.678
+ l 0.000, 0.000
+ V 64.676
+ h -0.017
+ C 61.586,58.229 66.827,53.000 73.253, 53.000
+ c 6.459, 0.000 11.683, 5.225 11.683, 11.676
+ h -6.849
+ c 0.000,-2.674 -2.152,-4.837 -4.834, -4.837
+ c -2.647, 0.000 -4.820, 2.163 -4.820, 4.837
+ v 16.501
+ l 0.000, 0.000
+ c 0.000, 2.675 2.173, 4.837 4.820, 4.837
+ c 2.682, 0.000 4.834,-2.162 4.834, -4.827
+ v -0.012
+ v -4.827
+ h -4.834
+ L 73.255,69.513
+ L 73.255,69.513 z"/>
+ </g>
+ </g>
+ </a>
+</svg>
diff --git a/metapost/context/base/mpiv/mp-lmtx.mpxl b/metapost/context/base/mpiv/mp-lmtx.mpxl
index b618ea4b5..4a6fde70d 100644
--- a/metapost/context/base/mpiv/mp-lmtx.mpxl
+++ b/metapost/context/base/mpiv/mp-lmtx.mpxl
@@ -2020,24 +2020,37 @@ vardef svgcolor(expr r,g,b) =
fi
enddef ;
+vardef svggray(expr s) =
+ s
+enddef ;
+
presetparameters "svg" [
filename = "",
fontname = "",
% unicode = 0,
width = 0,
height = 0,
+ origin = false,
+ offset = 0,
] ;
def lmt_svg = applyparameters "svg" "lmt_do_svg" enddef ;
vardef lmt_do_svg =
- save w, h ;
+ save w, h, o;
image (
pushparameters "svg" ;
w := getparameter "width" ;
h := getparameter "height" ;
+ o := getparameter "offset" ;
lua.mp.lmt_svg_include() ;
+ if getparameter "origin" :
+ currentpicture := currentpicture shifted -llcorner currentpicture ;
+ fi ;
popparameters ;
+ if o <> 0 :
+ setbounds currentpicture to boundingbox currentpicture enlarged o ;
+ fi ;
)
if w > 0 :
if h > 0 : xysized(w,h) else : xsized(w) fi
@@ -2142,3 +2155,45 @@ def lmt_registerglyph = applyparameters "mpsglyph" "lmt_do_registerglyph" end
vardef lmt_do_registerglyphs = lua.mp.lmt_register_glyphs() ; enddef ;
vardef lmt_do_registerglyph = lua.mp.lmt_register_glyph () ; enddef ;
+
+% Again an experiment (todo: the faster method):
+
+def lmt_remaptext = runscript("mp.lmt_do_remaptext()") enddef ;
+
+triplet mfun_tt_s ;
+
+vardef rawmaptext(expr s) =
+ mfun_tt_n := mfun_tt_n + 1 ;
+ mfun_tt_c := nullpicture ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := lua.mp.mf_map_text(mfun_tt_n,s) ;
+ mfun_tt_s := lua.mp.mf_map_move(mfun_tt_n) ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled wdpart mfun_tt_r
+ yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+ shifted (0,-dppart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
+ mfun_tt_c
+enddef ;
+
+vardef svgtext(expr t) =
+ save p ; picture p ;
+ % mfun_tt_s := (0,0,0) ;
+ % mfun_tt_r := (0,0,0) ;
+ p := rawmaptext(t) ;
+ p
+ if (mfun_labtype.drt >= 10) : % drt etc
+ shifted (0,ypart center p)
+ fi
+ shifted (
+ - mfun_labshift.drt(p)
+ - (redpart mfun_tt_s,0)
+ + (greenpart mfun_tt_s,bluepart mfun_tt_s)
+ )
+enddef ;
+
+vardef svg expr c = lmt_svg [ code = c ] enddef ;
diff --git a/metapost/context/base/mpiv/mp-luas.mpxl b/metapost/context/base/mpiv/mp-luas.mpxl
index 1cd5efe7f..c622582b8 100644
--- a/metapost/context/base/mpiv/mp-luas.mpxl
+++ b/metapost/context/base/mpiv/mp-luas.mpxl
@@ -160,9 +160,9 @@ vardef positionregion(expr name) = lua.mp.positionregion(name) enddef ;
vardef positionbox (expr name) = lua.mp.positionbox (name) enddef ;
vardef positionanchor = lua.mp.positionanchor() enddef ;
-let wdpart = redpart ;
-let htpart = greenpart ;
-let dppart = bluepart ;
+let wdpart = redpart ;
+let htpart = greenpart ;
+let dppart = bluepart ;
vardef positioninregion =
currentpicture := currentpicture shifted - positionxy(positionanchor) ;
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index c617524f4..908d45686 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.109
+local otlversion = 3.110
local helpinfo = [[
<?xml version="1.0"?>
diff --git a/scripts/context/lua/mtx-install.lua b/scripts/context/lua/mtx-install.lua
index 5395ff6ee..095ded2d6 100644
--- a/scripts/context/lua/mtx-install.lua
+++ b/scripts/context/lua/mtx-install.lua
@@ -91,9 +91,9 @@ local platforms = {
--
["linux-armhf"] = "linux-armhf",
--
- ["openbsd"] = "openbsd6.5",
- ["openbsd-i386"] = "openbsd6.5",
- ["openbsd-amd64"] = "openbsd6.5-amd64",
+ ["openbsd"] = "openbsd6.6",
+ ["openbsd-i386"] = "openbsd6.6",
+ ["openbsd-amd64"] = "openbsd6.6-amd64",
--
["freebsd"] = "freebsd",
["freebsd-i386"] = "freebsd",
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 0fd5404d7..0d5c86713 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -5703,7 +5703,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 17171
+-- original size: 41281, stripped down to: 17261
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -6218,49 +6218,52 @@ end
function utf.utf32_to_utf8_t(t,endian)
return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
-local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+if bit32 then
+ local rshift=bit32.rshift
+ local function little(b)
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
-end
-local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ local function big(b)
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
-end
-local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
-local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
-local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
+ local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+ local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+ local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
-end
-local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
+ local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
-end
-utf.utf8_to_utf16_be=utf8_to_utf16_be
-utf.utf8_to_utf16_le=utf8_to_utf16_le
-function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
+ utf.utf8_to_utf16_be=utf8_to_utf16_be
+ utf.utf8_to_utf16_le=utf8_to_utf16_le
+ function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
end
local pattern=Cs (
@@ -25857,8 +25860,8 @@ 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
-- skipped libraries : -
--- original bytes : 1030717
--- stripped bytes : 407989
+-- original bytes : 1030951
+-- stripped bytes : 408133
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 0fd5404d7..0d5c86713 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -5703,7 +5703,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 17171
+-- original size: 41281, stripped down to: 17261
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -6218,49 +6218,52 @@ end
function utf.utf32_to_utf8_t(t,endian)
return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
-local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+if bit32 then
+ local rshift=bit32.rshift
+ local function little(b)
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
-end
-local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ local function big(b)
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
-end
-local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
-local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
-local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
+ local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+ local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+ local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
-end
-local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
+ local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
-end
-utf.utf8_to_utf16_be=utf8_to_utf16_be
-utf.utf8_to_utf16_le=utf8_to_utf16_le
-function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
+ utf.utf8_to_utf16_be=utf8_to_utf16_be
+ utf.utf8_to_utf16_le=utf8_to_utf16_le
+ function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
end
local pattern=Cs (
@@ -25857,8 +25860,8 @@ 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
-- skipped libraries : -
--- original bytes : 1030717
--- stripped bytes : 407989
+-- original bytes : 1030951
+-- stripped bytes : 408133
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 0fd5404d7..0d5c86713 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -5703,7 +5703,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 17171
+-- original size: 41281, stripped down to: 17261
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -6218,49 +6218,52 @@ end
function utf.utf32_to_utf8_t(t,endian)
return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
-local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+if bit32 then
+ local rshift=bit32.rshift
+ local function little(b)
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
-end
-local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ local function big(b)
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
-end
-local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
-local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
-local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
+ local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+ local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+ local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
-end
-local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
+ local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
-end
-utf.utf8_to_utf16_be=utf8_to_utf16_be
-utf.utf8_to_utf16_le=utf8_to_utf16_le
-function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
+ utf.utf8_to_utf16_be=utf8_to_utf16_be
+ utf.utf8_to_utf16_le=utf8_to_utf16_le
+ function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
end
local pattern=Cs (
@@ -25857,8 +25860,8 @@ 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
-- skipped libraries : -
--- original bytes : 1030717
--- stripped bytes : 407989
+-- original bytes : 1030951
+-- stripped bytes : 408133
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 0fd5404d7..0d5c86713 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -5703,7 +5703,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 17171
+-- original size: 41281, stripped down to: 17261
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -6218,49 +6218,52 @@ end
function utf.utf32_to_utf8_t(t,endian)
return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
-local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+if bit32 then
+ local rshift=bit32.rshift
+ local function little(b)
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
-end
-local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ local function big(b)
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
-end
-local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
-local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
-local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
+ local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+ local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+ local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
-end
-local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
+ local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
-end
-utf.utf8_to_utf16_be=utf8_to_utf16_be
-utf.utf8_to_utf16_le=utf8_to_utf16_le
-function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
+ utf.utf8_to_utf16_be=utf8_to_utf16_be
+ utf.utf8_to_utf16_le=utf8_to_utf16_le
+ function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
end
local pattern=Cs (
@@ -25857,8 +25860,8 @@ 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
-- skipped libraries : -
--- original bytes : 1030717
--- stripped bytes : 407989
+-- original bytes : 1030951
+-- stripped bytes : 408133
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index adfd46772..42dac33ab 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{2019.10.11 15:47}
+\newcontextversion{2019.10.28 18:12}
%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 71b70dd56..d3691a6e7 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{2019.10.11 15:47}
+\edef\contextversion{2019.10.28 18:12}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index ba830e3de..629e4f73f 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -69,7 +69,7 @@ local getwhd = nuts.getwhd
local hlist_code = nodes.nodecodes.hlist
local find_tail = nuts.tail
-local hpack = nuts.hpack
+----- hpack = nuts.hpack
local new_latelua = nuts.pool.latelua
diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua
index 5ea72c7e3..15590dccc 100644
--- a/tex/context/base/mkiv/attr-col.lua
+++ b/tex/context/base/mkiv/attr-col.lua
@@ -549,7 +549,7 @@ local function extender(transparencies,key)
end
local function reviver(data,n)
- if transparencies.supported then
+ if n and transparencies.supported then
local v = values[n]
local d
if not v then
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index 617bf7cc3..deb11b4d2 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -1992,6 +1992,10 @@ do
end
end
+ function structurestags.gettablecell(fulltag)
+ return tabledata[fulltag]
+ end
+
function extras.tablecell(di,element,n,fulltag)
local hash = tabledata[fulltag]
if hash then
@@ -2027,6 +2031,10 @@ do
end
end
+ function structurestags.gettabulatecell(fulltag)
+ return tabulatedata[fulltag]
+ end
+
function extras.tabulate(di,element,n,fulltag)
local data = di.data
for i=1,#data do
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 4b584e787..f06aeab01 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{2019.10.11 15:47}
+\newcontextversion{2019.10.28 18:12}
%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-lmtx-error.pdf b/tex/context/base/mkiv/context-lmtx-error.pdf
new file mode 100644
index 000000000..0455781a3
--- /dev/null
+++ b/tex/context/base/mkiv/context-lmtx-error.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/context-lmtx-error.tex b/tex/context/base/mkiv/context-lmtx-error.tex
new file mode 100644
index 000000000..25020cb59
--- /dev/null
+++ b/tex/context/base/mkiv/context-lmtx-error.tex
@@ -0,0 +1,8 @@
+\startTEXpage[offset=overlay,toffset=.5pt,boffset=.5pt,background=color,backgroundcolor=gray]
+ \definedfont[LMTypewriterVarWd-Regular]%
+ \darkred e%
+ \darkgreen r%
+ \darkblue r%
+ \darkyellow o%
+ \darkgray r%
+\stopTEXpage
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 58334d47a..b367c0c44 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{2019.10.11 15:47}
+\edef\contextversion{2019.10.28 18:12}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 1e235689a..77678596c 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{2019.10.11 15:47}
+\edef\contextversion{2019.10.28 18:12}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/data-vir.lua b/tex/context/base/mkiv/data-vir.lua
index 7e25c822d..c5e63039c 100644
--- a/tex/context/base/mkiv/data-vir.lua
+++ b/tex/context/base/mkiv/data-vir.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['data-vir'] = {
license = "see context related readme files"
}
+local type = type
local formatters, validstrings = string.formatters, string.valid
local trace_virtual = false
@@ -18,14 +19,18 @@ local resolvers = resolvers
local finders, openers, loaders, savers = resolvers.finders, resolvers.openers, resolvers.loaders, resolvers.savers
-local data = { }
-local n = 0 -- hm, number can be query
-local f_virtual = formatters["virtual://%s.%s"]
+local data = { }
+local n = 0 -- hm, number can be query
+local f_virtual_n = formatters["virtual://%s.%s"]
+local f_virtual_y = formatters["virtual://%s-%s.%s"]
-function savers.virtual(specification,content)
+function savers.virtual(specification,content,suffix)
n = n + 1 -- one number for all namespaces
- local path = specification.path
- local filename = f_virtual(path ~= "" and path or "virtualfile",n)
+ local path = type(specification) == "table" and specification.path or specification
+ if type(path) ~= "string" or path == "" then
+ path = "virtualfile"
+ end
+ local filename = suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,suffix)
if trace_virtual then
report_virtual("saver: file %a saved",filename)
end
diff --git a/tex/context/base/mkiv/font-age.lua b/tex/context/base/mkiv/font-age.lua
index b20a57538..1545c1c8d 100644
--- a/tex/context/base/mkiv/font-age.lua
+++ b/tex/context/base/mkiv/font-age.lua
@@ -12,6 +12,9 @@ if context then
os.exit()
end
+-- There is no need for a special script to generate this list as it's seldom
+-- changes: inspect(fonts.encodings.agl.unicodes) will do.
+
return {
["A"]=65,
["AE"]=198,
@@ -1603,6 +1606,7 @@ return {
["eightideographicparen"]=12839,
["eightinferior"]=8328,
["eightmonospace"]=65304,
+ ["eightoldstyle"]=56,
["eightparen"]=9339,
["eightperiod"]=9359,
["eightpersian"]=1784,
@@ -1760,6 +1764,7 @@ return {
["fiveideographicparen"]=12836,
["fiveinferior"]=8325,
["fivemonospace"]=65301,
+ ["fiveoldstyle"]=53,
["fiveparen"]=9336,
["fiveperiod"]=9356,
["fivepersian"]=1781,
@@ -1788,6 +1793,7 @@ return {
["fourinferior"]=8324,
["fourmonospace"]=65300,
["fournumeratorbengali"]=2551,
+ ["fouroldstyle"]=52,
["fourparen"]=9335,
["fourperiod"]=9355,
["fourpersian"]=1780,
@@ -2616,6 +2622,7 @@ return {
["nineideographicparen"]=12840,
["nineinferior"]=8329,
["ninemonospace"]=65305,
+ ["nineoldstyle"]=57,
["nineparen"]=9340,
["nineperiod"]=9360,
["ninepersian"]=1785,
@@ -2782,6 +2789,7 @@ return {
["oneinferior"]=8321,
["onemonospace"]=65297,
["onenumeratorbengali"]=2548,
+ ["oneoldstyle"]=49,
["oneparen"]=9332,
["oneperiod"]=9352,
["onepersian"]=1777,
@@ -3298,6 +3306,7 @@ return {
["sevenideographicparen"]=12838,
["seveninferior"]=8327,
["sevenmonospace"]=65303,
+ ["sevenoldstyle"]=55,
["sevenparen"]=9338,
["sevenperiod"]=9358,
["sevenpersian"]=1783,
@@ -3394,6 +3403,7 @@ return {
["sixideographicparen"]=12837,
["sixinferior"]=8326,
["sixmonospace"]=65302,
+ ["sixoldstyle"]=54,
["sixparen"]=9337,
["sixperiod"]=9357,
["sixpersian"]=1782,
@@ -3602,6 +3612,7 @@ return {
["threeinferior"]=8323,
["threemonospace"]=65299,
["threenumeratorbengali"]=2550,
+ ["threeoldstyle"]=51,
["threeparen"]=9334,
["threeperiod"]=9354,
["threepersian"]=1779,
@@ -3722,6 +3733,7 @@ return {
["twoinferior"]=8322,
["twomonospace"]=65298,
["twonumeratorbengali"]=2549,
+ ["twooldstyle"]=50,
["twoparen"]=9333,
["twoperiod"]=9353,
["twopersian"]=1778,
@@ -4088,6 +4100,7 @@ return {
["zerohackarabic"]=1632,
["zeroinferior"]=8320,
["zeromonospace"]=65296,
+ ["zerooldstyle"]=48,
["zeropersian"]=1776,
["zerosuperior"]=8304,
["zerothai"]=3664,
diff --git a/tex/context/base/mkiv/font-agl.lua b/tex/context/base/mkiv/font-agl.lua
index 49b85421f..19912b944 100644
--- a/tex/context/base/mkiv/font-agl.lua
+++ b/tex/context/base/mkiv/font-agl.lua
@@ -395,7 +395,7 @@ local synonyms = allocate {
zeroarabic = 0x0660,
}
-local extras = allocate { -- private extensions
+local extras = allocate { -- private extensions
Dcroat = 0x0110,
Delta = 0x2206,
Euro = 0x20AC,
@@ -635,6 +635,17 @@ local extras = allocate { -- private extensions
theta1 = 0x03D1,
twodotenleader = 0x2025,
+ zerooldstyle = 0x0030,
+ oneoldstyle = 0x0031,
+ twooldstyle = 0x0032,
+ threeoldstyle = 0x0033,
+ fouroldstyle = 0x0034,
+ fiveoldstyle = 0x0035,
+ sixoldstyle = 0x0036,
+ sevenoldstyle = 0x0037,
+ eightoldstyle = 0x0038,
+ nineoldstyle = 0x0039,
+
dotlessj = 0x0237,
}
@@ -653,7 +664,7 @@ if names then
mark(unicodes)
mark(ctxcodes)
-else
+elseif characters then
names = allocate { } -- filled from char-def.lua
unicodes = allocate { }
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index c3fb58580..da02ab608 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.109
+ otf.version = otf.version or 3.110
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-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 8bf44d79e..5d3bd4230 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.109 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.110 -- 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)
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 51b1c248f..0e7e25808 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -720,6 +720,10 @@ local function checklookups(fontdata,missing,nofmissing)
end
end
+local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst = 0xE000
+local pualast = 0xF8FF
+
local function unifymissing(fontdata)
if not fonts.mappings then
require("font-map")
@@ -730,20 +734,22 @@ local function unifymissing(fontdata)
resources.unicodes = unicodes
for unicode, d in next, fontdata.descriptions do
if unicode < privateoffset then
- local name = d.name
- if name then
- unicodes[name] = unicode
+ if unicode >= puafirst and unicode <= pualast then
+ -- report_unicodes("resolving private unicode %U",unicode)
+ else
+ local name = d.name
+ if name then
+ unicodes[name] = unicode
+ end
end
+ else
+ -- report_unicodes("resolving private unicode %U",unicode)
end
end
fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
resources.unicodes = nil
end
-local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
-local puafirst = 0xE000
-local pualast = 0xF8FF
-
local function unifyglyphs(fontdata,usenames)
local private = fontdata.private or privateoffset
local glyphs = fontdata.glyphs
diff --git a/tex/context/base/mkiv/grph-con.lua b/tex/context/base/mkiv/grph-con.lua
index ab6651f97..788136f6d 100644
--- a/tex/context/base/mkiv/grph-con.lua
+++ b/tex/context/base/mkiv/grph-con.lua
@@ -420,3 +420,25 @@ do -- png | jpg | profiles
end
end
+
+if CONTEXTLMTXMODE > 0 then
+
+ -- This might also work ok in mkiv but is yet untested. Anyway, it's experimental as we
+ -- go through TeX which is is inefficient. I'll improve the buffer trick.
+
+ local function remap(specification)
+ local fullname = specification.fullname
+ if fullname then
+ local only = file.nameonly(fullname)
+ local name = formatters["svg-%s-inclusion"](only)
+ local code = formatters["\\includesvgfile[%s]\\resetbuffer[%s]"](fullname,name)
+ buffers.assign(name,code)
+ specification.format = "buffer"
+ specification.fullname = name
+ end
+ return specification
+ end
+
+ figures.remappers.svg = { mp = remap }
+
+end
diff --git a/tex/context/base/mkiv/grph-img.lua b/tex/context/base/mkiv/grph-img.lua
index 795ea4827..4b4bee1fc 100644
--- a/tex/context/base/mkiv/grph-img.lua
+++ b/tex/context/base/mkiv/grph-img.lua
@@ -16,27 +16,9 @@ local round = math.round
local concat = table.concat
local suffixonly = file.suffix
-local files = utilities.files
-local getsize = files.getsize
-local readbyte = files.readbyte
-local readstring = files.readstring
-local readcardinal = files.readcardinal
-local readcardinal2 = files.readcardinal2
-local readcardinal4 = files.readcardinal4
-local readcardinal2le = files.readcardinal2le
-local readcardinal4le = files.readcardinal4le
-local skipbytes = files.skip
-local setposition = files.setposition
-local getposition = files.getposition
-
-local newreader = io.newreader
-
-local setmetatableindex = table.setmetatableindex
-local setmetatablecall = table.setmetatablecall
-
------ lpdf = lpdf or { }
------ pdfmajorversion = lpdf.majorversion
------ pdfminorversion = lpdf.minorversion
+local newreader = io.newreader
+local setmetatableindex = table.setmetatableindex
+local setmetatablecall = table.setmetatablecall
local graphics = graphics or { }
local identifiers = { }
@@ -119,22 +101,20 @@ do
-- good old tiff tags here.
local function read_APP1_Exif(f, xres, yres, orientation) -- untested
- local position = false
- local readcardinal2 = readcardinal2
- local readcardinal4 = readcardinal4
+ local position = false
+ local littleendian = false
-- endian II|MM
while true do
- position = getposition(f)
- local b = readbyte(f)
+ position = f:getposition()
+ local b = f:readbyte()
if b == 0 then
-- next one
- elseif b == 0x4D and readbyte(f) == 0x4D then -- M
+ elseif b == 0x4D and f:readbyte() == 0x4D then -- M
-- big endian
break
- elseif b == 0x49 and readbyte(f) == 0x49 then -- I
+ elseif b == 0x49 and f:readbyte() == 0x49 then -- I
-- little endian
- readcardinal2 = readcardinal2le
- readcardinal4 = readcardinal4le
+ littleendian = true
break
else
-- warning "bad exif data"
@@ -142,46 +122,46 @@ do
end
end
-- version
- local version = readcardinal2(f)
+ local version = littleendian and f:readcardinal2le() or f:readcardinal2()
if version ~= 42 then
return xres, yres, orientation
end
-- offset to records
- local offset = readcardinal4(f)
+ local offset = littleendian and f:readcardinal4le() or f:readcardinal4()
if not offset then
return xres, yres, orientation
end
- setposition(f,position + offset)
- local entries = readcardinal2(f)
+ f:setposition(position + offset)
+ local entries = littleendian and f:readcardinal2le() or f:readcardinal2()
if not entries or entries == 0 then
return xres, yres, orientation
end
local x_res, y_res, x_res_ms, y_res_ms, x_temp, y_temp
local res_unit, res_unit_ms
for i=1,entries do
- local tag = readcardinal2(f)
- local kind = readcardinal2(f)
- local size = readcardinal4(f)
+ local tag = littleendian and f:readcardinal2le() or f:readcardinal2()
+ local kind = littleendian and f:readcardinal2le() or f:readcardinal2()
+ local size = littleendian and f:readcardinal4le() or f:readcardinal4()
local value = 0
local num = 0
local den = 0
if kind == 1 or kind == 7 then -- byte | undefined
- value = readbyte(f)
- skipbytes(f,3)
+ value = f:readbyte()
+ f:skip(3)
elseif kind == 3 or kind == 8 then -- (un)signed short
- value = readcardinal2(f)
- skipbytes(f,2)
+ value = littleendian and f:readcardinal2le() or f:readcardinal2()
+ f:skip(2)
elseif kind == 4 or kind == 9 then -- (un)signed long
- value = readcardinal4(f)
+ value = littleendian and f:readcardinal4le() or f:readcardinal4()
elseif kind == 5 or kind == 10 then -- (s)rational
- local offset = readcardinal4(f)
- local saved = getposition(f)
- setposition(f,position+offset)
- num = readcardinal4(f)
- den = readcardinal4(f)
- setposition(f,saved)
+ local offset = littleendian and f:readcardinal4le() or f:readcardinal4()
+ local saved = f:getposition()
+ f:setposition(position+offset)
+ num = littleendian and f:readcardinal4le() or f:readcardinal4()
+ den = littleendian and f:readcardinal4le() or f:readcardinal4()
+ f:setposition(saved)
else -- 2 -- ascii
- skipbytes(f,4)
+ f:skip(4)
end
if tag == 274 then -- orientation
orientation = value
@@ -226,7 +206,7 @@ do
return round(xres), round(yres), orientation
end
- function identifiers.jpg(filename)
+ function identifiers.jpg(filename,method)
local specification = {
filename = filename,
filetype = "jpg",
@@ -235,7 +215,7 @@ do
specification.error = "invalid filename"
return specification -- error
end
- local f = io.open(filename,"rb")
+ local f = newreader(filename,method)
if not f then
specification.error = "unable to open file"
return specification -- error
@@ -246,7 +226,7 @@ do
specification.totalpages = 1
specification.pagenum = 1
specification.length = 0
- local banner = readcardinal2(f)
+ local banner = f:readcardinal2()
if banner ~= 0xFFD8 then
specification.error = "no jpeg file"
return specification -- error
@@ -255,11 +235,11 @@ do
local yres = 0
local orientation = 1
local okay = false
- local filesize = getsize(f) -- seek end
+ local filesize = f:getsize() -- seek end
-- local majorversion = pdfmajorversion and pdfmajorversion() or 1
-- local minorversion = pdfminorversion and pdfminorversion() or 7
- while getposition(f) < filesize do
- local b = readbyte(f)
+ while f:getposition() < filesize do
+ local b = f:readbyte()
if not b then
break
elseif b ~= 0xFF then
@@ -269,8 +249,8 @@ do
end
break
end
- local category = readbyte(f)
- local position = getposition(f)
+ local category = f:readbyte()
+ local position = f:getposition()
local length = 0
local tagdata = tags[category]
if not tagdata then
@@ -290,25 +270,25 @@ do
-- specification.error = "no progressive DCT in PDF <= 1.2"
-- break
-- end
- length = readcardinal2(f)
- specification.colordepth = readcardinal(f)
- specification.ysize = readcardinal2(f)
- specification.xsize = readcardinal2(f)
- specification.colorspace = colorspaces[readcardinal(f)]
+ length = f:readcardinal2()
+ specification.colordepth = f:readcardinal()
+ specification.ysize = f:readcardinal2()
+ specification.xsize = f:readcardinal2()
+ specification.colorspace = colorspaces[f:readcardinal()]
if not specification.colorspace then
specification.error = "unsupported color space"
break
end
okay = true
elseif name == "APP0" then
- length = readcardinal2(f)
+ length = f:readcardinal2()
if length > 6 then
- local format = readstring(f,5)
+ local format = f:readstring(5)
if format == "JFIF\000" then
- skipbytes(f,2)
- units = readcardinal(f)
- xres = readcardinal2(f)
- yres = readcardinal2(f)
+ f:skip(2)
+ units = f:readcardinal()
+ xres = f:readcardinal2()
+ yres = f:readcardinal2()
if units == 1 then
-- pixels per inch
if xres == 1 or yres == 1 then
@@ -325,18 +305,18 @@ do
end
end
elseif name == "APP1" then
- length = readcardinal2(f)
+ length = f:readcardinal2()
if length > 7 then
- local format = readstring(f,5)
+ local format = f:readstring(5)
if format == "Exif\000" then
xres, yres, orientation = read_APP1_Exif(f,xres,yres,orientation)
end
end
elseif not tagdata.zerolength then
- length = readcardinal2(f)
+ length = f:readcardinal2()
end
if length > 0 then
- setposition(f,position+length)
+ f:setposition(position+length)
end
end
f:close()
@@ -362,15 +342,15 @@ end
do
local function read_boxhdr(specification,f)
- local size = readcardinal4(f)
- local kind = readstring(f,4)
+ local size = f:readcardinal4()
+ local kind = f:readstring(4)
if kind then
kind = strip(lower(kind))
else
kind = ""
end
if size == 1 then
- size = readcardinal4(f) * 0xFFFF0000 + readcardinal4(f)
+ size = f:readcardinal4() * 0xFFFF0000 + f:readcardinal4()
end
if size == 0 and kind ~= "jp2c" then -- move this
specification.error = "invalid size"
@@ -379,40 +359,40 @@ do
end
local function scan_ihdr(specification,f)
- specification.ysize = readcardinal4(f)
- specification.xsize = readcardinal4(f)
- skipbytes(f,2) -- nc
- specification.colordepth = readcardinal(f) + 1
- skipbytes(f,3) -- c unkc ipr
+ specification.ysize = f:readcardinal4()
+ specification.xsize = f:readcardinal4()
+ f:skip(2) -- nc
+ specification.colordepth = f:readcardinal() + 1
+ f:skip(3) -- c unkc ipr
end
local function scan_resc_resd(specification,f)
- local vr_n = readcardinal2(f)
- local vr_d = readcardinal2(f)
- local hr_n = readcardinal2(f)
- local hr_d = readcardinal2(f)
- local vr_e = readcardinal(f)
- local hr_e = readcardinal(f)
+ local vr_n = f:readcardinal2()
+ local vr_d = f:readcardinal2()
+ local hr_n = f:readcardinal2()
+ local hr_d = f:readcardinal2()
+ local vr_e = f:readcardinal()
+ local hr_e = f:readcardinal()
specification.xres = math.round((hr_n / hr_d) * math.exp(hr_e * math.log(10.0)) * 0.0254)
specification.yres = math.round((vr_n / vr_d) * math.exp(vr_e * math.log(10.0)) * 0.0254)
end
local function scan_res(specification,f,last)
- local pos = getposition(f)
+ local pos = f:getposition()
while true do
local kind, size = read_boxhdr(specification,f)
pos = pos + size
if kind == "resc" then
if specification.xres == 0 and specification.yres == 0 then
scan_resc_resd(specification,f)
- if getposition(f) ~= pos then
+ if f:getposition() ~= pos then
specification.error = "invalid resc"
return
end
end
elseif tpos == "resd" then
scan_resc_resd(specification,f)
- if getposition(f) ~= pos then
+ if f:getposition() ~= pos then
specification.error = "invalid resd"
return
end
@@ -425,19 +405,19 @@ do
if specification.error then
break
end
- setposition(f,pos)
+ f:setposition(pos)
end
end
local function scan_jp2h(specification,f,last)
local okay = false
- local pos = getposition(f)
+ local pos = f:getposition()
while true do
local kind, size = read_boxhdr(specification,f)
pos = pos + size
if kind == "ihdr" then
scan_ihdr(specification,f)
- if getposition(f) ~= pos then
+ if f:getposition() ~= pos then
specification.error = "invalid ihdr"
return false
end
@@ -453,12 +433,12 @@ do
if specification.error then
break
end
- setposition(f,pos)
+ f:setposition(pos)
end
return okay
end
- function identifiers.jp2(filename)
+ function identifiers.jp2(filename,method)
local specification = {
filename = filename,
filetype = "jp2",
@@ -467,7 +447,7 @@ do
specification.error = "invalid filename"
return specification -- error
end
- local f = io.open(filename,"rb")
+ local f = newreader(filename,method)
if not f then
specification.error = "unable to open file"
return specification -- error
@@ -482,13 +462,13 @@ do
local yres = 0
local orientation = 1
local okay = false
- local filesize = getsize(f) -- seek end
+ local filesize = f:getsize() -- seek end
--
local pos = 0
-- signature
local kind, size = read_boxhdr(specification,f)
pos = pos + size
- setposition(f,pos)
+ f:setposition(pos)
-- filetype
local kind, size = read_boxhdr(specification,f)
if kind ~= "ftyp" then
@@ -496,7 +476,7 @@ do
return specification
end
pos = pos + size
- setposition(f,pos)
+ f:setposition(pos)
while not okay do
local kind, size = read_boxhdr(specification,f)
pos = pos + size
@@ -506,7 +486,7 @@ do
specification.error = "no ihdr box found"
return specification
end
- setposition(f,pos)
+ f:setposition(pos)
end
--
f:close()
@@ -538,7 +518,7 @@ do
-- 6 = rgb + alpha "image c"
-- for i=1,length/3 do
- -- palette[i] = readstring(f,3)
+ -- palette[i] = f:readstring3)
-- end
local function grab(t,f,once)
@@ -635,7 +615,6 @@ do
tables[kind] = t
end
t[#t+1] = {
--- offset = getposition(f),
offset = f:getposition(),
length = length,
}
diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua
index bfe67094e..1d59972ab 100644
--- a/tex/context/base/mkiv/grph-inc.lua
+++ b/tex/context/base/mkiv/grph-inc.lua
@@ -298,6 +298,7 @@ local figures_resources = allocate() figures.resources = figures_resources
local existers = allocate() figures.existers = existers
local checkers = allocate() figures.checkers = checkers
local includers = allocate() figures.includers = includers
+local remappers = allocate() figures.remappers = remappers
local converters = allocate() figures.converters = converters
local identifiers = allocate() figures.identifiers = identifiers
local programs = allocate() figures.programs = programs
@@ -324,7 +325,7 @@ local figures_order = allocate {
local figures_formats = allocate { -- magic and order will move here
["pdf"] = { list = { "pdf" } },
- ["mps"] = { patterns = { "mps", "%d+" } },
+ ["mps"] = { patterns = { "^mps$", "^%d+$" } }, -- we need to anchor
["jpg"] = { list = { "jpg", "jpeg" } },
["png"] = { list = { "png" } },
["jp2"] = { list = { "jp2" } },
@@ -779,24 +780,32 @@ local function register(askedname,specification)
arguments or ""
)
end
- -- quick hack
- local converter = (newformat ~= format or resolution or arguments) and converters[format]
+ -- begin of quick hack
+ local remapper = remappers[format]
+ if remapper then
+ remapper = remapper[conversion]
+ if remapper then
+ specification = remapper(specification) or specification
+ format = specification.format
+ newformat = format
+ conversion = nil
+ end
+ end
+ -- end of quick hack
+ local converter = (not remapper) and (newformat ~= format or resolution or arguments) and converters[format]
if converter then
- if converter[newformat] then
- converter = converter[newformat]
+ local okay = converter[newformat]
+ if okay then
+ converter = okay
else
newformat = defaultformat
- if converter[newformat] then
- converter = converter[newformat]
- else
- converter = nil
- newformat = defaultformat
- end
+ converter = converter[newformat]
end
elseif trace_conversion then
report_inclusion("no converter for %a to %a",format,newformat)
end
if converter then
+ -- todo: make this a function
--
-- todo: outline as helper function
--
@@ -891,7 +900,7 @@ local function register(askedname,specification)
format = suffix
end
end
-specification.format = format
+ specification.format = format
elseif io.exists(oldname) then
report_inclusion("file %a is bugged",oldname)
if format and imagetypes[format] then
@@ -1425,6 +1434,7 @@ local transforms = setmetatableindex (
local function checktransform(figure,forced)
if auto_transform then
+
local orientation = (forced ~= "" and forced ~= v_auto and forced) or figure.orientation or 0
local transform = transforms["orientation-"..orientation]
figure.transform = transform
diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv
index 31c9cbce9..578bad1d0 100644
--- a/tex/context/base/mkiv/grph-inc.mkiv
+++ b/tex/context/base/mkiv/grph-inc.mkiv
@@ -904,6 +904,25 @@
\unexpanded\def\overlayfigure#1%
{\externalfigure[#1][\c!width=\d_overlay_width,\c!height=\d_overlay_height]}
+% Experimental (will become cleaner):
+
+\ifcase\contextlmtxmode \else
+
+ \unexpanded\def\includesvgfile {\dontleavehmode\begingroup\dodoubleempty\grph_include_svg_file}
+ \unexpanded\def\includesvgbuffer{\dontleavehmode\begingroup\dodoubleempty\grph_include_svg_buffer}
+
+ \def\grph_include_svg_file[#1][#2]%
+ {\getdummyparameters[\c!offset=\zeropoint,#2]%
+ \clf_includesvgfile{#1}\dimexpr\dummyparameter\c!offset\relax
+ \endgroup}
+
+ \def\grph_include_svg_buffer[#1][#2]%
+ {\getdummyparameters[\c!offset=\zeropoint,#2]%
+ \clf_includesvgbuffer{#1}\dimexpr\dummyparameter\c!offset\relax
+ \endgroup}
+
+\fi
+
% Bonus:
\useexternalfigure
diff --git a/tex/context/base/mkiv/grph-trf.mkiv b/tex/context/base/mkiv/grph-trf.mkiv
index 0c7ba22f8..274b2f8ef 100644
--- a/tex/context/base/mkiv/grph-trf.mkiv
+++ b/tex/context/base/mkiv/grph-trf.mkiv
@@ -603,8 +603,18 @@
\edef\p_sy{#2}%
\dowithnextboxcs\grph_scale_fast_sx_xy_finish\hbox}
+% \def\grph_scale_fast_sx_xy_finish
+% {\grph_scale_check_sx_sy
+% \grph_scale_calculations_nop
+% \grph_scale_apply
+% \box\nextbox
+% \egroup}
+
\def\grph_scale_fast_sx_xy_finish
{\grph_scale_check_sx_sy
+ \d_grph_scale_wd\wd\nextbox
+ \d_grph_scale_ht\ht\nextbox
+ \d_grph_scale_dp\dp\nextbox
\grph_scale_calculations_nop
\grph_scale_apply
\box\nextbox
diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua
index 13e0a3fa1..c57aaf33e 100644
--- a/tex/context/base/mkiv/l-unicode.lua
+++ b/tex/context/base/mkiv/l-unicode.lua
@@ -1081,56 +1081,62 @@ function utf.utf32_to_utf8_t(t,endian)
return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
-local function little(b)
- if b < 0x10000 then
- return char(b%256,rshift(b,8))
- else
- b = b - 0x10000
- local b1 = rshift(b,10) + 0xD800
- local b2 = b%1024 + 0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+if bit32 then
+
+ local rshift = bit32.rshift
+
+ local function little(b)
+ if b < 0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
-end
-local function big(b)
- if b < 0x10000 then
- return char(rshift(b,8),b%256)
- else
- b = b - 0x10000
- local b1 = rshift(b,10) + 0xD800
- local b2 = b%1024 + 0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ local function big(b)
+ if b < 0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
-end
-local l_remap = Cs((p_utf8byte/little+P(1)/"")^0)
-local b_remap = Cs((p_utf8byte/big +P(1)/"")^0)
+ local l_remap = Cs((p_utf8byte/little+P(1)/"")^0)
+ local b_remap = Cs((p_utf8byte/big +P(1)/"")^0)
-local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255) .. lpegmatch(b_remap,str)
+ local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255) .. lpegmatch(b_remap,str)
+ end
end
-end
-local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254) .. lpegmatch(l_remap,str)
+ local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254) .. lpegmatch(l_remap,str)
+ end
end
-end
-utf.utf8_to_utf16_be = utf8_to_utf16_be
-utf.utf8_to_utf16_le = utf8_to_utf16_le
+ utf.utf8_to_utf16_be = utf8_to_utf16_be
+ utf.utf8_to_utf16_le = utf8_to_utf16_le
-function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
+ function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
+
end
local pattern = Cs (
diff --git a/tex/context/base/mkiv/lang-txt.lua b/tex/context/base/mkiv/lang-txt.lua
index daf8f787e..f89795e39 100644
--- a/tex/context/base/mkiv/lang-txt.lua
+++ b/tex/context/base/mkiv/lang-txt.lua
@@ -36,6 +36,7 @@ if not modules then modules = { } end modules ['lang-txt'] = {
-- kr Korean Jeong Dalyoung
-- la Latin ...
-- lt Lithuanian Marius AlekneviÄius
+-- mk Macedonian Jakub Loula, Tomáš Hála (2019), Stojan Trajanovski
-- nb Norwegian Hans Fredrik Nordhaug, ...
-- nn Norwegian Hans Fredrik Nordhaug, ...
-- nl Dutch Hans Hagen
@@ -44,7 +45,7 @@ if not modules then modules = { } end modules ['lang-txt'] = {
-- pt Portuguese Pedro F. M. Mendonça
-- ro Romanian Dan Seracu, ...
-- ru Russian Olga Briginets, Alexander Bokovoy, Victor Figurnov, ...
--- sk Slovak ...
+-- sk Slovak Tomáš Hála (2012)
-- sl Slovenian Mojca Miklavec
-- sv Swedish ...
-- tk Turkish Tobias Burnus
@@ -73,6 +74,7 @@ data.labels={
["en"]="In",
["es"]="En",
["fr"]="Dans",
+ ["mk"]="во",
["pe"]="در",
},
},
@@ -81,6 +83,7 @@ data.labels={
["de"]="Numer",
["en"]="Number",
["fr"]="Numéro",
+ ["mk"]="Број",
["nl"]="Nummer",
["pe"]="شماره",
},
@@ -90,6 +93,7 @@ data.labels={
["de"]="Band",
["en"]="Volume",
["et"]="Köide",
+ ["mk"]="Том",
["nl"]="Deel",
["pe"]="جلد",
},
@@ -102,6 +106,7 @@ data.labels={
["et"]="ja",
["fr"]="et",
["it"]="e",
+ ["mk"]="и",
["nl"]="en",
["pe"]="Ùˆ",
},
@@ -114,6 +119,7 @@ data.labels={
["et"]="väljaanne",
["fr"]="édition",
["it"]="edizione",
+ ["mk"]="издание",
["nl"]="editie",
["pe"]="ویرایش",
},
@@ -125,6 +131,7 @@ data.labels={
["et"]="toimetaja",
["fr"]="éditeur",
["it"]="a cura di",
+ ["mk"]="уредник",
["pe"]="ویراستار",
},
},
@@ -136,6 +143,8 @@ data.labels={
["et"]="toimetajad",
["fr"]="éditeurs",
["it"]="a cura di",
+ ["mk"]="уредници",
+
},
},
["in"]={
@@ -143,6 +152,7 @@ data.labels={
["en"]="in",
["es"]="en",
["fr"]="dans",
+ ["mk"]="во",
["pe"]="در",
},
},
@@ -154,6 +164,7 @@ data.labels={
["et"]="magistritöö",
["fr"]="Thèse de master (DEA, DESS, master)",
["it"]="Tesi di laurea",
+ ["mk"]="МагиÑтерÑка диÑертација",
["nl"]="Masterproef",
["pe"]="پایان‌نامه کارشناسی ارشد",
},
@@ -163,6 +174,7 @@ data.labels={
["de"]="Numer",
["en"]="number",
["fr"]="numéro",
+ ["mk"]="број",
["nl"]="nummer",
["pe"]="شماره",
},
@@ -172,6 +184,7 @@ data.labels={
["de"]="von",
["en"]="of",
["fr"]="de",
+ ["mk"]="од",
["nl"]="van",
},
},
@@ -179,12 +192,14 @@ data.labels={
["labels"]={
["en"]="et al.",
["et"]="jt",
+ ["mk"]="и др.",
},
},
["p"]={
["labels"]={
["de"]="S.",
["en"]="p.",
+ ["mk"]="ÑÑ‚Ñ€.",
["et"]="lk",
["pe"]="ص",
},
@@ -194,6 +209,7 @@ data.labels={
["de"]="Seiten",
["en"]="pages",
["et"]="leheküljed",
+ ["mk"]="Ñтраници",
["nl"]="paginas",
["pe"]="صÙحات",
},
@@ -206,6 +222,7 @@ data.labels={
["et"]="Patent",
["fr"]="Brevet",
["it"]="Brevetto",
+ ["mk"]="Патент",
["nl"]="Octrooi",
},
},
@@ -217,6 +234,7 @@ data.labels={
["et"]="doktoritöö",
["fr"]="Thèse de doctorat",
["it"]="Tesi di dottorato",
+ ["mk"]="ДокторÑка диÑертација",
["nl"]="Proefschrift",
["pe"]="رساله دکتری",
},
@@ -226,6 +244,7 @@ data.labels={
["de"]="S.",
["en"]="pp.",
["et"]="lk-d",
+ ["mk"]="ÑÑ‚Ñ€.",
["pe"]="صص",
},
},
@@ -237,6 +256,7 @@ data.labels={
["et"]="tehniline raport",
["fr"]="Rapport technique",
["it"]="Relazione tecnica",
+ ["mk"]="Технички извештај",
["nl"]="Technisch rapport",
["pe"]="گزارش ÙÙ†ÛŒ",
},
@@ -246,6 +266,7 @@ data.labels={
["de"]="Band",
["en"]="volume",
["et"]="köide",
+ ["mk"]="том",
["nl"]="deel",
["pe"]="جلد",
},
@@ -258,6 +279,7 @@ data.labels={
["et"]="koos",
["fr"]="avec",
["it"]="con",
+ ["mk"]="Ñо",
["nl"]="met",
},
},
@@ -267,6 +289,7 @@ data.labels={
["labels"]={
["cz"]="P",
["en"]="Pr",
+ ["mk"]="P",
["sk"]="P",
},
},
@@ -276,6 +299,7 @@ data.labels={
["en"]="arccos",
["es"]="arc\\sixperemspace cos",
["hr"]="arc\\sixperemspace cos",
+ ["mk"]="arccos",
["pl"]="arc\\sixperemspace cos",
["sk"]="arccos",
},
@@ -286,6 +310,7 @@ data.labels={
["en"]="arccosh",
["es"]="arc\\sixperemspace cosh",
["hr"]="arc\\sixperemspace cosh",
+ ["mk"]="arccosh",
["pl"]="arc\\sixperemspace cosh",
["sk"]="arccosh",
},
@@ -296,6 +321,7 @@ data.labels={
["en"]="arccot",
["es"]="arc\\sixperemspace cot",
["hr"]="arc\\sixperemspace ctg",
+ ["mk"]="arccotg",
["pl"]="arc\\sixperemspace ctg",
["sk"]="arccotg",
},
@@ -306,6 +332,7 @@ data.labels={
["en"]="arcsin",
["es"]="arc\\sixperemspace sen",
["hr"]="arc\\sixperemspace sin",
+ ["mk"]="arcsin",
["pl"]="arc\\sixperemspace sin",
["sk"]="arcsin",
},
@@ -316,6 +343,7 @@ data.labels={
["en"]="arcsinh",
["es"]="arc\\sixperemspace senh",
["hr"]="arc\\sixperemspace sinh",
+ ["mk"]="arcsinh",
["pl"]="arc\\sixperemspace sinh",
["sk"]="arcsinh",
},
@@ -326,6 +354,7 @@ data.labels={
["en"]="arctan",
["es"]="arc\\sixperemspace tan",
["hr"]="arc\\sixperemspace tg",
+ ["mk"]="arctg",
["pl"]="arc\\sixperemspace tg",
["sk"]="arctg",
},
@@ -336,8 +365,9 @@ data.labels={
["en"]="arctanh",
["es"]="arc\\sixperemspace tanh",
["hr"]="arc\\sixperemspace tgh",
+ ["mk"]="arctgh",
["pl"]="arc\\sixperemspace tgh",
- ["sk"]="arctg",
+ ["sk"]="arctgh",
},
},
["arg"]={
@@ -345,6 +375,7 @@ data.labels={
["cz"]="arg",
["en"]="arg",
["es"]="arg",
+ ["mk"]="arg",
["sk"]="arg",
},
},
@@ -353,6 +384,7 @@ data.labels={
["cz"]="cos",
["en"]="cos",
["es"]="cos",
+ ["mk"]="cos",
["sk"]="cos",
},
},
@@ -361,6 +393,7 @@ data.labels={
["cz"]="cosh",
["en"]="cosh",
["es"]="cosh",
+ ["mk"]="cosh",
["sk"]="cosh",
},
},
@@ -370,6 +403,7 @@ data.labels={
["en"]="cot",
["es"]="cot",
["hr"]="ctg",
+ ["mk"]="ctg",
["pl"]="ctg",
["sk"]="cotg",
},
@@ -379,6 +413,7 @@ data.labels={
["cz"]="cotgh",
["en"]="coth",
["es"]="coth",
+ ["mk"]="ctgh",
["sk"]="cotgh",
},
},
@@ -387,6 +422,7 @@ data.labels={
["cz"]="cosec",
["en"]="csc",
["es"]="csc",
+ ["mk"]="cosec",
["sk"]="cosec",
},
},
@@ -396,6 +432,7 @@ data.labels={
["en"]="cot",
["es"]="cot",
["hr"]="ctg",
+ ["mk"]="ctg",
["pl"]="ctg",
["sk"]="cotg",
},
@@ -405,6 +442,7 @@ data.labels={
["cz"]="deg",
["en"]="deg",
["es"]="gr",
+ ["mk"]="deg",
["sk"]="deg",
},
},
@@ -426,6 +464,7 @@ data.labels={
["cz"]="dim",
["en"]="dim",
["es"]="dim",
+ ["mk"]="dim",
["sk"]="dim",
},
},
@@ -443,6 +482,7 @@ data.labels={
["en"]="gcd",
["es"]="mcd",
["hr"]="nzd",
+ ["mk"]="ÐЗД",
["nl"]="ggd",
["sk"]="NSD",
},
@@ -460,6 +500,7 @@ data.labels={
["cz"]="inf",
["en"]="inf",
["es"]="inf",
+ ["mk"]="inf",
["sk"]="inf",
},
},
@@ -485,6 +526,7 @@ data.labels={
["en"]="lcm",
["es"]="MCM",
["hr"]="nzv",
+ ["mk"]="ÐЗС",
["nl"]="kgv",
["sk"]="NSN",
},
@@ -494,6 +536,7 @@ data.labels={
["cz"]="log",
["en"]="lg",
["es"]="log",
+ ["mk"]="lg",
["sk"]="log",
},
},
@@ -502,6 +545,7 @@ data.labels={
["cz"]="lim",
["en"]="lim",
["es"]="lím",
+ ["mk"]="lim",
["sk"]="lim",
},
},
@@ -510,6 +554,7 @@ data.labels={
["cz"]="lim\\sixperemspace inf",
["en"]="lim\\sixperemspace inf",
["es"]="lím\\sixperemspace inf",
+ ["mk"]="lim\\sixperemspace inf",
["sk"]="lim\\sixperemspace inf",
},
},
@@ -518,6 +563,7 @@ data.labels={
["cz"]="lim\\sixperemspace sup",
["en"]="lim\\sixperemspace sup",
["es"]="lím\\sixperemspace sup",
+ ["mk"]="lim\\sixperemspace sup",
["sk"]="lim\\sixperemspace sup",
},
},
@@ -526,6 +572,7 @@ data.labels={
["cz"]="ln",
["en"]="ln",
["es"]="ln",
+ ["mk"]="ln",
["sk"]="ln",
},
},
@@ -534,6 +581,7 @@ data.labels={
["cz"]="log",
["en"]="log",
["es"]="log",
+ ["mk"]="log",
["sk"]="log",
},
},
@@ -542,6 +590,7 @@ data.labels={
["cz"]="max",
["en"]="max",
["es"]="máx",
+ ["mk"]="max",
["sk"]="max",
},
},
@@ -558,6 +607,7 @@ data.labels={
["cz"]="min",
["en"]="min",
["es"]="mín",
+ ["mk"]="min",
["sk"]="min",
},
},
@@ -566,6 +616,7 @@ data.labels={
["cz"]="mod",
["en"]="mod",
["es"]="mod",
+ ["mk"]="mod",
["sk"]="mod",
},
},
@@ -582,6 +633,7 @@ data.labels={
["cz"]="sec",
["en"]="sec",
["es"]="sec",
+ ["mk"]="sec",
["sk"]="sec",
},
},
@@ -590,6 +642,7 @@ data.labels={
["cz"]="sin",
["en"]="sin",
["es"]="sen",
+ ["mk"]="sin",
["sk"]="sin",
},
},
@@ -598,6 +651,7 @@ data.labels={
["cz"]="sinh",
["en"]="sinh",
["es"]="senh",
+ ["mk"]="sinh",
["sk"]="sinh",
},
},
@@ -606,6 +660,7 @@ data.labels={
["cz"]="sup",
["en"]="sup",
["es"]="sup",
+ ["mk"]="sup",
["sk"]="sup",
},
},
@@ -615,6 +670,7 @@ data.labels={
["en"]="tan",
["es"]="tan",
["hr"]="tg",
+ ["mk"]="tg",
["pl"]="tg",
["sk"]="tg",
},
@@ -624,6 +680,7 @@ data.labels={
["cz"]="tgh",
["en"]="tanh",
["es"]="tanh",
+ ["mk"]="tgh",
["sk"]="tgh",
},
},
@@ -659,6 +716,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="",
+ ["mk"]=" и ",
["nb"]="",
["nl"]=" en ",
["nn"]="",
@@ -699,6 +757,7 @@ data.labels={
["kr"]="부ë¡",
["la"]="",
["lt"]="",
+ ["mk"]="Додаток ",
["nb"]="Tillegg ",
["nl"]="",
["nn"]="Tillegg ",
@@ -741,6 +800,7 @@ data.labels={
["la"]="Aprilis",
["lt"]="balandžio",
["nb"]="april",
+ ["mk"]="април",
["nl"]="april",
["nn"]="april",
["pe"]="آوریل",
@@ -781,6 +841,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="apr",
+ ["mk"]="апр.",
["nb"]="april",
["nl"]="",
["nn"]="april",
@@ -816,6 +877,7 @@ data.labels={
["it"]="a pagina ",
["la"]="",
["lt"]="puslapyje ",
+ ["mk"]="на Ñтраница ",
["nb"]="på side ",
["nl"]="op pagina ",
["nn"]="på side ",
@@ -858,6 +920,7 @@ data.labels={
["kr"]="8",
["la"]="Augustus",
["lt"]="rugpjÅ«Äio",
+ ["mk"]="авгуÑÑ‚",
["nb"]="august",
["nl"]="augustus",
["nn"]="august",
@@ -899,6 +962,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="aug",
+ ["mk"]="авг.",
["nb"]="aug.",
["nl"]="",
["nn"]="aug.",
@@ -938,6 +1002,7 @@ data.labels={
["kr"]={ "제", "장" },
["la"]="",
["lt"]="",
+ ["mk"]="Глава ",
["nb"]="",
["nl"]="",
["nn"]="",
@@ -973,6 +1038,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="",
+ ["mk"]=" (продолжение)",
["nb"]="",
["nl"]=" (vervolgd)",
["nn"]="",
@@ -995,6 +1061,7 @@ data.labels={
["en"]="day",
["et"]="päev",
["kr"]="ì¼",
+ ["mk"]="ден",
["nl"]="dag",
["pe"]="روز",
},
@@ -1024,6 +1091,7 @@ data.labels={
["la"]="December",
["lt"]="gruodžio",
["nb"]="desember",
+ ["mk"]="декември",
["nl"]="december",
["nn"]="desember",
["pe"]="دسامبر",
@@ -1064,6 +1132,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="dec",
+ ["mk"]="дек.",
["nb"]="des.",
["nl"]="",
["nn"]="des.",
@@ -1104,6 +1173,7 @@ data.labels={
["kr"]="2",
["la"]="Februarius",
["lt"]="vasario",
+ ["mk"]="февруари",
["nb"]="februar",
["nl"]="februari",
["nn"]="februar",
@@ -1145,6 +1215,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="feb",
+ ["mk"]="фев.",
["nb"]="feb.",
["nl"]="",
["nn"]="feb.",
@@ -1183,6 +1254,7 @@ data.labels={
["kr"]="그림 ",
["la"]="Imago ",
["lt"]={ "", " pav." },
+ ["mk"]="Слика ",
["nb"]="Figur ",
["nl"]="Figuur ",
["nn"]="Figur ",
@@ -1204,6 +1276,7 @@ data.labels={
["labels"]={
["en"]="on a following page",
["et"]="järgmisel leheküljel",
+ ["mk"]="на Ñледната Ñтраница",
["nl"]="op een volgende bladzijde",
["pe"]="در صÙحات آینده",
},
@@ -1230,6 +1303,7 @@ data.labels={
["kr"]="금요ì¼",
["la"]="Dies Veneris",
["lt"]="penktadienis",
+ ["mk"]="петок",
["nb"]="fredag",
["nl"]="vrijdag",
["nn"]="fredag",
@@ -1268,6 +1342,7 @@ data.labels={
["ja"]="イラスト",
["la"]="Typus ",
["lt"]="Graphic ",
+ ["mk"]="График ",
["nb"]="Bilde ",
["nl"]="Grafiek ",
["nn"]="Bilete ",
@@ -1305,6 +1380,7 @@ data.labels={
["kr"]="그러므로",
["la"]="",
["lt"]="kaip parodyta aukÅ¡Äiau",
+ ["mk"]="како што е прикажано погоре",
["nb"]="som vist over",
["nl"]="hierboven",
["nn"]="som vist over",
@@ -1342,6 +1418,7 @@ data.labels={
["kr"]="ì´í›„ë¡œ",
["la"]="",
["lt"]="kaip parodyta žemiau",
+ ["mk"]="како што е прикажано подолу",
["nb"]="som vist under",
["nl"]="hieronder",
["nn"]="som vist under",
@@ -1381,6 +1458,7 @@ data.labels={
["kr"]="간주곡",
["la"]="Intermissum ",
["lt"]="Intermezzo ",
+ ["mk"]="ДигреÑија ",
["nb"]="Intermesso ",
["nl"]="Intermezzo ",
["nn"]="Intermesso ",
@@ -1421,6 +1499,7 @@ data.labels={
["kr"]="1",
["la"]="Ianuarius",
["lt"]="sausio",
+ ["mk"]="јануари",
["nb"]="januar",
["nl"]="januari",
["nn"]="januar",
@@ -1462,6 +1541,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="jan",
+ ["mk"]="jан.",
["nb"]="jan.",
["nl"]="",
["nn"]="jan.",
@@ -1503,6 +1583,7 @@ data.labels={
["kr"]="7",
["la"]="Iulius",
["lt"]="liepos",
+ ["mk"]="јули",
["nb"]="juli",
["nl"]="juli",
["nn"]="juli",
@@ -1544,6 +1625,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="jul",
+ ["mk"]="јул.",
["nb"]="juli",
["nl"]="",
["nn"]="juli",
@@ -1584,6 +1666,7 @@ data.labels={
["kr"]="6",
["la"]="Iunius",
["lt"]="birželio",
+ ["mk"]="јуни",
["nb"]="juni",
["nl"]="juni",
["nn"]="juni",
@@ -1625,6 +1708,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="jun",
+ ["mk"]="јун.",
["nb"]="juni",
["nl"]="",
["nn"]="juni",
@@ -1663,6 +1747,7 @@ data.labels={
["kr"]="í–‰",
["la"]="versus ",
["lt"]="line ",
+ ["mk"]="линија ",
["nb"]="linje ",
["nl"]="regel ",
["nn"]="linje ",
@@ -1702,6 +1787,7 @@ data.labels={
["kr"]="í–‰",
["la"]="versus ",
["lt"]="lines ",
+ ["mk"]="линии ",
["nb"]="linjer ",
["nl"]="regels ",
["nn"]="linjer ",
@@ -1742,6 +1828,7 @@ data.labels={
["kr"]="3",
["la"]="Martius",
["lt"]="kovo",
+ ["mk"]="март",
["nb"]="mars",
["nl"]="maart",
["nn"]="mars",
@@ -1783,6 +1870,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="mar",
+ ["mk"]="мар.",
["nb"]="mars",
["nl"]="",
["nn"]="mars",
@@ -1824,6 +1912,7 @@ data.labels={
["kr"]="5",
["la"]="Maius",
["lt"]="gegužės",
+ ["mk"]="мај",
["nb"]="mai",
["nl"]="mei",
["nn"]="mai",
@@ -1865,6 +1954,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="may",
+ ["mk"]="мај",
["nb"]="mai",
["nl"]="",
["nn"]="mai",
@@ -1903,6 +1993,7 @@ data.labels={
["kr"]="월요ì¼",
["la"]="Dies Lunae",
["lt"]="pirmadienis",
+ ["mk"]="понеделник",
["nb"]="mandag",
["nl"]="maandag",
["nn"]="måndag",
@@ -1925,6 +2016,7 @@ data.labels={
["en"]="month",
["et"]="kuu",
["kr"]="ì›”",
+ ["mk"]="меÑец",
["nl"]="maand",
["pe"]="ماه",
},
@@ -1953,6 +2045,7 @@ data.labels={
["kr"]="11",
["la"]="November",
["lt"]="lapkriÄio",
+ ["mk"]="ноември",
["nb"]="november",
["nl"]="november",
["nn"]="november",
@@ -1994,6 +2087,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="nov",
+ ["mk"]="ноем.",
["nb"]="nov.",
["nl"]="",
["nn"]="nov.",
@@ -2033,6 +2127,7 @@ data.labels={
["kr"]="10",
["la"]="October",
["lt"]="spalio",
+ ["mk"]="октомври",
["nb"]="oktober",
["nl"]="oktober",
["nn"]="oktober",
@@ -2074,6 +2169,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="oct",
+ ["mk"]="окт.",
["nb"]="okt.",
["nl"]="",
["nn"]="okt.",
@@ -2110,6 +2206,7 @@ data.labels={
["kr"]="쪽",
["la"]="",
["lt"]="puslapis ",
+ ["mk"]="Ñтраница ",
["nb"]="side ",
["nl"]="pagina ",
["nn"]="side ",
@@ -2149,7 +2246,8 @@ data.labels={
["kr"]={ "제", "부" },
["la"]="Pars ",
["lt"]={ "", " dalis" },
- ["nb"]="Del",
+ ["mk"]="Дел ",
+ ["nb"]="Del ",
["nl"]="Deel ",
["nn"]="Del",
["pe"]="قسمت ",
@@ -2170,6 +2268,7 @@ data.labels={
["labels"]={
["en"]="on a preceding page",
["et"]="eelmisel lehel",
+ ["mk"]="на претходната Ñтраница",
["nl"]="op een voorgaande bladzijde",
["pe"]="در صÙحات گذشته",
},
@@ -2196,6 +2295,7 @@ data.labels={
["kr"]="토요ì¼",
["la"]="Dies Saturni",
["lt"]="šeštadienis",
+ ["mk"]="Ñабота",
["nb"]="lørdag",
["nl"]="zaterdag",
["nn"]="laurdag",
@@ -2237,6 +2337,7 @@ data.labels={
["la"]="",
["lt"]="",
["nb"]="",
+ ["mk"]="Поглавје ",
["nl"]="",
["nn"]="",
["pe"]="بخش ",
@@ -2273,6 +2374,7 @@ data.labels={
["kr"]="",
["la"]="",
["lt"]="žiūrėti ",
+ ["mk"]="види ",
["nb"]="se ",
["nl"]="zie ",
["nn"]="sjå ",
@@ -2314,6 +2416,7 @@ data.labels={
["kr"]="9",
["la"]="September",
["lt"]="rugsÄ—jo",
+ ["mk"]="Ñептември",
["nb"]="september",
["nl"]="september",
["nn"]="september",
@@ -2355,6 +2458,7 @@ data.labels={
["it"]="",
["la"]="",
["lt"]="sep",
+ ["mk"]="Ñепт.",
["nb"]="sep.",
["nl"]="",
["nn"]="sep.",
@@ -2393,6 +2497,7 @@ data.labels={
["ja"]="",
["la"]="",
["lt"]="",
+ ["mk"]="Подпоглавје ",
["nb"]="",
["nl"]="",
["nn"]="",
@@ -2432,6 +2537,7 @@ data.labels={
["ja"]="",
["la"]="",
["lt"]="",
+ ["mk"]="Подподпоглавје ",
["nb"]="",
["nl"]="",
["nn"]="",
@@ -2471,6 +2577,7 @@ data.labels={
["ja"]="",
["la"]="",
["lt"]="",
+ ["mk"]="Подподподпоглавје ",
["nb"]="",
["nl"]="",
["nn"]="",
@@ -2510,6 +2617,7 @@ data.labels={
["kr"]="ì¼ìš”ì¼",
["la"]="Dies Solis",
["lt"]="sekmadienis",
+ ["mk"]="недела",
["nb"]="søndag",
["nl"]="zondag",
["nn"]="sundag",
@@ -2549,6 +2657,7 @@ data.labels={
["kr"]="표 ",
["la"]="Tabula ",
["lt"]={ "", " lentelÄ—." },
+ ["mk"]="Табела ",
["nb"]="Tabell ",
["nl"]="Tabel ",
["nn"]="Tabell ",
@@ -2588,6 +2697,7 @@ data.labels={
["kr"]="목요ì¼",
["la"]="Dies Iovis",
["lt"]="ketvirtadienis",
+ ["mk"]="четврток",
["nb"]="torsdag",
["nl"]="donderdag",
["nn"]="torsdag",
@@ -2627,6 +2737,7 @@ data.labels={
["kr"]="화요ì¼",
["la"]="Dies Martis",
["lt"]="antradienis",
+ ["mk"]="вторник",
["nb"]="tirsdag",
["nl"]="dinsdag",
["nn"]="tysdag",
@@ -2666,6 +2777,7 @@ data.labels={
["kr"]="수요ì¼",
["la"]="Dies Mercuri",
["lt"]="treÄiadienis",
+ ["mk"]="Ñреда",
["nb"]="onsdag",
["nl"]="woensdag",
["nn"]="onsdag",
@@ -2688,6 +2800,7 @@ data.labels={
["en"]="year",
["et"]="aasta",
["kr"]="ë…„",
+ ["mk"]="година",
["nl"]="jaar",
["pe"]="سال",
},
@@ -2716,6 +2829,7 @@ data.labels={
["kr"]="약어",
["la"]="Notae",
["lt"]="Santrumpos",
+ ["mk"]="Скратеници",
["nb"]="Forkortelser",
["nl"]="Afkortingen",
["nn"]="Forkortingar",
@@ -2755,6 +2869,7 @@ data.labels={
["kr"]="목차",
["la"]="Quod in libro continetur",
["lt"]="Turinys",
+ ["mk"]="Содржина",
["nb"]="Innhold",
["nl"]="Inhoud",
["nn"]="Innhald",
@@ -2794,6 +2909,7 @@ data.labels={
["kr"]="그림 ",
["la"]="Imagines",
["lt"]="Iliustracijos",
+ ["mk"]="ЛиÑта на Ñлики",
["nb"]="Figurer",
["nl"]="Figuren",
["nn"]="Figurar",
@@ -2833,6 +2949,7 @@ data.labels={
["kr"]="그래픽 ",
["la"]="Typi",
["lt"]="Graphics",
+ ["mk"]="ЛиÑта на графици",
["nb"]="Bilde",
["nl"]="Grafieken",
["nn"]="Bilete",
@@ -2872,6 +2989,7 @@ data.labels={
["kr"]="찾아보기",
["la"]="Indices",
["lt"]="RodyklÄ—",
+ ["mk"]="ИндекÑ",
["nb"]="Register",
["nl"]="Index",
["nn"]="Register",
@@ -2911,6 +3029,7 @@ data.labels={
["kr"]="간주곡",
["la"]="Intermissa",
["lt"]="Intermezzos",
+ ["mk"]="ЛиÑта на дигреÑии",
["nb"]="Intermesso",
["nl"]="Intermezzo's",
["nn"]="Intermesso",
@@ -2949,6 +3068,7 @@ data.labels={
["kr"]="ì´ì„±",
["la"]="Typi negotiales",
["lt"]="Logos",
+ ["mk"]="Логоа",
["nb"]="Logoer",
["nl"]="Logo's",
["nn"]="Logoar",
@@ -2985,6 +3105,7 @@ data.labels={
["kr"]="참고문헌",
["la"]="",
["lt"]="Literatūra",
+ ["mk"]="Литература",
["nb"]="",
["nl"]="Literatuur",
["nn"]="",
@@ -3024,6 +3145,7 @@ data.labels={
["kr"]="표 ",
["la"]="Tabulae",
["lt"]="LentelÄ—s",
+ ["mk"]="ЛиÑта на табели",
["nb"]="Tabeller",
["nl"]="Tabellen",
["nn"]="Tabellar",
@@ -3063,6 +3185,7 @@ data.labels={
["kr"]="측정단위",
["la"]="Modi",
["lt"]="Units",
+ ["mk"]="Единици",
["nb"]="Enheter",
["nl"]="Eenheden",
["nn"]="Einingar",
diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua
index 05f18f512..1c4a3ba27 100644
--- a/tex/context/base/mkiv/lpdf-ano.lua
+++ b/tex/context/base/mkiv/lpdf-ano.lua
@@ -133,6 +133,99 @@ local function checkautoprefixes(destinations)
end
end
+local maxslice = 32 -- could be made configureable ... 64 is also ok
+
+local function pdfmakenametree(list,apply)
+ if not next(list) then
+ return
+ end
+ local slices = { }
+ local sorted = sortedkeys(list)
+ local size = #sorted
+ local maxslice = maxslice
+ if size <= 1.5*maxslice then
+ maxslice = size
+ end
+ for i=1,size,maxslice do
+ local amount = min(i+maxslice-1,size)
+ local names = pdfarray { }
+ local n = 0
+ for j=i,amount do
+ local name = sorted[j]
+ local target = list[name]
+ n = n + 1 ; names[n] = tostring(name)
+ n = n + 1 ; names[n] = apply and apply(target) or target
+ end
+ local first = sorted[i]
+ local last = sorted[amount]
+ local limits = pdfarray {
+ first,
+ last,
+ }
+ local d = pdfdictionary {
+ Names = names,
+ Limits = limits,
+ }
+ slices[#slices+1] = {
+ reference = pdfreference(pdfflushobject(d)),
+ limits = limits,
+ }
+ end
+ local function collectkids(slices,first,last)
+ local f = slices[first]
+ local l = slices[last]
+ if f and l then
+ local k = pdfarray()
+ local n = 0
+ local d = pdfdictionary {
+ Kids = k,
+ Limits = pdfarray {
+ f.limits[1],
+ l.limits[2],
+ },
+ }
+ for i=first,last do
+ n = n + 1 ; k[n] = slices[i].reference
+ end
+ return d
+ end
+ end
+ if #slices == 1 then
+ return slices[1].reference
+ else
+ while true do
+ local size = #slices
+ if size > maxslice then
+ local temp = { }
+ local n = 0
+ for i=1,size,maxslice do
+ local kids = collectkids(slices,i,min(i+maxslice-1,size))
+ if kids then
+ n = n + 1
+ temp[n] = {
+ reference = pdfreference(pdfflushobject(kids)),
+ limits = kids.Limits,
+ }
+ else
+ -- error
+ end
+ end
+ slices = temp
+ else
+ local kids = collectkids(slices,1,size)
+ if kids then
+ return pdfreference(pdfflushobject(kids))
+ else
+ -- error
+ return
+ end
+ end
+ end
+ end
+end
+
+lpdf.makenametree = pdfmakenametree
+
-- Bah, I hate this kind of features .. anyway, as we have delayed resolving we
-- only support a document-wide setup and it has to be set before the first one
-- is used. Also, we default to a non-intrusive gray and the outline is kept
@@ -237,8 +330,6 @@ end
lpdf.registerdestination = pdfregisterdestination
-local maxslice = 32 -- could be made configureable ... 64 is also ok
-
logs.registerfinalactions(function()
if log_destinations and next(destinations) then
local report = logs.startfilelogging("references","used destinations")
@@ -252,98 +343,10 @@ logs.registerfinalactions(function()
end
end)
-local function pdfnametree(destinations)
- local slices = { }
- checkautoprefixes(destinations)
- if not next(destinations) then
- return
- end
- local sorted = sortedkeys(destinations)
- local size = #sorted
-
- if size <= 1.5*maxslice then
- maxslice = size
- end
-
- for i=1,size,maxslice do
- local amount = min(i+maxslice-1,size)
- local names = pdfarray { }
- local n = 0
- for j=i,amount do
- local destination = sorted[j]
- local pagenumber = destinations[destination]
- n = n + 1 ; names[n] = tostring(destination) -- tostring is a safeguard
- n = n + 1 ; names[n] = pdfreference(pagenumber)
- end
- local first = sorted[i]
- local last = sorted[amount]
- local limits = pdfarray {
- first,
- last,
- }
- local d = pdfdictionary {
- Names = names,
- Limits = limits,
- }
- slices[#slices+1] = {
- reference = pdfreference(pdfflushobject(d)),
- limits = limits,
- }
- end
- local function collectkids(slices,first,last)
- local f = slices[first]
- local l = slices[last]
- if f and l then
- local k = pdfarray()
- local n = 0
- local d = pdfdictionary {
- Kids = k,
- Limits = pdfarray {
- f.limits[1],
- l.limits[2],
- },
- }
- for i=first,last do
- n = n + 1 ; k[n] = slices[i].reference
- end
- return d
- end
- end
- if #slices == 1 then
- return slices[1].reference
- else
- while true do
- if #slices > maxslice then
- local temp = { }
- local size = #slices
- for i=1,size,maxslice do
- local kids = collectkids(slices,i,min(i+maxslice-1,size))
- if kids then
- temp[#temp+1] = {
- reference = pdfreference(pdfflushobject(kids)),
- limits = kids.Limits,
- }
- else
- -- error
- end
- end
- slices = temp
- else
- local kids = collectkids(slices,1,#slices)
- if kids then
- return pdfreference(pdfflushobject(kids))
- else
- -- error
- return
- end
- end
- end
- end
-end
-
local function pdfdestinationspecification()
if next(destinations) then -- safeguard
- local r = pdfnametree(destinations)
+ checkautoprefixes(destinations)
+ local r = pdfmakenametree(destinations,pdfreference)
if r then
pdfaddtonames("Dests",r)
end
@@ -353,7 +356,6 @@ local function pdfdestinationspecification()
end
end
-lpdf.nametree = pdfnametree
lpdf.destinationspecification = pdfdestinationspecification
lpdf.registerdocumentfinalizer(pdfdestinationspecification,"collect destinations")
diff --git a/tex/context/base/mkiv/lpdf-img.lua b/tex/context/base/mkiv/lpdf-img.lua
index 4e54989cd..97b596937 100644
--- a/tex/context/base/mkiv/lpdf-img.lua
+++ b/tex/context/base/mkiv/lpdf-img.lua
@@ -65,6 +65,18 @@ trackers.register("graphics.backend", function(v) trace = v end)
local injectors = { }
lpdf.injectors = injectors
+-- todo: load from a virtual file
+
+local function loadcontent(filename,method)
+ return method == "string" and filename or loaddata(filename)
+end
+
+local function newcontent(filename,method)
+ return newreader(filename,method)
+end
+
+--
+
local chars = setmetatableindex(function(t,k) -- share this one
local v = (k <= 0 and "\000") or (k >= 255 and "\255") or char(k)
t[k] = v
@@ -73,7 +85,7 @@ end)
do
- function injectors.jpg(specification)
+ function injectors.jpg(specification,method)
if specification.error then
return
end
@@ -96,7 +108,7 @@ do
local xsize = specification.xsize
local ysize = specification.ysize
local colordepth = specification.colordepth
- local content = loaddata(filename)
+ local content = loadcontent(filename,method)
local xobject = pdfdictionary {
Type = pdfconstant("XObject"),
Subtype = pdfconstant("Image"),
@@ -127,7 +139,7 @@ end
do
- function injectors.jp2(specification)
+ function injectors.jp2(specification,method)
if specification.error then
return
end
@@ -138,7 +150,7 @@ do
-- todo: set filename
local xsize = specification.xsize
local ysize = specification.ysize
- local content = loaddata(filename)
+ local content = loadcontent(filename,method)
local xobject = pdfdictionary {
Type = pdfconstant("XObject"),
Subtype = pdfconstant("Image"),
@@ -936,7 +948,7 @@ do
if not idat then
return
end
- local pngfile = newreader(filename,method)
+ local pngfile = newcontent(filename,method)
if not pngfile then
return
end
@@ -1074,7 +1086,7 @@ do
else
pallette = false
end
- elseif decode then
+ elseif decode or (enforcecmyk and not palette) then
-- this one needs checking
local bytes = analyze(colordepth,colorspace)
if bytes then
@@ -1091,6 +1103,7 @@ do
else
return
end
+ decode = true -- due to enforcecmyk
else
-- print("PASS ON")
end
diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua
index fd1e52aad..b039daa58 100644
--- a/tex/context/base/mkiv/lpdf-ini.lua
+++ b/tex/context/base/mkiv/lpdf-ini.lua
@@ -1502,12 +1502,12 @@ end
do
- local f_actual_text_p = formatters["BT /Span << /ActualText <feff%s> >> BDC %s EMC ET"]
- local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"]
- local s_actual_text_e = "EMC ET"
- local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"]
- local s_actual_text_e_not = "EMC"
- local f_actual_text = formatters["/Span <</ActualText %s >> BDC"]
+ local f_actual_text_p = formatters["BT /Span << /ActualText <feff%s> >> BDC %s EMC ET"]
+ local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"]
+ local s_actual_text_e = "EMC ET"
+ local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"]
+ local s_actual_text_e_not = "EMC"
+ local f_actual_text = formatters["/Span <</ActualText %s >> BDC"]
local context = context
local pdfdirect = nodes.pool.directliteral -- we can use nuts.write deep down
@@ -1689,5 +1689,3 @@ end
if environment.arguments.nocompression then
lpdf.setcompression(0,0,true)
end
-
-
diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua
index b46274b34..4cce7fc74 100644
--- a/tex/context/base/mkiv/lpdf-lmt.lua
+++ b/tex/context/base/mkiv/lpdf-lmt.lua
@@ -79,8 +79,6 @@ local properties = fonthashes.properties
local report = logs.reporter("backend")
-local trace_threshold = false trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end)
-
-- used variables
local pdf_h, pdf_v
@@ -89,7 +87,7 @@ local need_width, need_mode, done_width, done_mode
local mode
local f_pdf_cur, f_pdf, fs_cur, fs, f_cur
local tj_delta, cw
-local usedfonts, usedxforms, usedximages
+local usedfonts, usedxforms, usedximages, usedxgroups
local getxformname, getximagename
local boundingbox, shippingmode, objectnumber
local tmrx, tmry, tmsx, tmsy, tmtx, tmty
@@ -132,6 +130,7 @@ local function reset_variables(specification)
usedfonts = setmetatableindex(usefont)
usedxforms = { }
usedximages = { }
+ -- usedxgroups = { }
boundingbox = specification.boundingbox
end
@@ -521,6 +520,8 @@ local flushcharacter do
return v
end)
+ 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)
if need_tf or font ~= f_cur or f_pdf ~= f_pdf_cur or fs ~= fs_cur or mode == "page" then
pdf_goto_textmode()
@@ -842,6 +843,11 @@ end
-- rules
+local f_font = formatters["F%d"]
+local f_form = formatters["Fm%d"]
+local f_group = formatters["Gp%d"]
+local f_image = formatters["Im%d"]
+
local flushedxforms = { } -- actually box resources but can also be direct
local localconverter = nil -- will be set
@@ -1040,6 +1046,37 @@ local flushrule, flushsimplerule, flushimage do
pdf.getximagename = getximagename
end)
+ -- Groups are flushed immediately but we can decide to make them into a
+ -- specific whatsit ... but not now. We could hash them if needed when
+ -- we use lot sof them in mp ... but not now.
+
+ usedxgroups = { }
+ local groups = 0
+ local group = nil
+
+ function lpdf.flushgroup(content,bbox)
+ if not group then
+ group = pdfdictionary {
+ Type = pdfconstant("Group"),
+ S = pdfconstant("Transparency"),
+ }
+ end
+ local wrapper = pdfdictionary {
+ Type = pdf_xobject,
+ Subtype = pdf_form,
+ FormType = 1,
+ Group = group,
+ BBox = pdfarray(bbox),
+ Resources = lpdf.collectedresources { serialize = false },
+ }
+ local objnum = pdfflushstreamobject(content,wrapper,false)
+ groups = groups + 1
+ usedxgroups[groups] = objnum
+ return f_group(groups)
+ end
+
+ -- end of experiment
+
local function flushpdfximage(current,pos_h,pos_v,pos_r,size_h,size_v)
local width,
@@ -1053,7 +1090,7 @@ local flushrule, flushsimplerule, flushimage do
yorigin,
xsize,
ysize,
- rotation,
+ rotation, -- transform / orientation / rotation : it's a mess (i need to redo this)
objnum,
groupref = pdfincludeimage(index) -- needs to be sorted out, bad name (no longer mixed anyway)
@@ -1064,6 +1101,8 @@ local flushrule, flushsimplerule, flushimage do
local rx, sx, sy, ry, tx, ty = 1, 0, 0, 1, 0, 0
+ -- tricky: xsize and ysize swapped
+
if kind == img_pdf or kind == img_stream or kind == img_memstream then
rx, ry, tx, ty = 1/xsize, 1/ysize, xorigin/xsize, yorigin/ysize
else
@@ -1364,15 +1403,70 @@ local function initialize(driver,details)
reset_buffer()
end
-local f_font = formatters["F%d"]
-local f_form = formatters["Fm%d"]
-local f_image = formatters["Im%d"]
-
-- This will all move and be merged and become less messy.
-- todo: more clever resource management: a bit tricky as we can inject
-- stuff in the page stream
+local compact = false
+
+do
+
+ -- This is more a convenience feature and it might even be not entirely robust.
+ -- It removes redundant color directives which makes the page stream look a bit
+ -- nicer (also when figuring out issues). I might add more here but there is
+ -- some additional overhead involved so runtime can be impacted.
+
+ local P, R, S, Cs, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cs, lpeg.match
+
+ local p_ds = (R("09") + S(" ."))^1
+ ----- p_nl = S("\n\r")^1
+ local p_nl = S("\n")^1
+ local p_eg = P("Q")
+
+ local p_cl = p_ds * (P("rg") + P("g") + P("k")) * p_ds * (P("RG") + P("G") + P("K"))
+ ----- p_cl = (p_ds * (P("rg") + P("g") + P("k") + P("RG") + P("G") + P("K")))^1
+ local p_tr = P("/Tr") * p_ds * P("gs")
+
+ local p_no_cl = (p_cl * p_nl) / ""
+ local p_no_tr = (p_tr * p_nl) / ""
+ local p_no_nl = 1 - p_nl
+
+ local p_do_cl = p_cl * p_nl
+ local p_do_tr = p_tr * p_nl
+
+ local p_do_eg = p_eg * p_nl
+
+ local pattern = Cs( (
+ (p_no_cl + p_no_tr)^0 * p_do_eg -- transparencies and colors before Q
+ + p_no_tr * p_no_cl * p_do_tr * p_do_cl -- transparencies and colors before others
+ + p_no_cl * p_do_cl -- successive colors
+ + p_no_tr * p_do_tr -- successive transparencies
+ + p_no_nl^1
+ + 1
+ )^1 )
+
+ local oldsize = 0
+ local newsize = 0
+
+ directives.register("pdf.compact", function(v)
+ compact = v and function(s)
+ oldsize = oldsize + #s
+ s = lpegmatch(pattern,s) or s
+ newsize = newsize + #s
+ return s
+ end
+ end)
+
+ statistics.register("pdf pagestream",function()
+ if oldsize ~= newsize then
+ return string.format("old size: %i, new size %i",oldsize,newsize)
+ end
+ end)
+
+
+end
+
local pushmode, popmode
local function finalize(driver,details)
@@ -1386,6 +1480,10 @@ local function finalize(driver,details)
local content = concat(buffer,"\n",1,b)
+ if compact then
+ content = compact(content)
+ end
+
local fonts = nil
local xforms = nil
@@ -1399,7 +1497,7 @@ local function finalize(driver,details)
-- messy: use real indexes for both ... so we need to change some in the
-- full luatex part
- if next(usedxforms) or next(usedximages) then
+ if next(usedxforms) or next(usedximages) or next(usedxgroups) then
xforms = pdfdictionary { }
for k in sortedhash(usedxforms) do
-- xforms[f_form(k)] = pdfreference(k)
@@ -1408,6 +1506,9 @@ local function finalize(driver,details)
for k, v in sortedhash(usedximages) do
xforms[f_image(k)] = pdfreference(v)
end
+ for k, v in sortedhash(usedxgroups) do
+ xforms[f_group(k)] = pdfreference(v)
+ end
end
reset_buffer()
@@ -1951,9 +2052,15 @@ end)
local openfile, closefile do
- local f_used = formatters["%010i 00000 n \010"]
- local f_link = formatters["%010i 00000 f \010"]
- local f_first = formatters["%010i 65535 f \010"]
+ -- I used to do <space><lf> but then figured out that when I open and save a file in a mode
+ -- that removes trailing spaces, the xref becomes invalid. The problem was then that a
+ -- reconstruction of the file by a viewer gives weird effects probably because percent symbols
+ -- gets interpreted then. Thanks to Ross Moore for noticing this side effect!
+
+ local f_used = formatters["%010i 00000 n\013\010"]
+ local f_link = formatters["%010i 00000 f\013\010"]
+ local f_first = formatters["%010i 65535 f\013\010"]
+
local f_pdf = formatters["%%PDF-%i.%i\010"]
local f_xref = formatters["xref\0100 %i\010"]
local f_trailer_id = formatters["trailer\010<< %s /ID [ <%s> <%s> ] >>\010startxref\010%i\010%%%%EOF"]
@@ -2006,7 +2113,23 @@ local openfile, closefile do
end
closefile = function(abort)
- if not abort then
+ if abort then
+ f:close()
+ f = io.open(abort,"wb")
+ if f then
+ local name = resolvers.findfile("context-lmtx-error.pdf")
+ if name then
+ local data = io.loaddata(name)
+ if data then
+ f:write(data)
+ f:close()
+ return
+ end
+ end
+ f:close()
+ removefile(abort)
+ end
+ else
local xrefoffset = offset
local lastfree = 0
local noffree = 0
@@ -2188,9 +2311,10 @@ local openfile, closefile do
flush(f,f_trailer_no(trailer(),xrefoffset))
end
end
+ f:close()
end
- f:close()
io.flush()
+ closefile = function() end
end
end
@@ -2239,8 +2363,8 @@ updaters.register("backend.update.pdf",function()
specification.index = index
local xobject = pdfdictionary { }
if not specification.notype then
- xobject.Type = pdfconstant("XObject")
- xobject.Subtype = pdfconstant("Form")
+ xobject.Type = pdf_xobject
+ xobject.Subtype = pdf_form
xobject.FormType = 1
end
local bbox = specification.bbox
@@ -2322,8 +2446,8 @@ updaters.register("backend.update.pdf",function()
local bbox = specification.bbox
local xorigin = bbox[1]
local yorigin = bbox[2]
- local xsize = specification.width -- should equal to: bbox[3] - xorigin
- local ysize = specification.height -- should equal to: bbox[4] - yorigin
+ local xsize = bbox[3] - xorigin -- we need the original ones, not the 'rotated' ones
+ local ysize = bbox[4] - yorigin -- we need the original ones, not the 'rotated' ones
local transform = specification.transform or 0
local objnum = specification.objnum or pdfreserveobj()
local groupref = nil
@@ -2448,7 +2572,6 @@ do
local texgetbox = tex.getbox
local pdfname = nil
- local tmpname = nil
local converter = nil
local useddriver = nil -- a bit of a hack
@@ -2474,13 +2597,7 @@ do
-- end
--
pdfname = file.addsuffix(tex.jobname,"pdf")
- tmpname = "l_m_t_x_" .. pdfname
- removefile(tmpname)
- if isfile(tmpname) then
- report("file %a can't be opened, aborting",tmpname)
- os.exit()
- end
- openfile(tmpname)
+ openfile(pdfname)
--
luatex.registerstopactions(1,function()
if pdfname then
@@ -2507,35 +2624,15 @@ do
local function wrapup(driver)
if pdfname then
- local ok = true
- if isfile(pdfname) then
- removefile(pdfname)
- end
- if isfile(pdfname) then
- ok = false
- file.copy(tmpname,pdfname)
- else
- renamefile(tmpname,pdfname)
- if isfile(tmpname) then
- ok = false
- end
- end
- if not ok then
- print(formatters["\nerror in renaming %a to %a\n"](tmpname,pdfname))
- end
+ closefile()
pdfname = nil
- tmpname = nil
end
end
local function cleanup(driver)
- if tmpname then
- closefile(true)
- if isfile(tmpname) then
- removefile(tmpname)
- end
+ if pdfname then
+ closefile(pdfname)
pdfname = nil
- tmpname = nil
end
end
diff --git a/tex/context/base/mkiv/lpdf-pde.lua b/tex/context/base/mkiv/lpdf-pde.lua
index b159df24f..2a8cfeede 100644
--- a/tex/context/base/mkiv/lpdf-pde.lua
+++ b/tex/context/base/mkiv/lpdf-pde.lua
@@ -1035,7 +1035,7 @@ if images then do
local root = pdfdoc.Catalog
local page = pdfdoc.pages[pagenumber]
if page then
- local sizetag = sizes[size or "crop"] or sizes.cro
+ local sizetag = sizes[size or "crop"] or sizes.crop
local mediabox = page.MediaBox or { 0, 0, 0, 0 }
local cropbox = page[sizetag] or mediabox
return {
diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua
index 0a2fe679e..d99e09243 100644
--- a/tex/context/base/mkiv/lpdf-tag.lua
+++ b/tex/context/base/mkiv/lpdf-tag.lua
@@ -6,11 +6,11 @@ if not modules then modules = { } end modules ['lpdf-tag'] = {
license = "see context related readme files"
}
-local next = next
-local format, match, concat = string.format, string.match, table.concat
+local next, type = next, type
+local format, match, gmatch = string.format, string.match, string.gmatch
+local concat, sortedhash = table.concat, table.sortedhash
local lpegmatch, P, S, C = lpeg.match, lpeg.P, lpeg.S, lpeg.C
local settings_to_hash = utilities.parsers.settings_to_hash
-local sortedhash = table.sortedhash
local formatters = string.formatters
local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
@@ -36,6 +36,7 @@ local pdfunicode = lpdf.unicode
local pdfflushobject = lpdf.flushobject
local pdfreserveobject = lpdf.reserveobject
local pdfpagereference = lpdf.pagereference
+local pdfmakenametree = lpdf.makenametree
local addtocatalog = lpdf.addtocatalog
local addtopageattributes = lpdf.addtopageattributes
@@ -62,6 +63,7 @@ local getattr = nuts.getattr
local getprev = nuts.getprev
local getnext = nuts.getnext
local getlist = nuts.getlist
+local getchar = nuts.getchar
local setlink = nuts.setlink
local setlist = nuts.setlist
@@ -75,7 +77,7 @@ local structure_kids -- delayed
local structure_ref -- delayed
local parent_ref -- delayed
local root -- delayed
-local names -- delayed
+local names = { }
local tree = { }
local elements = { }
@@ -90,29 +92,49 @@ local usedmapping = { }
----- tagsplitter = structurestags.patterns.splitter
--- local embeddedtags = false -- true will id all, for tracing
--- local f_tagid = formatters["%s-%04i"]
--- local embeddedfilelist = pdfarray() -- /AF crap
---
--- directives.register("structures.tags.embedmath",function(v)
--- if not v then
--- -- only enable
--- elseif embeddedtags == true then
--- -- already all tagged
--- elseif embeddedtags then
--- embeddedtags.math = true
--- else
--- embeddedtags = { math = true }
--- end
--- end)
+local embeddedtags = false -- true will id all, for tracing, otherwise table
+local f_tagid = formatters["%s-%04i"]
+local embeddedfilelist = pdfarray() -- /AF crap
--- function codeinjections.maptag(original,target,kind)
--- mapping[original] = { target, kind or "inline" }
--- end
+-- for testing, not that it was ever used:
+
+directives.register("structures.tags.embed",function(v)
+ if type(v) == "string" then
+ if type(embeddedtags) ~= "table" then
+ embeddedtags = { }
+ end
+ for s in gmatch(v,"([^, ]+)") do
+ embeddedtags[s] = true
+ end
+ elseif v and not embeddedtags then
+ embeddedtags = true
+ end
+end)
+
+-- for old times sake, not that it was ever used:
+
+directives.register("structures.tags.embedmath",function(v)
+ if not v then
+ -- only enable
+ elseif embeddedtags == true then
+ -- already all tagged
+ elseif embeddedtags then
+ embeddedtags.math = true
+ else
+ embeddedtags = { math = true }
+ end
+end)
+
+function codeinjections.maptag(original,target,kind)
+ mapping[original] = { target, kind or "inline" }
+end
+
+-- mostly the same as the annotations tree
local function finishstructure()
if root and #structure_kids > 0 then
- local nums, n = pdfarray(), 0
+ local nums = pdfarray()
+ local n = 0
for i=1,#tree do
n = n + 1 ; nums[n] = i - 1
n = n + 1 ; nums[n] = pdfreference(pdfflushobject(tree[i]))
@@ -120,17 +142,7 @@ local function finishstructure()
local parenttree = pdfdictionary {
Nums = nums
}
- -- we need to split names into smaller parts (e.g. alphabetic or so)
- -- we already have code for that somewhere
- if #names > 0 then
- local kids = pdfdictionary {
- Limits = pdfarray { names[1], names[#names-1] },
- Names = names,
- }
- local idtree = pdfdictionary {
- Kids = pdfarray { pdfreference(pdfflushobject(kids)) },
- }
- end
+ local idtree = pdfmakenametree(names)
--
local rolemap = pdfdictionary()
for k, v in next, usedmapping do
@@ -142,7 +154,7 @@ local function finishstructure()
Type = pdfconstant("StructTreeRoot"),
K = pdfreference(pdfflushobject(structure_kids)),
ParentTree = pdfreference(pdfflushobject(parent_ref,parenttree)),
- IDTree = #names > 0 and pdfreference(pdfflushobject(idtree)) or nil,
+ IDTree = idtree,
RoleMap = rolemap, -- sorted ?
}
pdfflushobject(structure_ref,structuretree)
@@ -191,6 +203,9 @@ end
local pdf_userproperties = pdfconstant("UserProperties")
+-- /O /Table
+-- /Headers [ ]
+
local function makeattribute(t)
if t and next(t) then
local properties = pdfarray()
@@ -209,40 +224,65 @@ end
local function makeelement(fulltag,parent)
local specification = specifications[fulltag]
- local tag = specification.tagname
- if tag == "ignore" then
+ local tagname = specification.tagname
+ local tagnameused = tagname
+ local attributes = nil
+ if tagname == "ignore" then
return false
- elseif tag == "mstackertop" or tag == "mstackerbot" or tag == "mstackermid"then
+ elseif tagname == "mstackertop" or tagname == "mstackerbot" or tagname == "mstackermid"then
-- TODO
return true
+ elseif tagname == "tabulatecell" then
+ local d = structurestags.gettabulatecell(fulltag)
+ if d and d.kind == 1 then
+ tagnameused = "tabulateheadcell"
+ end
+ elseif tagname == "tablecell" then
+ -- will become a plugin model
+ local d = structurestags.gettablecell(fulltag)
+ if d then
+ if d.kind == 1 then
+ tagnameused = "tableheadcell"
+ end
+ local rows = d.rows or 1
+ local cols = d.columns or 1
+ if rows > 1 or cols > 1 then
+ attributes = pdfdictionary {
+ O = pdfconstant("Table"),
+ RowSpan = rows > 1 and rows or nil,
+ ColSpan = cols > 1 and cols or nil,
+ }
+ end
+
+ end
end
--
local detail = specification.detail
local userdata = specification.userdata
--
- usedmapping[tag] = true
+ usedmapping[tagname] = true
--
-- specification.attribute is unique
--
local id = nil
- -- local af = nil
- -- if embeddedtags then
- -- local tagname = specification.tagname
- -- local tagindex = specification.tagindex
- -- if embeddedtags == true or embeddedtags[tagname] then
- -- id = f_tagid(tagname,tagindex)
- -- af = job.fileobjreferences.collected[id]
- -- if af then
- -- local r = pdfreference(af)
- -- af = pdfarray { r }
- -- -- embeddedfilelist[#embeddedfilelist+1] = r
- -- end
- -- end
- -- end
+ local af = nil
+ if embeddedtags then
+ local tagindex = specification.tagindex
+ if embeddedtags == true or embeddedtags[tagname] then
+ id = f_tagid(tagname,tagindex)
+ af = job.fileobjreferences.collected[id]
+ if af then
+ local r = pdfreference(af)
+ af = pdfarray { r }
+ -- embeddedfilelist[#embeddedfilelist+1] = r
+ end
+ end
+ end
--
local k = pdfarray()
local r = pdfreserveobject()
- local t = usedlabels[tag] or tag
+ local t = usedlabels[tagnameused] or tagnameused
+ -- local a = nil
local d = pdfdictionary {
Type = pdf_struct_element,
S = pdfconstant(t),
@@ -251,16 +291,15 @@ local function makeelement(fulltag,parent)
P = parent.pref,
Pg = pageref,
K = pdfreference(r),
- A = a and makeattribute(a) or nil,
+ -- A = a and makeattribute(a) or nil,
+ A = attributes,
-- Alt = " Who cares ",
-- ActualText = " Hi Hans ",
AF = af,
}
local s = pdfreference(pdfflushobject(d))
if id and names then
- local size = #names
- names[size+1] = id
- names[size+2] = s
+ names[id] = s
end
local kids = parent.kids
kids[#kids+1] = s
@@ -336,11 +375,11 @@ function nodeinjections.addtags(head)
root = { pref = pdfreference(structure_ref), kids = structure_kids }
names = pdfarray()
end
-
local function collectranges(head,list)
for n, id in nextnode, head do
if id == glyph_code then
-- maybe also disc
+if getchar(n) ~= 0 then
local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
-- if not at then
-- range = nil
@@ -352,6 +391,7 @@ function nodeinjections.addtags(head)
elseif range then
range[4] = n -- stop
end
+end
elseif id == hlist_code or id == vlist_code then
local at = getattr(n,a_image)
if at then
diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua
index 8f7f19e84..96dc626f7 100644
--- a/tex/context/base/mkiv/lxml-css.lua
+++ b/tex/context/base/mkiv/lxml-css.lua
@@ -146,52 +146,116 @@ if context then
end
-local p_digit = lpeg.patterns.digit
-
-local pattern = Cf( Ct("") * (
- Cg(
- Cc("style") * (
- C("italic")
- + C("oblique")
- + C("slanted") / "oblique"
- )
- + Cc("variant") * (
- (C("smallcaps") + C("caps")) / "small-caps"
- )
- + Cc("weight") * (
- C("bold")
- )
- + Cc("family") * (
- (C("mono") + C("type")) / "monospace" -- just ignore the "space(d)"
- + (C("sansserif") + C("sans")) / "sans-serif" -- match before serif
- + C("serif")
- )
- + Cc("size") * Ct (
- (S("+-")^0 * (p_digit^0 * P(".") * p_digit^1 + p_digit^1 * P(".") + p_digit^1)) / tonumber
- * C(P("p") * S("txc") + P("e") * S("xm") + S("mc") * P("m") + P("in") + P("%"))
+
+do
+
+ local p_digit = lpegpatterns.digit
+ local p_unquoted = Cs(lpegpatterns.unquoted)
+ local p_size = (S("+-")^0 * (p_digit^0 * P(".") * p_digit^1 + p_digit^1 * P(".") + p_digit^1)) / tonumber
+ * C(P("p") * S("txc") + P("e") * S("xm") + S("mc") * P("m") + P("in") + P("%"))
+
+ local pattern = Cf( Ct("") * (
+ Cg(
+ Cc("style") * (
+ C("italic")
+ + C("oblique")
+ + C("slanted") / "oblique"
+ )
+ + Cc("variant") * (
+ (C("smallcaps") + C("caps")) / "small-caps"
+ )
+ + Cc("weight") * (
+ C("bold")
+ )
+ + Cc("family") * (
+ (C("mono") + C("type")) / "monospace" -- just ignore the "space(d)"
+ + (C("sansserif") + C("sans")) / "sans-serif" -- match before serif
+ + C("serif")
+ )
+ + Cc("size") * Ct(p_size)
)
- )
---+ P("\\") * (
--- P("bf") * ( Cg ( Cc("weight") * Cc("bold") ) )
--- + P("bi") * ( Cg ( Cc("weight") * Cc("bold") )
--- * Cg ( Cc("style") * Cc("italic") ) )
--- + P("bs") * ( Cg ( Cc("weight") * Cc("bold") )
--- * Cg ( Cc("style") * Cc("oblique") ) )
--- + P("it") * ( Cg ( Cc("style") * Cc("italic") ) )
--- + P("sl") * ( Cg ( Cc("style") * Cc("oblique") ) )
--- + P("sc") * ( Cg ( Cc("variant") * Cc("small-caps") ) )
--- + P("tt") * ( Cg ( Cc("family") * Cc("monospace") ) )
---)
- + P(1)
-)^0 , rawset)
-
-function css.fontspecification(str)
- return str and lpegmatch(pattern,lower(str))
-end
+ + P(1)
+ )^0 , rawset)
+
+ function css.fontspecification(str)
+ return str and lpegmatch(pattern,lower(str))
+ end
+
+ -- These map onto context!
+
+ function css.style(str)
+ if str and str ~= "" then
+ str = lower(str)
+ if str == "italic" then
+ return "italic"
+ elseif str == "slanted" or str == "oblique" then
+ return "slanted"
+ end
+ end
+ return "normal"
+ end
+
+ function css.variant(str) -- will change to a feature
+ if str and str ~= "" then
+ str = lower(str)
+ if str == "small-caps" or str == "caps" or str == "smallcaps" then
+ return "caps"
+ end
+ end
+ return "normal"
+ end
+
+ function css.weight(str)
+ if str and str ~= "" then
+ str = lower(str)
+ if str == "bold" then
+ return "bold"
+ end
+ end
+ return "normal"
+ end
+
+ function css.family(str)
+ if str and str ~= "" then
+ str = lower(str)
+ if str == "mono" or str == "type" or str == "monospace" then
+ return "mono"
+ elseif str == "sansserif" or str == "sans" then
+ return "sans"
+ elseif str == "serif" then
+ return "serif"
+ else
+ -- what if multiple ...
+ return lpegmatch(p_unquoted,str) or str
+ end
+ end
+ end
+
+ function css.size(str,factors)
+ local size, unit
+ if type(str) == "table" then
+ size, unit = str[1], str[2]
+ elseif str and str ~= "" then
+ size, unit = lpegmatch(p_size,lower(str))
+ end
+ if size and unit then
+ if factors then
+ return (factors[unit] or 1) * size
+ else
+ return size, unit
+ end
+ end
+ end
+
+ function css.colorspecification(str)
+ if str and str ~= "" then
+ local c = attributes.colors.values[tonumber(str)]
+ if c then
+ return format("rgb(%s%%,%s%%,%s%%)",c[3]*100,c[4]*100,c[5]*100)
+ end
+ end
+ end
-function css.colorspecification(str)
- local c = str and attributes.colors.values[tonumber(str)]
- return c and format("rgb(%s%%,%s%%,%s%%)",c[3]*100,c[4]*100,c[5]*100)
end
-- The following might be handy. It hooks into the normal parser as <selector>
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index 7a8419702..0af9a2121 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -319,7 +319,7 @@ function mathematics.define(family)
if mathclass then
local name = character.mathname
if name then
- report_math("fatal error, conlicting mathclass and mathspec for %C",unicode)
+ report_math("fatal error, conflicting mathclass and mathspec for %C",unicode)
os.exit()
else
local class = classes[mathclass] or mathclass -- no real checks needed
diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv
index 7259fca3f..c9018ba50 100644
--- a/tex/context/base/mkiv/math-ini.mkiv
+++ b/tex/context/base/mkiv/math-ini.mkiv
@@ -129,6 +129,11 @@
\mathflattenmode 31
+\ifdefined\mathlimitsmode
+ % ignore \limits and \nolimts when no scripts (better spacing)
+ \mathlimitsmode\plusone
+\fi
+
\appendtoks
\attribute\mathmodeattribute\plusone
\to \everydisplay
diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi
index 92325d0af..cc3625eb4 100644
--- a/tex/context/base/mkiv/math-stc.mkvi
+++ b/tex/context/base/mkiv/math-stc.mkvi
@@ -86,11 +86,19 @@
\def\math_stackers_regular
{\mathstylehbox{\usemathstackerscolorparameter\c!color
- \Umathaccent\fam\zerocount\scratchunicode{\hskip\scratchwidth}}}
+ \hskip\d_math_stackers_offset_l
+ \Umathaccent\fam\zerocount\scratchunicode
+ {\hskip\dimexpr\scratchwidth-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
+ \hskip\d_math_stackers_offset_r
+ }}
\def\math_stackers_stretch % we don't have that one yet
{\mathstylehbox{\usemathstackerscolorparameter\c!color
- \Umathaccent\fam\zerocount\scratchunicode{\hskip\hsize}}}
+ \hskip\d_math_stackers_offset_l
+ \Umathaccent\fam\zerocount\scratchunicode
+ {\hskip\dimexpr\hsize-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
+ \hskip\d_math_stackers_offset_r
+ }}
% these delimiters are a unuseable as they don't center for small arguments:
%
@@ -499,7 +507,7 @@
\dostoptagged
\mathstackersparameter\c!right\relax
\endgroup}
- %\math_stackers_start_group}
+ %\math_stackers_stop_group}
\unexpanded\def\definemathextensible
{\dotripleempty\math_stackers_define_normal}
@@ -572,8 +580,27 @@
\let\math_stackers_stop_group\endgroup
\fi}
-\unexpanded\def\math_stackers_make_double#top#bottom#category#codepoint#codeextra#text%
+\newconstant\c_math_stackers_top
+\newconstant\c_math_stackers_bottom
+\newconstant\c_math_stackers_codepoint
+\newconstant\c_math_stackers_extracode
+\newdimen \d_math_stackers_offset_l
+\newdimen \d_math_stackers_offset_r
+
+\setupmathstackers[lt=\zeropoint,rt=\zeropoint,lb=\zeropoint,rb=\zeropoint]
+
+\unexpanded\def\math_stackers_make_double#top#bottom#category#codepoint#codeextra%
{\math_stackers_start_group{#category}%
+ \c_math_stackers_top #top\relax
+ \c_math_stackers_bottom #bottom\relax
+ \c_math_stackers_codepoint#codepoint\relax
+ \c_math_stackers_extracode#codeextra\relax
+ \dosingleempty\math_stackers_make_double_indeed}
+
+\unexpanded\def\math_stackers_make_double_indeed[#settings]#text%
+ {\iffirstargument
+ \setupcurrentmathstackers[#settings]%
+ \fi
\mathstackersparameter\c!left\relax
\dostarttagged\t!mathstacker\currentmathstackers
\ifmmode\math_class_by_parameter\mathstackersparameter\else\dontleavehmode\fi
@@ -587,7 +614,7 @@
\scratchleftoffset \zeropoint
\scratchrightoffset\zeropoint
%
- \math_stackers_check_unicode{#codepoint}%
+ \math_stackers_check_unicode\c_math_stackers_codepoint
%
\ifx\math_stackers_middle\empty
\setbox\scratchboxthree\emptyhbox
@@ -602,24 +629,37 @@
\fi
\advance\scratchwidth2\scratchhoffset
%
+ %\scratchunicode\c_math_stackers_codepoint
+ \ifcase\c_math_stackers_bottom
+ \d_math_stackers_offset_l\mathstackersparameter{lt}%
+ \d_math_stackers_offset_r\mathstackersparameter{rt}%
+ \else\ifcase\c_math_stackers_top
+ \d_math_stackers_offset_l\mathstackersparameter{lb}%
+ \d_math_stackers_offset_r\mathstackersparameter{rb}%
+ \else
+ \d_math_stackers_offset_l\mathstackersparameter{lt}%
+ \d_math_stackers_offset_r\mathstackersparameter{rt}%
+ \fi\fi
\setbox\scratchboxtwo\csname\??mathstackersalternative\p_alternative\endcsname
\setbox\scratchboxthree\hpack to \scratchwidth{\hss\box\scratchboxthree\hss}%
%
- \scratchunicode#codeextra\relax
- \ifcase\scratchunicode\else
+ \ifcase\c_math_stackers_extracode\else
+ \scratchunicode\c_math_stackers_extracode
+ \d_math_stackers_offset_l\mathstackersparameter{lb}%
+ \d_math_stackers_offset_r\mathstackersparameter{rb}%
\setbox\scratchboxone\csname\??mathstackersalternative\p_alternative\endcsname
\fi
%
\math_stackers_normalize_three
% analysis
- \ifcase#bottom\relax
- \ifcase#top\relax
+ \ifcase\c_math_stackers_bottom
+ \ifcase\c_math_stackers_top
\dosettagproperty\s!subtype\t!munderover
\else
\dosettagproperty\s!subtype\t!mover
\fi
\else
- \ifcase#top\relax
+ \ifcase\c_math_stackers_top
\dosettagproperty\s!subtype\t!munder
\else
% brrr
@@ -633,7 +673,7 @@
\math_stackers_stop_tagged
%
\ifdim\htdp\scratchboxtwo>\zeropoint
- \ifcase#bottom\else
+ \ifcase\c_math_stackers_bottom\else
\kern-\scratchwidth
% under
\math_stackers_start_tagged_bot
@@ -643,7 +683,7 @@
+\ht\scratchboxtwo
+\mathstackersparameter\c!distance % was \c!voffset
\relax
- \ifcase#top\relax
+ \ifcase\c_math_stackers_top
\box\scratchboxtwo
\else
\box\scratchboxone
@@ -651,7 +691,7 @@
\egroup
\math_stackers_stop_tagged
\fi
- \ifcase#top\else
+ \ifcase\c_math_stackers_top\else
\kern-\scratchwidth
% over
\math_stackers_start_tagged_top
@@ -665,7 +705,6 @@
\egroup
\math_stackers_stop_tagged
\fi
- %
\fi}%
\dostoptagged
\mathstackersparameter\c!right\relax
@@ -696,10 +735,6 @@
\setuevalue{#1}{\math_stackers_make_double\plusone \plusone\noexpand\currentmathstackers{\number#2}{\number#3}}%
\fi}
-\unexpanded\def\mathover {\begingroup\dosingleempty\math_stackers_handle_over }
-\unexpanded\def\mathunder {\begingroup\dosingleempty\math_stackers_handle_under }
-\unexpanded\def\mathdouble{\begingroup\dodoubleempty\math_stackers_handle_double}
-
\unexpanded\def\definemathover {\dotripleargument \math_stackers_define_over }
\unexpanded\def\definemathunder {\dotripleargument \math_stackers_define_under }
\unexpanded\def\definemathdouble{\doquadrupleargument\math_stackers_define_double}
@@ -713,29 +748,41 @@
\def\math_stackers_define_double[#category][#command][#topcode][#bottomcode]%
{\setuvalue{#command}{\math_stackers_handle_direct\plusone\plusone{#category}{#topcode}{#bottomcode}}}
-\unexpanded\def\mathover {\begingroup\dosingleempty\math_stackers_handle_over }
-\unexpanded\def\mathunder {\begingroup\dosingleempty\math_stackers_handle_under }
-\unexpanded\def\mathdouble{\begingroup\dosingleempty\math_stackers_handle_double}
+\unexpanded\def\mathover {\begingroup\dodoubleempty\math_stackers_handle_over }
+\unexpanded\def\mathunder {\begingroup\dodoubleempty\math_stackers_handle_under }
+\unexpanded\def\mathdouble{\begingroup\dodoubleempty\math_stackers_handle_double}
-\def\math_stackers_handle_over[#category]#topcode#text%
- {\math_stackers_make_double\plusone\zerocount
- {\iffirstargument#category\else\v!top\fi}%
+\def\math_stackers_handle_over[#category][#settings]#topcode#text%
+ {\edef\currentmathstackers{\iffirstargument#category\else\v!top\fi}%
+ \ifsecondargument
+ \setupcurrentmathstackers[#settings]%
+ \fi
+ \math_stackers_make_double\plusone\zerocount
+ {\currentmathstackers}%
{#topcode}%
{0}%
{#text}%
\endgroup}
-\def\math_stackers_handle_under[#category]#bottomcode#text%
- {\math_stackers_make_double\zerocount\plusone
- {\iffirstargument#category\else\v!bottom\fi}%
+\def\math_stackers_handle_under[#category][#settings]#bottomcode#text%
+ {\edef\currentmathstackers{\iffirstargument#category\else\v!bottom\fi}%
+ \ifsecondargument
+ \setupcurrentmathstackers[#settings]%
+ \fi
+ \math_stackers_make_double\zerocount\plusone
+ {\currentmathstackers}%
{#bottomcode}%
{0}%
{#text}%
\endgroup}
-\def\math_stackers_handle_double[#category]#topcode#bottomcode#text%
- {\math_stackers_make_double\plusone\plusone
- {\iffirstargument#category\else\v!both\fi}%
+\def\math_stackers_handle_double[#category][#settings]#topcode#bottomcode#text%
+ {\edef\currentmathstackers{\iffirstargument#category\else\v!both\fi}%
+ \ifsecondargument
+ \setupcurrentmathstackers[#settings]%
+ \fi
+ \math_stackers_make_double\plusone\plusone
+ {\currentmathstackers}%
{#topcode}%
{#bottomcode}%
{#text}%
diff --git a/tex/context/base/mkiv/meta-tex.mkiv b/tex/context/base/mkiv/meta-tex.mkiv
index 03ad5ee39..418ddc196 100644
--- a/tex/context/base/mkiv/meta-tex.mkiv
+++ b/tex/context/base/mkiv/meta-tex.mkiv
@@ -153,4 +153,87 @@
\clf_MPLIBconvertoutlinetext\numexpr#1\relax{#2}\scratchbox
\endgroup}
+%D For now here. We don't do the whole thing, because then one can as
+%D well just export to pdf. We assume consistent integration.
+
+\definefontsynonym[serif-normal-normal] [\s!Serif]
+\definefontsynonym[serif-normal-italic] [\s!SerifItalic]
+\definefontsynonym[serif-normal-oblique][\s!SerifSlanted]
+\definefontsynonym[serif-bold-normal] [\s!SerifBold]
+\definefontsynonym[serif-bold-italic] [\s!SerifBoldItalic]
+\definefontsynonym[serif-bold-oblique] [\s!SerifBoldSlanted]
+
+\definefontsynonym[sans-normal-normal] [\s!Sans]
+\definefontsynonym[sans-normal-italic] [\s!SansItalic]
+\definefontsynonym[sans-normal-oblique] [\s!SansSlanted]
+\definefontsynonym[sans-bold-normal] [\s!SansBold]
+\definefontsynonym[sans-bold-italic] [\s!SansBoldItalic]
+\definefontsynonym[sans-bold-oblique] [\s!SansBoldSlanted]
+
+\definefontsynonym[mono-normal-normal] [\s!Mono]
+\definefontsynonym[mono-normal-italic] [\s!MonoItalic]
+\definefontsynonym[mono-normal-oblique] [\s!MonoSlanted]
+\definefontsynonym[mono-bold-normal] [\s!MonoBold]
+\definefontsynonym[mono-bold-italic] [\s!MonoBoldItalic]
+\definefontsynonym[mono-bold-oblique] [\s!MonoBoldSlanted]
+
+\installcorenamespace {svgfamily}
+
+\setvalue{\??svgfamily }{serif}
+\setvalue{\??svgfamily serif}{serif}
+\setvalue{\??svgfamily sans}{sans}
+\setvalue{\??svgfamily mono}{mono}
+
+%D This can't change because otherwise \type {\scale[width=4cm]{graphic}} fails.
+
+\unexpanded\def\svgscaled#1%
+ {\fastsxsy{#1}{#1}\svgnormal}
+
+\unexpanded\def\svgnormal#1#2#3#4% family weight style text
+ {\bgroup
+ \edef\p_family{#1}%
+ \ifx\p_family\empty\else
+ \edef\p_font{\ifcsname\??svgfamily#1\endcsname\lastnamedcs\else#1\fi-#2-#3}%
+ \predefinedfont[\s!spec:\p_font*\s!default\space @ 10bp]%
+ \fi
+ #4%
+ \egroup}
+
+\unexpanded\def\svgcolored#1#2#3#4% r g b text
+ {\colored[r=#1,g=#2,b=#3]{#4}}
+
+\unexpanded\def\svgplaced#1#2#3#4% dx dy width text
+ {\doifelsenothing{#3}%
+ {\hpack}%
+ {\hpack to #3}%
+ {\raise#2\onebasepoint\hbox{\kern#1\onebasepoint\relax#4}}}
+
+\newdimen\grph_svg_scratchwidth % maybe \startsvgpos etc
+
+\unexpanded\def\svgposchar#1#2#3% dx dy char
+ {\setbox\scratchbox\hpack\bgroup
+ \raise#2\onebasepoint\hbox\bgroup
+ \kern\dimexpr#1\onebasepoint-\grph_svg_scratchwidth\relax
+ \char#3\relax
+ \egroup
+ \egroup
+ \advance\grph_svg_scratchwidth\wd\scratchbox
+ \box\scratchbox}
+
+\unexpanded\def\svgchar#1% char
+ {\char#1\relax}
+
+\definelayer[svgmps][\c!method=\v!fit]
+
+\unexpanded\def\svgstartlayer
+ {\resetlayer[svgmps]%
+ \setlayer[svgmps]\bgroup}
+
+\unexpanded\def\svgstoplayer
+ {\egroup
+ \flushlayer[svgmps]}
+
+\unexpanded\def\svgsetlayer#1#2%
+ {\setlayer[svgmps][\c!x=#1\onebasepoint,\c!y=#2\onebasepoint]} % {#3}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/mlib-cnt.lua b/tex/context/base/mkiv/mlib-cnt.lua
index 16625befb..adcaf9f94 100644
--- a/tex/context/base/mkiv/mlib-cnt.lua
+++ b/tex/context/base/mkiv/mlib-cnt.lua
@@ -313,12 +313,12 @@ function mp.lmt_contours_start()
for i=1,nofvalues do
colors[i] = { fcolor(i) }
end
-if attributes.colors.model == "cmyk" then
- for i=1,#colors do
- local c = colors[i]
- colors[i] = { 1 - c[1], 1 - c[2], 1 - c[3], 0 }
- end
-end
+ if attributes.colors.model == "cmyk" then
+ for i=1,#colors do
+ local c = colors[i]
+ colors[i] = { 1 - c[1], 1 - c[2], 1 - c[3], 0 }
+ end
+ end
return colors, fcolor
end
end
diff --git a/tex/context/base/mkiv/mlib-lmp.lua b/tex/context/base/mkiv/mlib-lmp.lua
index e72ddd03c..402c194fe 100644
--- a/tex/context/base/mkiv/mlib-lmp.lua
+++ b/tex/context/base/mkiv/mlib-lmp.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['mlib-lmp'] = {
license = "see context related readme files",
}
+local type = type
+
local aux = mp.aux
local mpnumeric = aux.numeric
local mppair = aux.pair
@@ -136,23 +138,64 @@ do
end
-function mp.lmt_svg_include()
- local filename = metapost.getparameter { "filename" }
- local fontname = metapost.getparameter { "fontname" }
- local metacode = nil
- if fontname and fontname ~= "" then
- local unicode = metapost.getparameter { "unicode" }
- if unicode then
- metacode = metapost.svgglyphtomp(fontname,math.round(unicode))
+if CONTEXTLMTXMODE > 0 then
+
+ function mp.lmt_svg_include()
+ local labelfile = metapost.getparameter { "labelfile" }
+ if labelfile then
+ local labels = table.load(labelfile) -- todo: same path as svg file
+ if type(labels) == "table" then
+ for i=1,#labels do
+ metapost.remaptext(labels[i])
+ end
+ end
+ end
+ local fontname = metapost.getparameter { "fontname" }
+ if fontname and fontname ~= "" then
+ local unicode = metapost.getparameter { "unicode" }
+ if unicode then
+ mpdirect (
+ metapost.svgglyphtomp(fontname,math.round(unicode))
+ )
+ end
+ return
+ end
+ local filename = metapost.getparameter { "filename" }
+ if filename and filename ~= "" then
+ mpdirect ( metapost.svgtomp {
+ data = io.loaddata(filename),
+ remap = true,
+ } )
+ return
+ end
+ local buffer = metapost.getparameter { "buffer" }
+ if buffer then
+ mpdirect ( metapost.svgtomp {
+ data = buffers.getcontent(buffer),
+ -- remap = true,
+ } )
+ return
+ end
+ local code = metapost.getparameter { "code" }
+ if code then
+ mpdirect ( metapost.svgtomp {
+ data = code,
+ } )
+ return
end
- elseif filename and filename ~= "" then
- metacode = metapost.svgtomp {
- data = io.loaddata(filename)
- }
end
- if metacode then
- mpdirect(metacode)
+
+end
+
+if CONTEXTLMTXMODE > 0 then
+
+ function mp.lmt_do_remaptext()
+ local parameters = metapost.scanparameters()
+ if parameters and parameters.label then
+ metapost.remaptext(parameters)
+ end
end
+
end
if CONTEXTLMTXMODE > 0 then
diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua
index ece332d84..4f183eed3 100644
--- a/tex/context/base/mkiv/mlib-pdf.lua
+++ b/tex/context/base/mkiv/mlib-pdf.lua
@@ -274,6 +274,34 @@ local function flushconcatpath(path, t, open)
return t
end
+local function toboundingbox(path)
+ local size = #path
+ if size == 4 then
+ local pth = path[1]
+ local x = pth.x_coord
+ local y = pth.y_coord
+ local llx, lly, urx, ury = x, y, x, y
+ for i=2,size do
+ pth = path[i]
+ x = pth.x_coord
+ y = pth.y_coord
+ if x < llx then
+ llx = x
+ elseif x > urx then
+ urx = x
+ end
+ if y < lly then
+ lly = y
+ elseif y > ury then
+ ury = y
+ end
+ end
+ return { llx, lly, urx, ury }
+ else
+ return { 0, 0, 0, 0 }
+ end
+end
+
metapost.flushnormalpath = flushnormalpath
-- The flusher is pdf based, if another backend is used, we need to overload the
@@ -283,8 +311,10 @@ metapost.flushnormalpath = flushnormalpath
-- We can avoid the before table but I like symmetry. There is of course a small
-- performance penalty, but so is passing extra arguments (result, flusher, after)
-- and returning stuff.
+--
+-- This variable stuff will change in lmtx.
-local ignore = function () end
+local ignore = function() end
local space = P(" ")
local equal = P("=")
@@ -380,10 +410,10 @@ function metapost.flush(specification,result)
local figures = result.fig
if figures then
flusher = flusher or pdfflusher
- local resetplugins = metapost.resetplugins or ignore -- before figure
- local processplugins = metapost.processplugins or ignore -- each object
+ local resetplugins = metapost.resetplugins or ignore -- before figure
+ local processplugins = metapost.processplugins or ignore -- each object
local synchronizeplugins = metapost.synchronizeplugins or ignore
- local pluginactions = metapost.pluginactions or ignore -- before / after
+ local pluginactions = metapost.pluginactions or ignore -- before / after
local startfigure = flusher.startfigure
local stopfigure = flusher.stopfigure
local flushfigure = flusher.flushfigure
@@ -413,6 +443,8 @@ function metapost.flush(specification,result)
-- we need to be indirect if we want the one-pass solution
+ local groupstack = { }
+
local function processfigure()
result[#result+1] = "q"
if objects then
@@ -444,6 +476,35 @@ function metapost.flush(specification,result)
miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false
elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then
-- skip
+ elseif objecttype == "start_group" then
+ if lpdf.flushgroup then
+ local before, after = processplugins(object)
+ if before then
+ result[#result+1] = "q"
+ result = pluginactions(before,result,flushfigure)
+ insert(groupstack, {
+ after = after,
+ result = result,
+ bbox = toboundingbox(object.path),
+ })
+ result = { }
+miterlimit, linecap, linejoin, dashed, linewidth = -1, -1, -1, "", false
+ else
+ insert(groupstack,false)
+ end
+ else
+ insert(groupstack,false)
+ end
+ elseif objecttype == "stop_group" then
+ local data = remove(groupstack)
+ if data then
+ local id = lpdf.flushgroup(concat(result,"\r"),data.bbox)
+ result = data.result
+ result[#result+1] = formatters["/%s Do"](id)
+ result = pluginactions(data.after,result,flushfigure)
+ result[#result+1] = "Q"
+miterlimit, linecap, linejoin, dashed, linewidth = -1, -1, -1, "", false
+ end
else
-- we use an indirect table as we want to overload
-- entries but this is not possible in userdata
@@ -451,7 +512,7 @@ function metapost.flush(specification,result)
-- can be optimized if no path
--
local original = object
- local object = { }
+ local object = { }
setmetatable(object, {
__index = original
})
diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua
index 46d436466..5098eb76d 100644
--- a/tex/context/base/mkiv/mlib-pps.lua
+++ b/tex/context/base/mkiv/mlib-pps.lua
@@ -30,6 +30,8 @@ local flush_list = node.flush_list
local setmetatableindex = table.setmetatableindex
local sortedhash = table.sortedhash
+local new_hlist = nodes.pool.hlist
+
local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
@@ -258,6 +260,9 @@ local function startjob(plugmode,kind,mpx)
top = {
textexts = { }, -- all boxes, optionally with a different color
texstrings = { },
+ mapstrings = { },
+ mapindices = { },
+ mapmoves = { },
texlast = 0,
texdata = setmetatableindex({},preset), -- references to textexts in order or usage
plugmode = plugmode, -- some day we can then skip all pre/postscripts
@@ -720,7 +725,7 @@ function metapost.processplugins(object) -- each object (second pass)
if prescript and #prescript > 0 then
local before = { }
local after = { }
- processoractions.runner(object,splitprescript(prescript) or {},before,after)
+ processoractions.runner(object,splitprescript(prescript) or { },before,after)
return #before > 0 and before, #after > 0 and after
else
local c = object.color
@@ -870,6 +875,92 @@ local tx_reset, tx_process do
mp.mf_some_text(index,madetext)
end
+ -- a label can be anything, also something mp doesn't like in strings
+ -- so we return an index instead
+
+ function metapost.processing()
+ return top and true or false
+ end
+
+ function metapost.remaptext(replacement)
+ if top then
+ local mapstrings = top.mapstrings
+ local mapindices = top.mapindices
+ local label = replacement.label
+ local index = 0
+ if label then
+ local found = mapstrings[label]
+ if found then
+ setmetatableindex(found,replacement)
+ index = found.index
+ else
+ index = #mapindices + 1
+ replacement.index = index
+ mapindices[index] = replacement
+ mapstrings[label] = replacement
+ end
+ end
+ return index
+ else
+ return 0
+ end
+ end
+
+ function metapost.remappedtext(what)
+ return top and (top.mapstrings[what] or top.mapindices[tonumber(what)])
+ end
+
+ function mp.mf_map_move(index)
+ mp.triplet(top.mapmoves[index])
+ end
+
+ function mp.mf_map_text(index,str)
+ local map = top.mapindices[tonumber(str)]
+ if type(map) == "table" then
+ local text = map.text
+ local overload = map.overload
+ local offset = 0
+ local width = 0
+ local where = nil
+ --
+ mp_index = index
+ -- the image text
+ if overload then
+ top.texstrings[mp_index] = map.template or map.label or "error"
+ tex.runtoks("mptexttoks")
+ local box = textakebox("mptextbox") or new_hlist()
+ width = bp * box.width
+ where = overload.where
+ end
+ -- the real text
+ top.texstrings[mp_index] = overload and overload.text or text or "error"
+ tex.runtoks("mptexttoks")
+ local box = textakebox("mptextbox") or new_hlist()
+ local twd = bp * box.width
+ local tht = bp * box.height
+ local tdp = bp * box.depth
+ -- the check
+ if where then
+ local scale = 1 -- / (map.scale or 1)
+ if where == "l" or where == "left" then
+ offset = scale * (twd - width)
+ elseif where == "m" or where == "middle" then
+ offset = scale * (twd - width) / 2
+ end
+ end
+ -- the result
+ top.textexts[mp_index] = box
+ top.mapmoves[mp_index] = { offset, map.dx or 0, map.dy or 0 }
+ --
+ mp.triplet(twd,tht,tdp)
+ madetext = nil
+ return
+ else
+ map = type(map) == "string" and map or str
+ return mp.mf_some_text(index,context.escape(map) or map)
+ end
+ end
+
-- This is a bit messy. In regular metapost it's a kind of immediate replacement
-- so embedded btex ... etex is not really working as one would expect. We now have
-- a mix: it's immediate when we are at the outer level (rawmadetext) and indirect
diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua
index cc4a77660..07fa6a191 100644
--- a/tex/context/base/mkiv/mlib-run.lua
+++ b/tex/context/base/mkiv/mlib-run.lua
@@ -852,6 +852,8 @@ do
end,
}
+ -- make table variant:
+
function metapost.simple(instance,code,useextensions,dontwrap)
-- can we pickup the instance ?
local mpx = metapost.pushformat {
diff --git a/tex/context/base/mkiv/mlib-scn.lua b/tex/context/base/mkiv/mlib-scn.lua
index 1ebe68bdc..709961543 100644
--- a/tex/context/base/mkiv/mlib-scn.lua
+++ b/tex/context/base/mkiv/mlib-scn.lua
@@ -250,7 +250,7 @@ local function get_parameters(nested)
end
local function getparameters()
- local namespace = scanstring()
+ local namespace = scanstring()
-- same as below
local parameters = get_parameters()
local presets = presets[namespace]
@@ -668,6 +668,11 @@ end
-- return false
-- end
+function metapost.scanparameters()
+-- scantoken() -- we scan the semicolon
+ return get_parameters()
+end
+
metapost.registerscript("getparameters", getparameters)
metapost.registerscript("applyparameters", applyparameters)
metapost.registerscript("presetparameters", presetparameters)
diff --git a/tex/context/base/mkiv/mlib-svg.lua b/tex/context/base/mkiv/mlib-svg.lua
index d201ec20e..afbf36ecf 100644
--- a/tex/context/base/mkiv/mlib-svg.lua
+++ b/tex/context/base/mkiv/mlib-svg.lua
@@ -6,36 +6,21 @@ if not modules then modules = { } end modules ['mlib-svg'] = {
license = "see context related readme files",
}
--- As usual with these standards, things like a path can be very compact while the rest is
--- very verbose which defeats the point. This is a first attempt. There will be a converter
--- to MP as well as directly to PDF. This module was made for one of the dangerous curves
--- talks at the 2019 CTX meeting. I will do the font when I need it (not that hard).
+-- Just a few notes:
--
--- There is no real need to boost performance here .. we can always make a fast variant
--- when really needed. I will also do some of the todo's when I run into proper fonts.
-
--- Written with Anne Clark on speakers as distraction.
-
--- Todo when I run into an example:
---
--- var(color,color)
--- --color<decimal>
--- currentColor : when i run into an example
--- some more fonts
---
--- Todo: some day
---
--- optimize
--- instances
--- withpen -> pickup
+-- There is no real need to boost performance here .. we can always make a fast
+-- variant when really needed. I will also do some of the todo's when I run into
+-- proper fonts. I need to optimize this a bit but will do that once I'm satisfied
+-- with the outcome and don't need more hooks and plugs. At some point I will
+-- optimize the MetaPost part because now we probably have more image wrapping
+-- than needed.
--
--- Todo: when i am motivated
+-- As usual with these standards, things like a path can be very compact while the
+-- rest is very verbose which defeats the point. This is a first attempt. There will
+-- be a converter to MP as well as directly to PDF. This module was made for one of
+-- the dangerous curves talks at the 2019 CTX meeting. I will do the font when I
+-- need it (not that hard).
--
--- shading
--- "none" -> false
--- clip = [ auto | rect(llx,lly,urx,ury) ] (in svg)
--- xlink url ... whatever
-
-- The fact that in the more recent versions of SVG the older text related elements
-- are depricated and not even supposed to be supported, combined with the fact that
-- the text element assumes css styling, demonstrates that there is not so much as a
@@ -43,468 +28,236 @@ if not modules then modules = { } end modules ['mlib-svg'] = {
-- (probably combined with some libraries that at that point exist) determine what
-- is standard. Anyway, it probably also means that these formats are not that
-- suitable for long term archival purposes. So don't take the next implementation
--- too serious.
-
+-- too serious. So in the end we now have (1) attributes for properties (which is
+-- nice and clean and what attributes are for, (2) a style attribute that needs to
+-- be parsed, (3) classes that map to styles and (4) element related styles, plus a
+-- kind of inheritance (given the limited number of elements sticking to only <g> as
+-- wrapper would have made much sense. Anyway, we need to deal with it. With all
+-- these style things going on, one can wonder where it will end. Basically svg
+-- became just a html element that way and less clean too. The same is true for
+-- tspan, which means that text itself is nested xml.
+--
-- We can do a direct conversion to PDF but then we also loose the abstraction which
--- in the future will be used.
+-- in the future will be used, and for fonts we need to spawn out to TeX anyway, so
+-- the little overhead of calling MetaPost is okay I guess. Also, we want to
+-- overload labels, share fonts with the main document, etc. and are not aiming at a
+-- general purpose SVG converter. For going to PDF one can just use InkScape.
+--
+-- Written with Anne Clark on speakers as distraction.
+--
+-- Todo when I run into an example (but ony when needed and reasonable):
+--
+-- var(color,color)
+-- --color<decimal>
+-- currentColor : when i run into an example
+-- a bit more shading
+-- clip = [ auto | rect(llx,lly,urx,ury) ] (in svg)
+-- xlink url ... whatever
+-- masks
+-- opacity per group (i need to add that to metafun first, inefficient pdf but
+-- maybe filldraw can help here)
+--
+-- Maybe in metafun:
+--
+-- penciled n -> withpen pencircle scaled n
+-- applied (...) -> transformed bymatrix (...)
+-- withopacity n -> withtransparency (1,n)
+
+-- When testing mbo files:
+--
+-- empty paths
+-- missing control points
+-- funny fontnames like abcdefverdana etc
+-- paths representing glyphs but also with style specs
+-- all kind of attributes
+-- very weird and inefficient shading
+
+-- 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 type, tonumber = type, tonumber
+local rawget, type, tonumber, tostring, next, setmetatable = rawget, 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 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 concat, setmetatableindex = table.concat, table.setmetatableindex
+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 = string.formatters
+local formatters, fullstrip = string.formatters, string.fullstrip
local extract = bit32.extract
+local utfsplit, utfbyte = utf.split, utf.byte
-local xmlconvert, xmlcollected, xmlcount, xmlfirst, xmlroot, xmltext = xml.convert, xml.collected, xml.count, xml.first, xml.root, xml.text
+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
-metapost = metapost or { }
-local metapost = metapost
-local context = context
+local bpfactor = number.dimenfactors.bp
-local report = logs.reporter("metapost","svg")
-
-local trace = false
--- local trace = true
-
--- todo: also a high res mode
--- todo: optimize (no hurry)
-
-local f_rectangle = formatters['unitsquare xyscaled (%.3N,%.3N) shifted (%.3N,%.3N)']
-local f_rounded = formatters['roundedsquarexy(%.3N,%.3N,%.3N,%.3N) shifted (%.3N,%.3N)']
-local f_ellipse = formatters['(fullcircle xyscaled (%.3N,%.3N) shifted (%.3N,%.3N))']
-local f_circle = formatters['(fullcircle scaled %.3N shifted (%.3N,%.3N))']
-local f_line = formatters['((%.3N,%.3N)--(%.3N,%.3N))']
-local f_fill = formatters['fill %s(%s--cycle)%s%s%s ;'] -- play safe
-local f_fill_cycle_c = formatters['fill %s(%s..cycle)%s%s%s ;']
-local f_fill_cycle_l = formatters['fill %s(%s--cycle)%s%s%s ;']
-local f_eofill = formatters['eofill %s(%s--cycle)%s%s%s ;'] -- play safe
-local f_eofill_cycle_c = formatters['eofill %s(%s..cycle)%s%s%s ;']
-local f_eofill_cycle_l = formatters['eofill %s(%s--cycle)%s%s%s ;']
-local f_nofill = formatters['nofill %s(%s--cycle)%s ;'] -- play safe
-local f_nofill_cycle_c = formatters['nofill %s(%s..cycle)%s ;']
-local f_nofill_cycle_l = formatters['nofill %s(%s--cycle)%s ;']
-local f_draw = formatters['draw %s(%s)%s%s%s%s%s ;']
-local f_nodraw = formatters['nodraw %s(%s)%s ;']
-
--- local f_fill = formatters['F %s(%s--C)%s%s%s ;'] -- play safe
--- local f_fill_cycle_c = formatters['F %s(%s..C)%s%s%s ;']
--- local f_fill_cycle_l = formatters['F %s(%s--C)%s%s%s ;']
--- local f_eofill = formatters['E %s(%s--C)%s%s%s ;'] -- play safe
--- local f_eofill_cycle_c = formatters['E %s(%s..C)%s%s%s ;']
--- local f_eofill_cycle_l = formatters['E %s(%s--C)%s%s%s ;']
--- local f_nofill = formatters['f %s(%s--C)%s ;'] -- play safe
--- local f_nofill_cycle_c = formatters['f %s(%s..C)%s ;']
--- local f_nofill_cycle_l = formatters['f %s(%s--C)%s ;']
--- local f_draw = formatters['D %s(%s)%s%s%s%s%s ;']
--- local f_nodraw = formatters['d %s(%s)%s ;']
-
-local f_color = formatters[' withcolor "%s"']
------ f_color_rgb = formatters[' withcolor "0x%02X%02X%02X"']
------ f_color_rgba = formatters[' withcolor "0x%02X%02X%02X" withtransparency (1,%3N)']
------ f_color_triplet = formatters['"0x%02X%02X%02X"']
-
-local f_rgb = formatters[' withcolor svgcolor(%.3N,%.3N,%.3N)']
-local f_rgba = formatters[' withcolor svgcolor(%.3N,%.3N,%.3N) withtransparency (1,%3N)']
-local f_triplet = formatters['svgvolor(%.3N,%.3N,%.3N)']
-local f_gray = formatters[' withcolor %.3N']
-
-local f_opacity = formatters[' withtransparency (1,%.3N)']
-local f_pen = formatters[' withpen pencircle scaled %.3N']
-
-local f_dashed_n = formatters[" dashed dashpattern (%s ) "]
-local f_dashed_y = formatters[" dashed dashpattern (%s ) shifted (%.3N,0) "]
-
-local f_moveto = formatters['(%N,%n)']
-local f_curveto_z = formatters[' controls (%.3N,%.3N) and (%.3N,%.3N) .. (%.3N,%.3N)']
-local f_curveto_n = formatters['.. controls (%.3N,%.3N) and (%.3N,%.3N) .. (%.3N,%.3N)']
-local f_lineto_z = formatters['(%.3N,%.3N)']
-local f_lineto_n = formatters['-- (%.3N,%.3N)']
-
-local f_rotatedaround = formatters[" ) rotatedaround((%.3N,%.3N),%.3N)"]
-local f_rotated = formatters[" ) rotated(%.3N)"]
-local f_shifted = formatters[" ) shifted(%.3N,%.3N)"]
-local f_slanted_x = formatters[" ) xslanted(%.3N)"]
-local f_slanted_y = formatters[" ) yslanted(%.3N)"]
-local f_scaled = formatters[" ) scaled(%.3N)"]
-local f_xyscaled = formatters[" ) xyscaled(%.3N,%.3N)"]
-local f_matrix = formatters[" ) transformed bymatrix(%.3N,%.3N,%.3N,%.3N,%.3N,%.3N)"]
-
--- penciled n -> withpen pencircle scaled n
--- applied (...) -> transformed bymatrix (...)
--- withopacity n -> withtransparency (1,n)
-
-local s_clip_start = 'draw image ('
-local f_clip_stop = formatters[') ; clip currentpicture to (%s) ;']
-local f_eoclip_stop = formatters[') ; eoclip currentpicture to (%s) ;']
-
-local f_transform_start = formatters["draw %s image ( "]
-local f_transform_stop = formatters[") %s ;"]
-
-local s_offset_start = "draw image ( "
-local f_offset_stop = formatters[") shifted (%.3N,%.3N) ;"]
-
-local s_scaled_start = "draw image ( "
-local f_scaled_stop = formatters[") scaled %.3N ;"]
-
-local s_hacked_start = "draw image ("
-local f_hacked_stop = formatters[") shifted (0,%.3N) scaled %.3N ;"]
--- local f_hacked_stop = formatters[") scaled %.3N ;"]
-
-local f_viewport_start = "draw image ("
-local f_viewport_stop = ") ;"
-local f_viewport_shift = formatters["currentpicture := currentpicture shifted (%03N,%03N);"]
-local f_viewport_clip = formatters["clip currentpicture to (unitsquare xyscaled (%03N,%03N));"]
-
-local f_linecap = formatters["interim linecap := %s ;"]
-local f_linejoin = formatters["interim linejoin := %s ;"]
-local f_miterlimit = formatters["interim miterlimit := %s ;"]
-
-local s_begingroup = "begingroup;"
-local s_endgroup = "endgroup;"
-
--- make dedicated macro
-
-local s_shade_linear = ' withshademethod "linear" '
-local s_shade_circular = ' withshademethod "circular" '
-local f_shade_step = formatters['withshadestep ( withshadefraction %.3N withshadecolors(%s,%s) )']
-local f_shade_one = formatters['withprescript "sh_center_a=%.3N %.3N"']
-local f_shade_two = formatters['withprescript "sh_center_b=%.3N %.3N"']
-
-local f_text_scaled = formatters['(textext.drt("%s") scaled %.3N shifted (%.3N,%.3N))']
-local f_text_normal = formatters['(textext.drt("%s") shifted (%.3N,%.3N))']
-
--- We can actually use the svg color definitions from the tex end but maybe a user doesn't
--- want those replace the normal definitions.
-
-local svgcolors = {
- black = 0x000000,
- navy = 0x000080,
- darkblue = 0x00008B,
- mediumblue = 0x0000CD,
- blue = 0x0000FF,
- darkgreen = 0x006400,
- green = 0x008000,
- teal = 0x008080,
- darkcyan = 0x008B8B,
- deepskyblue = 0x00BFFF,
- darkturquoise = 0x00CED1,
- mediumspringgreen = 0x00FA9A,
- lime = 0x00FF00,
- springgreen = 0x00FF7F,
- cyan = 0x00FFFF,
- aqua = 0x00FFFF,
- midnightblue = 0x191970,
- dodgerblue = 0x1E90FF,
- lightseagreen = 0x20B2AA,
- forestgreen = 0x228B22,
- seagreen = 0x2E8B57,
- darkslategray = 0x2F4F4F,
- darkslategrey = 0x2F4F4F,
- limegreen = 0x32CD32,
- mediumseagreen = 0x3CB371,
- turquoise = 0x40E0D0,
- royalblue = 0x4169E1,
- steelblue = 0x4682B4,
- darkslateblue = 0x483D8B,
- mediumturquoise = 0x48D1CC,
- indigo = 0x4B0082,
- darkolivegreen = 0x556B2F,
- cadetblue = 0x5F9EA0,
- cornflowerblue = 0x6495ED,
- mediumaquamarine = 0x66CDAA,
- dimgrey = 0x696969,
- dimgray = 0x696969,
- slateblue = 0x6A5ACD,
- olivedrab = 0x6B8E23,
- slategrey = 0x708090,
- slategray = 0x708090,
- lightslategray = 0x778899,
- lightslategrey = 0x778899,
- mediumslateblue = 0x7B68EE,
- lawngreen = 0x7CFC00,
- chartreuse = 0x7FFF00,
- aquamarine = 0x7FFFD4,
- maroon = 0x800000,
- purple = 0x800080,
- olive = 0x808000,
- gray = 0x808080,
- grey = 0x808080,
- skyblue = 0x87CEEB,
- lightskyblue = 0x87CEFA,
- blueviolet = 0x8A2BE2,
- darkred = 0x8B0000,
- darkmagenta = 0x8B008B,
- saddlebrown = 0x8B4513,
- darkseagreen = 0x8FBC8F,
- lightgreen = 0x90EE90,
- mediumpurple = 0x9370DB,
- darkviolet = 0x9400D3,
- palegreen = 0x98FB98,
- darkorchid = 0x9932CC,
- yellowgreen = 0x9ACD32,
- sienna = 0xA0522D,
- brown = 0xA52A2A,
- darkgray = 0xA9A9A9,
- darkgrey = 0xA9A9A9,
- lightblue = 0xADD8E6,
- greenyellow = 0xADFF2F,
- paleturquoise = 0xAFEEEE,
- lightsteelblue = 0xB0C4DE,
- powderblue = 0xB0E0E6,
- firebrick = 0xB22222,
- darkgoldenrod = 0xB8860B,
- mediumorchid = 0xBA55D3,
- rosybrown = 0xBC8F8F,
- darkkhaki = 0xBDB76B,
- silver = 0xC0C0C0,
- mediumvioletred = 0xC71585,
- indianred = 0xCD5C5C,
- peru = 0xCD853F,
- chocolate = 0xD2691E,
- tan = 0xD2B48C,
- lightgray = 0xD3D3D3,
- lightgrey = 0xD3D3D3,
- thistle = 0xD8BFD8,
- orchid = 0xDA70D6,
- goldenrod = 0xDAA520,
- palevioletred = 0xDB7093,
- crimson = 0xDC143C,
- gainsboro = 0xDCDCDC,
- plum = 0xDDA0DD,
- burlywood = 0xDEB887,
- lightcyan = 0xE0FFFF,
- lavender = 0xE6E6FA,
- darksalmon = 0xE9967A,
- violet = 0xEE82EE,
- palegoldenrod = 0xEEE8AA,
- lightcoral = 0xF08080,
- khaki = 0xF0E68C,
- aliceblue = 0xF0F8FF,
- honeydew = 0xF0FFF0,
- azure = 0xF0FFFF,
- sandybrown = 0xF4A460,
- wheat = 0xF5DEB3,
- beige = 0xF5F5DC,
- whitesmoke = 0xF5F5F5,
- mintcream = 0xF5FFFA,
- ghostwhite = 0xF8F8FF,
- salmon = 0xFA8072,
- antiquewhite = 0xFAEBD7,
- linen = 0xFAF0E6,
- lightgoldenrodyellow = 0xFAFAD2,
- oldlace = 0xFDF5E6,
- red = 0xFF0000,
- fuchsia = 0xFF00FF,
- magenta = 0xFF00FF,
- deeppink = 0xFF1493,
- orangered = 0xFF4500,
- tomato = 0xFF6347,
- hotpink = 0xFF69B4,
- coral = 0xFF7F50,
- darkorange = 0xFF8C00,
- lightsalmon = 0xFFA07A,
- orange = 0xFFA500,
- lightpink = 0xFFB6C1,
- pink = 0xFFC0CB,
- gold = 0xFFD700,
- peachpuff = 0xFFDAB9,
- navajowhite = 0xFFDEAD,
- moccasin = 0xFFE4B5,
- bisque = 0xFFE4C4,
- mistyrose = 0xFFE4E1,
- blanchedalmond = 0xFFEBCD,
- papayawhip = 0xFFEFD5,
- lavenderblush = 0xFFF0F5,
- seashell = 0xFFF5EE,
- cornsilk = 0xFFF8DC,
- lemonchiffon = 0xFFFACD,
- floralwhite = 0xFFFAF0,
- snow = 0xFFFAFA,
- yellow = 0xFFFF00,
- lightyellow = 0xFFFFE0,
- ivory = 0xFFFFF0,
- white = 0xFFFFFF,
-}
-
-local svgcolor = setmetatableindex(function(t,k)
- -- we delay building all these strings
- local v = svgcolors[k]
- if v then
- v = f_rgb(extract(v,16,8),extract(v,8,8),extract(v,0,8))
+local function xmlinheritattributes(c,pa)
+ local at = c.at
+ local dt = c.dt
+ if at and dt then
+ if pa then
+ setmetatableindex(at,pa)
+ end
+ for i=1,#dt do
+ local dti = dt[i]
+ if type(dti) == "table" then
+ xmlinheritattributes(dti,at)
+ end
+ end
else
- v = false
+ -- comment of so
end
- t[k] = v
- return v
-end)
+end
-local p_digit = lpegpatterns.digit
-local p_hexdigit = lpegpatterns.hexdigit
-local p_space = lpegpatterns.whitespace
+xml.inheritattributes = xmlinheritattributes
-local p_hexcolor = P("#") * C(p_hexdigit*p_hexdigit)^1 / function(r,g,b)
- r = tonumber(r,16)/255
- if g then
- g = tonumber(g,16)/255
- end
- if b then
- b = tonumber(b,16)/255
- end
- if b then
- return f_rgb(r,g,b)
- else
- return f_gray(r)
- end
-end
+-- Maybe some day helpers will move to the metapost.svg namespace!
-local p_hexcolor3 = P("#") * C(p_hexdigit*p_hexdigit)^1 / function(r,g,b)
- r = tonumber(r,16)/255
- g = g and tonumber(g,16)/255 or r
- b = b and tonumber(b,16)/255 or g
- return f_triplet(r,g,b)
-end
+metapost = metapost or { }
+local metapost = metapost
+local context = context
-local function hexcolor(c)
- return lpegmatch(p_hexcolor,c)
-end
+local report = logs.reporter("metapost","svg")
-local function hexcolor3(c)
- return lpegmatch(p_hexcolor3,c)
-end
+local trace = false trackers.register("metapost.svg", function(v) trace = v end)
+local trace_text = false trackers.register("metapost.svg.text", function(v) trace_text = v end)
+local trace_path = false trackers.register("metapost.svg.path", function(v) trace_path = v end)
+local trace_result = false trackers.register("metapost.svg.result", function(v) trace_result = v end)
--- gains a little:
+local pathtracer = {
+ ["stroke"] = "darkred",
+ ["stroke-opacity"] = ".5",
+ ["stroke-width"] = ".5",
+ ["fill"] = "darkgray",
+ ["fill-opacity"] = ".75",
+}
--- local hexhash = setmetatableindex(function(t,k) local v = lpegmatch(p_hexcolor, k) t[k] = v return v end) -- per file
--- local hexhash3 = setmetatableindex(function(t,k) local v = lpegmatch(p_hexcolor3,k) t[k] = v return v end) -- per file
+-- 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).
--
--- local function hexcolor (c) return hexhash [c] end -- directly do hexhash [c]
--- local function hexcolor3(c) return hexhash3[c] end -- directly do hexhash3[c]
-
--- Most of the conversion is rather trivial code till I ran into a file with arcs. A bit
--- of searching lead to the a2c javascript function but it has some puzzling thingies
--- (like sin and cos definitions that look like leftovers). Anyway, we can if needed
--- optimize it a bit more. Here does it come from:
+-- Most of the conversion is rather trivial code till I ran into a file with arcs. A
+-- bit of searching lead to the a2c javascript function but it has some puzzling
+-- thingies (like sin and cos definitions that look like leftovers and possible
+-- division by zero). Anyway, we can if needed optimize it a bit more. Here does it
+-- come from:
-- http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
-- https://github.com/adobe-webplatform/Snap.svg/blob/b242f49e6798ac297a3dad0dfb03c0893e394464/src/path.js
-local d120 = (pi * 120) / 180
-local pi2 = 2 * pi
+local a2c do
-local function a2c(x1, y1, rx, ry, angle, large, sweep, x2, y2, f1, f2, cx, cy)
+ local d120 = (pi * 120) / 180
+ local pi2 = 2 * pi
- local recursive = f1
+ a2c = function(x1, y1, rx, ry, angle, large, sweep, x2, y2, f1, f2, cx, cy)
- if rx == 0 or ry == 0 then
- return { x1, y1, x2, y2, x2, y2 }
- end
+ if (rx == 0 or ry == 0 ) or (x1 == x2 and y1 == y2) then
+ return { x1, y1, x2, y2, x2, y2 }
+ end
- if x1 == x2 and y1 == y2 then
- return { x1, y1, x2, y2, x2, y2 }
- end
+ local recursive = f1
+ local rad = pi / 180 * angle
+ local res = nil
+ local cosrad = cos(-rad) -- local cosrad = cosd(angle)
+ local sinrad = sin(-rad) -- local sinrad = sind(angle)
- local rad = pi / 180 * angle
- local res = nil
+ if not recursive then
- local cosrad = cos(-rad) -- local cosrad = cosd(angle)
- local sinrad = sin(-rad) -- local sinrad = sind(angle)
+ x1, y1 = x1 * cosrad - y1 * sinrad, x1 * sinrad + y1 * cosrad
+ x2, y2 = x2 * cosrad - y2 * sinrad, x2 * sinrad + y2 * cosrad
- if not recursive then
+ local x = (x1 - x2) / 2
+ local y = (y1 - y2) / 2
+ local xx = x * x
+ local yy = y * y
+ local h = xx / (rx * rx) + yy / (ry * ry)
- x1, y1 = x1 * cosrad - y1 * sinrad, x1 * sinrad + y1 * cosrad
- x2, y2 = x2 * cosrad - y2 * sinrad, x2 * sinrad + y2 * cosrad
+ if h > 1 then
+ h = sqrt(h)
+ rx = h * rx
+ ry = h * ry
+ end
- local x = (x1 - x2) / 2
- local y = (y1 - y2) / 2
- local xx = x * x
- local yy = y * y
- local h = xx / (rx * rx) + yy / (ry * ry)
+ local rx2 = rx * rx
+ local ry2 = ry * ry
+ local ry2xx = ry2 * xx
+ local rx2yy = rx2 * yy
+ local total = rx2yy + ry2xx -- otherwise overflow
- if h > 1 then
- h = sqrt(h)
- rx = h * rx
- ry = h * ry
- end
+ local k = total == 0 and 0 or sqrt(abs((rx2 * ry2 - rx2yy - ry2xx) / total))
- local rx2 = rx * rx
- local ry2 = ry * ry
- local ry2xx = ry2 * xx
- local rx2yy = rx2 * yy
- local total = rx2yy + ry2xx -- otherwise overflow
-
- local k = total == 0 and 0 or sqrt(abs((rx2 * ry2 - rx2yy - ry2xx) / total))
+ if large == sweep then
+ k = -k
+ end
- if large == sweep then
- k = -k
- end
+ cx = k * rx * y / ry + (x1 + x2) / 2
+ cy = k * -ry * x / rx + (y1 + y2) / 2
- cx = k * rx * y / ry + (x1 + x2) / 2
- cy = k * -ry * x / rx + (y1 + y2) / 2
+ f1 = (y1 - cy) / ry -- otherwise crash on a tiny eps
+ f2 = (y2 - cy) / ry -- otherwise crash on a tiny eps
- f1 = (y1 - cy) / ry -- otherwise crash on a tiny eps
- f2 = (y2 - cy) / ry -- otherwise crash on a tiny eps
+ f1 = asin((f1 < -1.0 and -1.0) or (f1 > 1.0 and 1.0) or f1)
+ f2 = asin((f2 < -1.0 and -1.0) or (f2 > 1.0 and 1.0) or f2)
- f1 = asin((f1 < -1.0 and -1.0) or (f1 > 1.0 and 1.0) or f1)
- f2 = asin((f2 < -1.0 and -1.0) or (f2 > 1.0 and 1.0) or f2)
+ if x1 < cx then f1 = pi - f1 end
+ if x2 < cx then f2 = pi - f2 end
- if x1 < cx then f1 = pi - f1 end
- if x2 < cx then f2 = pi - f2 end
+ if f1 < 0 then f1 = pi2 + f1 end
+ if f2 < 0 then f2 = pi2 + f2 end
- if f1 < 0 then f1 = pi2 + f1 end
- if f2 < 0 then f2 = pi2 + f2 end
+ if sweep ~= 0 and f1 > f2 then f1 = f1 - pi2 end
+ if sweep == 0 and f2 > f1 then f2 = f2 - pi2 end
- if sweep ~= 0 and f1 > f2 then
- f1 = f1 - pi2
end
- if sweep == 0 and f2 > f1 then
- f2 = f2 - pi2
+
+ if abs(f2 - f1) > d120 then
+ local f2old = f2
+ local x2old = x2
+ local y2old = y2
+ f2 = f1 + d120 * ((sweep ~= 0 and f2 > f1) and 1 or -1)
+ x2 = cx + rx * cos(f2)
+ y2 = cy + ry * sin(f2)
+ res = a2c(x2, y2, rx, ry, angle, 0, sweep, x2old, y2old, f2, f2old, cx, cy)
end
- end
+ local c1 = cos(f1)
+ local s1 = sin(f1)
+ local c2 = cos(f2)
+ local s2 = sin(f2)
- if abs(f2 - f1) > d120 then
- local f2old = f2
- local x2old = x2
- local y2old = y2
- f2 = f1 + d120 * ((sweep ~= 0 and f2 > f1) and 1 or -1)
- x2 = cx + rx * cos(f2)
- y2 = cy + ry * sin(f2)
- res = a2c(x2, y2, rx, ry, angle, 0, sweep, x2old, y2old, f2, f2old, cx, cy)
- end
+ local t = tan((f2 - f1) / 4)
+ local hx = 4 * rx * t / 3
+ local hy = 4 * ry * t / 3
+
+ local r = { x1 - hx * s1, y1 + hy * c1, x2 + hx * s2, y2 - hy * c2, x2, y2, unpack(res or { }) }
- local c1 = cos(f1)
- local s1 = sin(f1)
- local c2 = cos(f2)
- local s2 = sin(f2)
-
- local t = tan((f2 - f1) / 4)
- local hx = 4 * rx * t / 3
- local hy = 4 * ry * t / 3
-
- local r = { x1 - hx * s1, y1 + hy * c1, x2 + hx * s2, y2 - hy * c2, x2, y2, unpack(res or { }) }
-
- if not recursive then -- we can also check for sin/cos being 0/1
- cosrad = cos(rad)
- sinrad = sin(rad)
- -- cosrad = cosd(angle)
- -- sinrad = sind(angle)
- for i0=1,#r,2 do
- local i1 = i0 + 1
- local x = r[i0]
- local y = r[i1]
- r[i0] = x * cosrad - y * sinrad
- r[i1] = x * sinrad + y * cosrad
+ if not recursive then -- we can also check for sin/cos being 0/1
+ cosrad = cos(rad)
+ sinrad = sin(rad)
+ -- cosrad = cosd(angle)
+ -- sinrad = sind(angle)
+ for i0=1,#r,2 do
+ local i1 = i0 + 1
+ local x = r[i0]
+ local y = r[i1]
+ r[i0] = x * cosrad - y * sinrad
+ r[i1] = x * sinrad + y * cosrad
+ end
end
+
+ return r
end
- return r
end
--- incredible: we can find .123.456 => 0.123 0.456 ...
+-- We share some patterns.
+
+local p_digit = lpegpatterns.digit
+local p_hexdigit = lpegpatterns.hexdigit
+local p_space = lpegpatterns.whitespace
local factors = {
["pt"] = 1.25,
@@ -521,14 +274,18 @@ local percentage_r = 1/100
local percentage_x = percentage_r
local percentage_y = percentage_r
+-- incredible: we can find .123.456 => 0.123 0.456 ...
+
local p_command_x = C(S("Hh"))
local p_command_y = C(S("Vv"))
local p_command_xy = C(S("CcLlMmQqSsTt"))
local p_command_a = C(S("Aa"))
local p_command = C(S("Zz"))
-local p_separator = S("\t\n\r ,")^1
-local p_number = (S("+-")^0 * (p_digit^0 * P(".") * p_digit^1 + p_digit^1 * P(".") + p_digit^1) )
+local p_optseparator = S("\t\n\r ,")^0
+local p_separator = S("\t\n\r ,")^1
+local p_number = (S("+-")^0 * (p_digit^0 * P(".") * p_digit^1 + p_digit^1 * P(".") + p_digit^1))
+ * (P("e") * S("+-")^0 * p_digit^1)^-1
local function convert (n) n = tonumber(n) return n end
local function convert_r (n,u) n = tonumber(n) if u == true then return percentage_r * n elseif u then return u * n else return n end end
@@ -537,11 +294,11 @@ local function convert_y (n,u) n = tonumber(n) if u == true then return percen
local function convert_vx(n,u) n = tonumber(n) if u == true then return percentage_x * n elseif u then return u * n else return n end end
local function convert_vy(n,u) n = - tonumber(n) if u == true then return percentage_y * n elseif u then return u * n else return n end end
-local p_unit = ( P("p") * S("txc") + P("e") * S("xm") + S("mc") * P("m") + P("in")) / factors
+local p_unit = (P("p") * S("txc") + P("e") * S("xm") + S("mc") * P("m") + P("in")) / factors
local p_percent = P("%") * Cc(true)
-local c_number_n = C(p_number)
-local c_number_u = C(p_number) * (p_unit + p_percent)^-1
+local c_number_n = C(p_number)
+local c_number_u = C(p_number) * (p_unit + p_percent)^-1
local p_number_n = c_number_n / convert
local p_number_x = c_number_u / convert_x
@@ -550,300 +307,688 @@ local p_number_y = c_number_u / convert_y
local p_number_vy = c_number_u / convert_vy
local p_number_r = c_number_u / convert_r
--- local p_number = p_number_r -- maybe no percent here
-
-local function asnumber (s) return lpegmatch(p_number, s) end
-local function asnumber_r (s) return lpegmatch(p_number_r, s) end
-local function asnumber_x (s) return lpegmatch(p_number_x, s) end
-local function asnumber_y (s) return lpegmatch(p_number_y, s) end
-local function asnumber_vx(s) return lpegmatch(p_number_vx,s) end
-local function asnumber_vy(s) return lpegmatch(p_number_vy,s) end
-
-local p_numbersep = p_number_n + p_separator
-local p_numbers = p_separator^0 * P("(") * p_numbersep^0 * p_separator^0 * P(")")
-local p_four = p_numbersep^4
-
--- local p_path = Ct((p_command + (p_number_x * p_separator^0 * p_number_y * p_separator^0) + p_separator)^1)
-
-local p_path = Ct ( (
- p_command_xy * (p_separator^0 * p_number_vx *
- p_separator^0 * p_number_vy )^1
- + p_command_x * (p_separator^0 * p_number_vx )^1
- + p_command_y * (p_separator^0 * p_number_vy )^1
- + p_command_a * (p_separator^0 * p_number_vx *
- p_separator^0 * p_number_vy *
- p_separator^0 * p_number_r *
- p_separator^0 * p_number_n * -- flags
- p_separator^0 * p_number_n * -- flags
- p_separator^0 * p_number_vx *
- p_separator^0 * p_number_vy )^1
+local function asnumber (s) return s and lpegmatch(p_number, s) or 0 end
+local function asnumber_r (s) return s and lpegmatch(p_number_r, s) or 0 end
+local function asnumber_x (s) return s and lpegmatch(p_number_x, s) or 0 end
+local function asnumber_y (s) return s and lpegmatch(p_number_y, s) or 0 end
+local function asnumber_vx(s) return s and lpegmatch(p_number_vx,s) or 0 end
+local function asnumber_vy(s) return s and lpegmatch(p_number_vy,s) or 0 end
+
+local p_number_vx_t = Ct { (p_number_vx + p_separator)^1 }
+local p_number_vy_t = Ct { (p_number_vy + p_separator)^1 }
+
+local zerotable = { 0 }
+
+local function asnumber_vx_t(s) return s and lpegmatch(p_number_vx_t,s) or zerotable end
+local function asnumber_vy_t(s) return s and lpegmatch(p_number_vy_t,s) or zerotable end
+
+local p_numbersep = p_number_n + p_separator
+local p_numbers = p_optseparator * P("(") * p_numbersep^0 * p_optseparator * P(")")
+local p_fournumbers = p_numbersep^4
+local p_path = Ct ( (
+ p_command_xy * (p_optseparator * p_number_vx *
+ p_optseparator * p_number_vy )^1
+ + p_command_x * (p_optseparator * p_number_vx )^1
+ + p_command_y * (p_optseparator * p_number_vy )^1
+ + p_command_a * (p_optseparator * p_number_vx *
+ p_optseparator * p_number_vy *
+ p_optseparator * p_number_r *
+ p_optseparator * p_number_n * -- flags
+ p_optseparator * p_number_n * -- flags
+ p_optseparator * p_number_vx *
+ p_optseparator * p_number_vy )^1
+ p_command
+ p_separator
)^1 )
-local p_rgbacolor = P("rgba(") * (C(p_number) + p_separator)^1 * P(")")
+-- We can actually use the svg color definitions from the tex end but maybe a user
+-- doesn't want those replace the normal definitions.
+--
+-- local hexhash = setmetatableindex(function(t,k) local v = lpegmatch(p_hexcolor, k) t[k] = v return v end) -- per file
+-- local hexhash3 = setmetatableindex(function(t,k) local v = lpegmatch(p_hexcolor3,k) t[k] = v return v end) -- per file
+--
+-- local function hexcolor (c) return hexhash [c] end -- directly do hexhash [c]
+-- local function hexcolor3(c) return hexhash3[c] end -- directly do hexhash3[c]
+
+local rgbcomponents, withcolor, thecolor do
+
+ local svgcolors = {
+ aliceblue = 0xF0F8FF, antiquewhite = 0xFAEBD7, aqua = 0x00FFFF, aquamarine = 0x7FFFD4,
+ azure = 0xF0FFFF, beige = 0xF5F5DC, bisque = 0xFFE4C4, black = 0x000000,
+ blanchedalmond = 0xFFEBCD, blue = 0x0000FF, blueviolet = 0x8A2BE2, brown = 0xA52A2A,
+ burlywood = 0xDEB887, cadetblue = 0x5F9EA0, hartreuse = 0x7FFF00, chocolate = 0xD2691E,
+ coral = 0xFF7F50, cornflowerblue = 0x6495ED, cornsilk = 0xFFF8DC, crimson = 0xDC143C,
+ cyan = 0x00FFFF, darkblue = 0x00008B, darkcyan = 0x008B8B, darkgoldenrod = 0xB8860B,
+ darkgray = 0xA9A9A9, darkgreen = 0x006400, darkgrey = 0xA9A9A9, darkkhaki = 0xBDB76B,
+ darkmagenta = 0x8B008B, darkolivegreen = 0x556B2F, darkorange = 0xFF8C00, darkorchid = 0x9932CC,
+ darkred = 0x8B0000, darksalmon = 0xE9967A, darkseagreen = 0x8FBC8F, darkslateblue = 0x483D8B,
+ darkslategray = 0x2F4F4F, darkslategrey = 0x2F4F4F, darkturquoise = 0x00CED1, darkviolet = 0x9400D3,
+ deeppink = 0xFF1493, deepskyblue = 0x00BFFF, dimgray = 0x696969, dimgrey = 0x696969,
+ dodgerblue = 0x1E90FF, firebrick = 0xB22222, floralwhite = 0xFFFAF0, forestgreen = 0x228B22,
+ fuchsia = 0xFF00FF, gainsboro = 0xDCDCDC, ghostwhite = 0xF8F8FF, gold = 0xFFD700,
+ goldenrod = 0xDAA520, gray = 0x808080, green = 0x008000, greenyellow = 0xADFF2F,
+ grey = 0x808080, honeydew = 0xF0FFF0, hotpink = 0xFF69B4, indianred = 0xCD5C5C,
+ indigo = 0x4B0082, ivory = 0xFFFFF0, khaki = 0xF0E68C, lavender = 0xE6E6FA,
+ lavenderblush = 0xFFF0F5, lawngreen = 0x7CFC00, lemonchiffon = 0xFFFACD, lightblue = 0xADD8E6,
+ lightcoral = 0xF08080, lightcyan = 0xE0FFFF, lightgoldenrodyellow = 0xFAFAD2, lightgray = 0xD3D3D3,
+ lightgreen = 0x90EE90, lightgrey = 0xD3D3D3, lightpink = 0xFFB6C1, lightsalmon = 0xFFA07A,
+ lightseagreen = 0x20B2AA, lightskyblue = 0x87CEFA, lightslategray = 0x778899, lightslategrey = 0x778899,
+ lightsteelblue = 0xB0C4DE, lightyellow = 0xFFFFE0, lime = 0x00FF00, limegreen = 0x32CD32,
+ linen = 0xFAF0E6, magenta = 0xFF00FF, maroon = 0x800000, mediumaquamarine = 0x66CDAA,
+ mediumblue = 0x0000CD, mediumorchid = 0xBA55D3, mediumpurple = 0x9370DB, mediumseagreen = 0x3CB371,
+ mediumslateblue = 0x7B68EE, mediumspringgreen = 0x00FA9A, mediumturquoise = 0x48D1CC, mediumvioletred = 0xC71585,
+ midnightblue = 0x191970, mintcream = 0xF5FFFA, mistyrose = 0xFFE4E1, moccasin = 0xFFE4B5,
+ navajowhite = 0xFFDEAD, navy = 0x000080, oldlace = 0xFDF5E6, olive = 0x808000,
+ olivedrab = 0x6B8E23, orange = 0xFFA500, orangered = 0xFF4500, orchid = 0xDA70D6,
+ palegoldenrod = 0xEEE8AA, palegreen = 0x98FB98, paleturquoise = 0xAFEEEE, palevioletred = 0xDB7093,
+ papayawhip = 0xFFEFD5, peachpuff = 0xFFDAB9, peru = 0xCD853F, pink = 0xFFC0CB,
+ plum = 0xDDA0DD, powderblue = 0xB0E0E6, purple = 0x800080, red = 0xFF0000,
+ rosybrown = 0xBC8F8F, royalblue = 0x4169E1, saddlebrown = 0x8B4513, salmon = 0xFA8072,
+ sandybrown = 0xF4A460, seagreen = 0x2E8B57, seashell = 0xFFF5EE, sienna = 0xA0522D,
+ silver = 0xC0C0C0, skyblue = 0x87CEEB, slateblue = 0x6A5ACD, slategray = 0x708090,
+ slategrey = 0x708090, snow = 0xFFFAFA, springgreen = 0x00FF7F, steelblue = 0x4682B4,
+ tan = 0xD2B48C, teal = 0x008080, thistle = 0xD8BFD8, tomato = 0xFF6347,
+ turquoise = 0x40E0D0, violet = 0xEE82EE, wheat = 0xF5DEB3, white = 0xFFFFFF,
+ whitesmoke = 0xF5F5F5, yellow = 0xFFFF00, yellowgreen = 0x9ACD32,
+ }
-local function rgbacolor(s)
- local r, g, b, a = lpegmatch(p_rgbacolor,s)
- if a then
- return f_rgba(r/255,g/255,b/255,a)
- end
-end
+ local f_rgb = formatters['withcolor svgcolor(%N,%N,%N)']
+ local f_gray = formatters['withcolor svggray(%N)']
+ local f_rgba = formatters['withcolor svgcolor(%N,%N,%N) withtransparency (1,%N)']
+ local f_graya = formatters['withcolor svggray(%N) withtransparency (1,%N)']
+ local f_name = formatters['withcolor "%s"']
+ local f_svgcolor = formatters['svgcolor(%N,%N,%N)']
+ local f_svggray = formatters['svggray(%N)']
+ local f_svgname = formatters['"%s"']
+
+ local triplets = setmetatableindex(function(t,k)
+ -- we delay building all these strings
+ local v = svgcolors[k]
+ if v then
+ v = { extract(v,16,8)/255, extract(v,8,8)/255, extract(v,0,8)/255 }
+ else
+ v = false
+ end
+ t[k] = v
+ return v
+ end)
-local function viewbox(v)
- local x, y, w, h = lpegmatch(p_four,v)
- if h then
- return x, y, w, h
+ local p_fraction = C(p_number) * C("%")^-1 / function(a,b)
+ a = tonumber(a) return a / (b and 100 or 255)
end
-end
+ local p_hexcolor = P("#") * C(p_hexdigit*p_hexdigit)^1 / function(r,g,b)
+ return r and tonumber(r,16)/255 or nil, g and tonumber(g,16)/255 or nil, b and tonumber(b,16)/255 or nil
+ end
+ local p_rgbacolor = P("rgb") * (P("a")^-1) * P("(") * (p_fraction + p_separator)^1 * P(")")
--- actually we can loop faster because we can go to the last one
+ rgbcomponents = function(color)
+ local h = lpegmatch(p_hexcolor,color)
+ if h then
+ return h
+ end
+ local r, g, b, a = lpegmatch(p_rgbacolor,color)
+ if r then
+ return r, g or r, b or r
+ end
+ local t = triplets[color]
+ return t[1], t[2], t[3]
-local function grabpath(str)
- local p = lpegmatch(p_path,str)
- local np = #p
- local t = { } -- no real saving here if we share
- local n = 0
- local all = { entries = np, closed = false, curve = false }
- local a = 0
- local i = 0
- local last = "M"
- local prev = last
- local kind = "L"
- local x = 0
- local y = 0
- local x1 = 0
- local y1 = 0
- local x2 = 0
- local y2 = 0
- local rx = 0
- local ry = 0
- local ar = 0
- local al = 0
- local as = 0
- local ac = nil
- while i < np do
- i = i + 1
- local pi = p[i]
- if type(pi) ~= "number" then
- last = pi
- i = i + 1
- pi = p[i]
- end
- -- most often
- ::restart::
- if last == "c" then
- x1 = x + pi
- i = i + 1 ; y1 = y + p[i]
- i = i + 1 ; x2 = x + p[i]
- i = i + 1 ; y2 = y + p[i]
- i = i + 1 ; x = x + p[i]
- i = i + 1 ; y = y + p[i]
- goto curveto
- elseif last == "l" then
- x = x + pi
- i = i + 1 ; y = y + p[i]
- goto lineto
- elseif last == "h" then
- x = x + pi
- goto lineto
- elseif last == "v" then
- y = y + pi
- goto lineto
- elseif last == "a" then
- x1 = x
- y1 = y
- rx = pi
- i = i + 1 ; ry = p[i]
- i = i + 1 ; ar = p[i]
- i = i + 1 ; al = p[i]
- i = i + 1 ; as = p[i]
- i = i + 1 ; x = x + p[i]
- i = i + 1 ; y = y + p[i]
- goto arc
- elseif last == "s" then
- if prev == "C" then
- x1 = 2 * x - x2
- y1 = 2 * y - y2
+ end
+
+ withcolor = function(color)
+ local r, g, b = lpegmatch(p_hexcolor,color)
+ if b and not (r == g and g == b) then
+ return f_rgb(r,g,b)
+ elseif r then
+ return f_gray(r)
+ end
+ local r, g, b, a = lpegmatch(p_rgbacolor,color)
+ if a then
+ if a == 1 then
+ if r == g and g == b then
+ return f_gray(r)
+ else
+ return f_rgb(r,g,b)
+ end
else
- x1 = x
- y1 = y
- end
- x2 = x + pi
- i = i + 1 ; y2 = y + p[i]
- i = i + 1 ; x = x + p[i]
- i = i + 1 ; y = y + p[i]
- goto curveto
- elseif last == "m" then
- if n > 0 then
- a = a + 1
- all[a] = concat(t,"",1,n)
- n = 0
- end
- x = x + pi
- i = i + 1 ; y = y + p[i]
- goto moveto
- elseif last == "z" then
- goto close
- -- less frequent
- elseif last == "C" then
- x1 = pi
- i = i + 1 ; y1 = p[i]
- i = i + 1 ; x2 = p[i]
- i = i + 1 ; y2 = p[i]
- i = i + 1 ; x = p[i]
- i = i + 1 ; y = p[i]
- goto curveto
- elseif last == "L" then
- x = pi
- i = i + 1 ; y = p[i]
- goto lineto
- elseif last == "H" then
- x = pi
- goto lineto
- elseif last == "V" then
- y = pi
- goto lineto
- elseif last == "A" then
- x1 = x
- y1 = y
- rx = pi
- i = i + 1 ; ry = p[i]
- i = i + 1 ; ar = p[i]
- i = i + 1 ; al = p[i]
- i = i + 1 ; as = p[i]
- i = i + 1 ; x = p[i]
- i = i + 1 ; y = p[i]
- goto arc
- elseif last == "S" then
- if prev == "C" then
- x1 = 2 * x - x2
- y1 = 2 * y - y2
+ if r == g and g == b then
+ return f_graya(r,a)
+ else
+ return f_rgba(r,g,b,a)
+ end
+ end
+ end
+ if not r then
+ local t = triplets[color]
+ if t then
+ r, g, b = t[1], t[2], t[3]
+ end
+ end
+ if r then
+ if r == g and g == b then
+ return f_gray(r)
+ elseif g and b then
+ return f_rgb(r,g,b)
else
- x1 = x
- y1 = y
- end
- x2 = pi
- i = i + 1 ; y2 = p[i]
- i = i + 1 ; x = p[i]
- i = i + 1 ; y = p[i]
- goto curveto
- elseif last == "M" then
- if n > 0 then
- a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
- end
- x = pi ;
- i = i + 1 ; y = p[i]
- goto moveto
- elseif last == "Z" then
- goto close
- -- very seldom
- elseif last == "q" then
- x1 = x + pi
- i = i + 1 ; y1 = y + p[i]
- i = i + 1 ; x2 = x + p[i]
- i = i + 1 ; y2 = y + p[i]
- goto quadratic
- elseif last == "t" then
- if prev == "C" then
- x1 = 2 * x - x1
- y1 = 2 * y - y1
+ return f_gray(r)
+ end
+ end
+ return f_name(color)
+ end
+
+ thecolor = function(color)
+ local h = lpegmatch(p_hexcolor,color)
+ if h then
+ return h
+ end
+ local r, g, b, a = lpegmatch(p_rgbacolor,color)
+ if not r then
+ local t = triplets[color]
+ if t then
+ r, g, b = t[1], t[2], t[3]
+ end
+ end
+ if r then
+ if r == g and g == b then
+ return f_svggray(r)
+ elseif g and b then
+ return f_svgcolor(r,g,b)
else
- x1 = x
- y1 = y
- end
- x2 = x + pi
- i = i + 1 ; y2 = y + p[i]
- goto quadratic
- elseif last == "Q" then
- x1 = pi
- i = i + 1 ; y1 = p[i]
- i = i + 1 ; x2 = p[i]
- i = i + 1 ; y2 = p[i]
- goto quadratic
- elseif last == "T" then
- if prev == "C" then
- x1 = 2 * x - x1
- y1 = 2 * y - y1
+ return f_svggray(r)
+ end
+ end
+ return f_svgname(color)
+ end
+
+end
+
+-- actually we can loop faster because we can go to the last one
+
+local grabpath, grablist do
+
+ local f_moveto = formatters['(%N,%n)']
+ local f_curveto_z = formatters['controls(%N,%N)and(%N,%N)..(%N,%N)']
+ local f_curveto_n = formatters['..controls(%N,%N)and(%N,%N)..(%N,%N)']
+ local f_lineto_z = formatters['(%N,%N)']
+ local f_lineto_n = formatters['--(%N,%N)']
+
+ local m = { __index = function() return 0 end }
+
+ grabpath = function(str)
+ local p = lpegmatch(p_path,str) or { }
+ local np = #p
+ local all = { entries = np, closed = false, curve = false }
+ if np == 0 then
+ return all
+ end
+ setmetatable(p,m)
+ local t = { } -- no real saving here if we share
+ local n = 0
+ local a = 0
+ local i = 0
+ local last = "M"
+ local prev = last
+ local kind = "L"
+ local x, y = 0, 0
+ local x1, y1 = 0, 0
+ local x2, y2 = 0, 0
+ local rx, ry = 0, 0
+ local ar, al = 0, 0
+ local as, ac = 0, nil
+ local mx, my = 0, 0
+ while i < np do
+ i = i + 1
+ local pi = p[i]
+ if type(pi) ~= "number" then
+ last = pi
+ i = i + 1
+ pi = p[i]
+ end
+ -- most often
+ if last == "c" then
+ x1 = x + pi
+ i = i + 1 ; y1 = y + p[i]
+ i = i + 1 ; x2 = x + p[i]
+ i = i + 1 ; y2 = y + p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto curveto
+ elseif last == "l" then
+ x = x + pi
+ i = i + 1 ; y = y + p[i]
+ goto lineto
+ elseif last == "h" then
+ x = x + pi
+ goto lineto
+ elseif last == "v" then
+ y = y + pi
+ goto lineto
+ elseif last == "a" then
+ x1 = x
+ y1 = y
+ rx = pi
+ i = i + 1 ; ry = p[i]
+ i = i + 1 ; ar = p[i]
+ i = i + 1 ; al = p[i]
+ i = i + 1 ; as = p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto arc
+ elseif last == "s" then
+ if prev == "C" then
+ x1 = 2 * x - x2
+ y1 = 2 * y - y2
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = x + pi
+ i = i + 1 ; y2 = y + p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto curveto
+ elseif last == "m" then
+ if n > 0 then
+ a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
+ end
+ x = x + pi
+ i = i + 1 ; y = y + p[i]
+ goto moveto
+ elseif last == "z" then
+ goto close
+ -- less frequent
+ elseif last == "C" then
+ x1 = pi
+ i = i + 1 ; y1 = p[i]
+ i = i + 1 ; x2 = p[i]
+ i = i + 1 ; y2 = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto curveto
+ elseif last == "L" then
+ x = pi
+ i = i + 1 ; y = p[i]
+ goto lineto
+ elseif last == "H" then
+ x = pi
+ goto lineto
+ elseif last == "V" then
+ y = pi
+ goto lineto
+ elseif last == "A" then
+ x1 = x
+ y1 = y
+ rx = pi
+ i = i + 1 ; ry = p[i]
+ i = i + 1 ; ar = p[i]
+ i = i + 1 ; al = p[i]
+ i = i + 1 ; as = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto arc
+ elseif last == "S" then
+ if prev == "C" then
+ x1 = 2 * x - x2
+ y1 = 2 * y - y2
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = pi
+ i = i + 1 ; y2 = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto curveto
+ elseif last == "M" then
+ if n > 0 then
+ a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
+ end
+ x = pi ;
+ i = i + 1 ; y = p[i]
+ goto moveto
+ elseif last == "Z" then
+ goto close
+ -- very seldom
+ elseif last == "q" then
+ x1 = x + pi
+ i = i + 1 ; y1 = y + p[i]
+ i = i + 1 ; x2 = x + p[i]
+ i = i + 1 ; y2 = y + p[i]
+ goto quadratic
+ elseif last == "t" then
+ if prev == "C" then
+ x1 = 2 * x - x1
+ y1 = 2 * y - y1
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = x + pi
+ i = i + 1 ; y2 = y + p[i]
+ goto quadratic
+ elseif last == "Q" then
+ x1 = pi
+ i = i + 1 ; y1 = p[i]
+ i = i + 1 ; x2 = p[i]
+ i = i + 1 ; y2 = p[i]
+ goto quadratic
+ elseif last == "T" then
+ if prev == "C" then
+ x1 = 2 * x - x1
+ y1 = 2 * y - y1
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = pi
+ i = i + 1 ; y2 = p[i]
+ goto quadratic
else
- x1 = x
- y1 = y
+ goto continue
end
- x2 = pi
- i = i + 1 ; y2 = p[i]
- goto quadratic
- else
- goto continue
- end
- ::moveto::
- n = n + 1 ; t[n] = f_moveto(x,y)
- last = last == "M" and "L" or "l"
- prev = "M"
- goto continue
- ::lineto::
- n = n + 1 ; t[n] = (n > 0 and f_lineto_n or f_lineto_z)(x,y)
- prev = "L"
- goto continue
- ::curveto::
- n = n + 1 ; t[n] = (n > 0 and f_curveto_n or f_curveto_z)(x1,y1,x2,y2,x,y)
- prev = "C"
- goto continue
- ::arc::
- ac = a2c(x1,y1,rx,ry,ar,al,as,x,y)
- for i=1,#ac,6 do
+ ::moveto::
+ n = n + 1 ; t[n] = f_moveto(x,y)
+ last = last == "M" and "L" or "l"
+ prev = "M"
+ mx = x
+ my = y
+ goto continue
+ ::lineto::
+ n = n + 1 ; t[n] = (n > 0 and f_lineto_n or f_lineto_z)(x,y)
+ prev = "L"
+ goto continue
+ ::curveto::
+ n = n + 1 ; t[n] = (n > 0 and f_curveto_n or f_curveto_z)(x1,y1,x2,y2,x,y)
+ prev = "C"
+ goto continue
+ ::arc::
+ ac = a2c(x1,y1,rx,ry,ar,al,as,x,y)
+ for i=1,#ac,6 do
+ n = n + 1 ; t[n] = (n > 0 and f_curveto_n or f_curveto_z)(
+ ac[i],ac[i+1],ac[i+2],ac[i+3],ac[i+4],ac[i+5]
+ )
+ end
+ prev = "A"
+ goto continue
+ ::quadratic::
n = n + 1 ; t[n] = (n > 0 and f_curveto_n or f_curveto_z)(
- ac[i],ac[i+1],ac[i+2],ac[i+3],ac[i+4],ac[i+5]
+ x + 2/3 * (x1-x ), y + 2/3 * (y1-y ),
+ x2 + 2/3 * (x1-x2), y2 + 2/3 * (y1-y2),
+ x2, y2
)
+ x = x2
+ y = y2
+ prev = "C"
+ goto continue
+ ::close::
+ -- n = n + 1 ; t[n] = prev == "C" and "..cycle" or "--cycle"
+ n = n + 1 ; t[n] = "--cycle"
+ if n > 0 then
+ a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
+ end
+ if i == np then
+ break
+ else
+ i = i - 1
+ end
+ kind = prev
+ prev = "Z"
+ -- this is kind of undocumented: a close also moves back
+ x = mx
+ y = my
+ ::continue::
+ end
+ if n > 0 then
+ a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
+ end
+ if prev == "Z" then
+ all.closed = true
+ end
+ all.curve = (kind == "C" or kind == "A")
+ return all, p
+ end
+
+ -- this is a bit tricky as what are points for a mark ... the next can be simplified
+ -- a lot
+
+ grablist = function(p)
+ local np = #p
+ if np == 0 then
+ return nil
+ end
+ local t = { }
+ local n = 0
+ local a = 0
+ local i = 0
+ local last = "M"
+ local prev = last
+ local kind = "L"
+ local x, y = 0, 0
+ local x1, y1 = 0, 0
+ local x2, y2 = 0, 0
+ local rx, ry = 0, 0
+ local ar, al = 0, 0
+ local as, ac = 0, nil
+ local mx, my = 0, 0
+ while i < np do
+ i = i + 1
+ local pi = p[i]
+ if type(pi) ~= "number" then
+ last = pi
+ i = i + 1
+ pi = p[i]
end
- prev = "A"
- goto continue
- ::quadratic::
- n = n + 1 ; t[n] = (n > 0 and f_curveto_n or f_curveto_z)(
- x + 2/3 * (x1-x ), y + 2/3 * (y1-y ),
- x2 + 2/3 * (x1-x2), y2 + 2/3 * (y1-y2),
- x2, y2
- )
- x = x2
- y = y2
- prev = "C"
- goto continue
- ::close::
- -- n = n + 1 ; t[n] = prev == "C" and "..cycle" or "--cycle"
- n = n + 1 ; t[n] = "--cycle"
- if n > 0 then
- a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
- end
- if i == n then
- break
+ -- most often
+ if last == "c" then
+ x1 = x + pi
+ i = i + 1 ; y1 = y + p[i]
+ i = i + 1 ; x2 = x + p[i]
+ i = i + 1 ; y2 = y + p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto curveto
+ elseif last == "l" then
+ x = x + pi
+ i = i + 1 ; y = y + p[i]
+ goto lineto
+ elseif last == "h" then
+ x = x + pi
+ goto lineto
+ elseif last == "v" then
+ y = y + pi
+ goto lineto
+ elseif last == "a" then
+ x1 = x
+ y1 = y
+ rx = pi
+ i = i + 1 ; ry = p[i]
+ i = i + 1 ; ar = p[i]
+ i = i + 1 ; al = p[i]
+ i = i + 1 ; as = p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto arc
+ elseif last == "s" then
+ if prev == "C" then
+ x1 = 2 * x - x2
+ y1 = 2 * y - y2
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = x + pi
+ i = i + 1 ; y2 = y + p[i]
+ i = i + 1 ; x = x + p[i]
+ i = i + 1 ; y = y + p[i]
+ goto curveto
+ elseif last == "m" then
+ x = x + pi
+ i = i + 1 ; y = y + p[i]
+ goto moveto
+ elseif last == "z" then
+ goto close
+ -- less frequent
+ elseif last == "C" then
+ x1 = pi
+ i = i + 1 ; y1 = p[i]
+ i = i + 1 ; x2 = p[i]
+ i = i + 1 ; y2 = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto curveto
+ elseif last == "L" then
+ x = pi
+ i = i + 1 ; y = p[i]
+ goto lineto
+ elseif last == "H" then
+ x = pi
+ goto lineto
+ elseif last == "V" then
+ y = pi
+ goto lineto
+ elseif last == "A" then
+ x1 = x
+ y1 = y
+ rx = pi
+ i = i + 1 ; ry = p[i]
+ i = i + 1 ; ar = p[i]
+ i = i + 1 ; al = p[i]
+ i = i + 1 ; as = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto arc
+ elseif last == "S" then
+ if prev == "C" then
+ x1 = 2 * x - x2
+ y1 = 2 * y - y2
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = pi
+ i = i + 1 ; y2 = p[i]
+ i = i + 1 ; x = p[i]
+ i = i + 1 ; y = p[i]
+ goto curveto
+ elseif last == "M" then
+ x = pi ;
+ i = i + 1 ; y = p[i]
+ goto moveto
+ elseif last == "Z" then
+ goto close
+ -- very seldom
+ elseif last == "q" then
+ x1 = x + pi
+ i = i + 1 ; y1 = y + p[i]
+ i = i + 1 ; x2 = x + p[i]
+ i = i + 1 ; y2 = y + p[i]
+ goto quadratic
+ elseif last == "t" then
+ if prev == "C" then
+ x1 = 2 * x - x1
+ y1 = 2 * y - y1
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = x + pi
+ i = i + 1 ; y2 = y + p[i]
+ goto quadratic
+ elseif last == "Q" then
+ x1 = pi
+ i = i + 1 ; y1 = p[i]
+ i = i + 1 ; x2 = p[i]
+ i = i + 1 ; y2 = p[i]
+ goto quadratic
+ elseif last == "T" then
+ if prev == "C" then
+ x1 = 2 * x - x1
+ y1 = 2 * y - y1
+ else
+ x1 = x
+ y1 = y
+ end
+ x2 = pi
+ i = i + 1 ; y2 = p[i]
+ goto quadratic
else
- i = i - 1
+ goto continue
end
- kind = prev
- prev = "Z"
- ::continue::
- end
- if n > 0 then
- a = a + 1 ; all[a] = concat(t,"",1,n) ; n = 0
- end
- if prev == "Z" then
- all.closed = true
+ ::moveto::
+ n = n + 1 ; t[n] = x
+ n = n + 1 ; t[n] = y
+ last = last == "M" and "L" or "l"
+ prev = "M"
+ mx = x
+ my = y
+ goto continue
+ ::lineto::
+ n = n + 1 ; t[n] = x
+ n = n + 1 ; t[n] = y
+ prev = "L"
+ goto continue
+ ::curveto::
+ n = n + 1 ; t[n] = x
+ n = n + 1 ; t[n] = y
+ prev = "C"
+ goto continue
+ ::arc::
+ ac = a2c(x1,y1,rx,ry,ar,al,as,x,y)
+ for i=1,#ac,6 do
+ n = n + 1 ; t[n] = ac[i+4]
+ n = n + 1 ; t[n] = ac[i+5]
+ end
+ prev = "A"
+ goto continue
+ ::quadratic::
+ n = n + 1 ; t[n] = x2
+ n = n + 1 ; t[n] = y2
+ x = x2
+ y = y2
+ prev = "C"
+ goto continue
+ ::close::
+ n = n + 1 ; t[n] = mx
+ n = n + 1 ; t[n] = my
+ if i == np then
+ break
+ end
+ kind = prev
+ prev = "Z"
+ x = mx
+ y = my
+ ::continue::
+ end
+ return t
end
- all.curve = (kind == "C" or kind == "A")
- return all
+
end
-local transform do
+-- todo: viewbox helper
+
+local s_wrapped_start = "draw image ("
+local f_wrapped_stop = formatters[") shifted (0,%N) scaled %N ;"]
+
+local handletransform, handleviewbox do
--todo: better lpeg
- local n = 0
+ local f_rotatedaround = formatters[" rotatedaround((%N,%N),%N)"]
+ local f_rotated = formatters[" rotated(%N)"]
+ local f_shifted = formatters[" shifted(%N,%N)"]
+ local f_slanted_x = formatters[" xslanted(%N)"]
+ local f_slanted_y = formatters[" yslanted(%N)"]
+ local f_scaled = formatters[" scaled(%N)"]
+ local f_xyscaled = formatters[" xyscaled(%N,%N)"]
+ local f_matrix = formatters[" transformed bymatrix(%N,%N,%N,%N,%N,%N)"]
+
+ local s_transform_start = "draw image ( "
+ local f_transform_stop = formatters[")%s ;"]
local function rotate(r,x,y)
if x then
- n = n + 1
return r and f_rotatedaround(x,-(y or x),-r)
elseif r then
- n = n + 1
return f_rotated(-r)
else
return ""
@@ -852,10 +997,8 @@ local transform do
local function translate(x,y)
if y then
- n = n + 1
return f_shifted(x,-y)
elseif x then
- n = n + 1
return f_shifted(x,0)
else
return ""
@@ -864,10 +1007,8 @@ local transform do
local function scale(x,y)
if y then
- n = n + 1
return f_xyscaled(x,y)
elseif x then
- n = n + 1
return f_scaled(x)
else
return ""
@@ -876,7 +1017,6 @@ local transform do
local function skewx(x)
if x then
- n = n + 1
return f_slanted_x(math.sind(-x))
else
return ""
@@ -885,7 +1025,6 @@ local transform do
local function skewy(y)
if y then
- n = n + 1
return f_slanted_y(math.sind(-y))
else
return ""
@@ -893,7 +1032,6 @@ local transform do
end
local function matrix(rx,sx,sy,ry,tx,ty)
- n = n + 1
return f_matrix(rx or 1, sx or 0, sy or 0, ry or 1, tx or 0, - (ty or 0))
end
@@ -910,14 +1048,20 @@ local transform do
+ P(1)/""
)^1)
- transform = function(t,image)
- n = 0
- local e = lpegmatch(p_transform,t)
- local b = rep("( ",n)
- if image then
- return f_transform_start(b), f_transform_stop(e)
- else
- return b, e
+ 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
+ end
+ end
+
+ handleviewbox = function(v)
+ if v then
+ local x, y, w, h = lpegmatch(p_fournumbers,v)
+ if h then
+ return x, y, w, h
+ end
end
end
@@ -927,10 +1071,13 @@ local dashed do
-- actually commas are mandate but we're tolerant
- local p_number = p_separator^0/"" * p_number_r
- local p_on = Cc(" on ") * p_number
- local p_off = Cc(" off ") * p_number
- local p_dashed = Cs((p_on * p_off^-1)^1)
+ local f_dashed_n = formatters[" dashed dashpattern (%s ) "]
+ local f_dashed_y = formatters[" dashed dashpattern (%s ) shifted (%N,0) "]
+
+ local p_number = p_optseparator/"" * p_number_r
+ local p_on = Cc(" on ") * p_number
+ local p_off = Cc(" off ") * p_number
+ local p_dashed = Cs((p_on * p_off^-1)^1)
dashed = function(s,o)
if not find(s,",") then
@@ -944,108 +1091,274 @@ end
do
- local defaults = {
- x = 0, x1 = 0, x2 = 0, cx = 0, rx = 0,
- y = 0, y1 = 0, y2 = 0, cy = 0, ry = 0,
- r = 0,
-
- width = 0,
- height = 0,
-
- stroke = "none",
- fill = "black",
- opacity = "none",
-
- ["stroke-width"] = 1,
- ["stroke-linecap"] = "none",
- ["stroke-linejoin"] = "none",
- ["stroke-dasharray"] = "none",
- ["stroke-dashoffset"] = "none",
- ["stroke-miterlimit"] = "none",
- ["stroke-opacity"] = "none",
-
- ["fill-opacity"] = "none",
- -- ["fill-rule"] = "nonzero",
- -- ["clip-rule"] = "nonzero",
- }
-
local handlers = { }
local process = false
local root = false
local result = false
local r = false
local definitions = false
- local styles = false
- local bodyfont = false
+ local classstyles = false
+ local tagstyles = false
+
+ local tags = {
+ ["a"] = true,
+ -- ["altgGlyph"] = true,
+ -- ["altgGlyphDef"] = true,
+ -- ["altgGlyphItem"] = true,
+ -- ["animate"] = true,
+ -- ["animateColor"] = true,
+ -- ["animateMotion"] = true,
+ -- ["animateTransform"] = true,
+ ["circle"] = true,
+ ["clipPath"] = true,
+ -- ["color-profile"] = true,
+ -- ["cursor"] = true,
+ ["defs"] = true,
+ -- ["desc"] = true,
+ ["ellipse"] = true,
+ -- ["filter"] = true,
+ -- ["font"] = true,
+ -- ["font-face"] = true,
+ -- ["font-face-format"] = true,
+ -- ["font-face-name"] = true,
+ -- ["font-face-src"] = true,
+ -- ["font-face-uri"] = true,
+ -- ["foreignObject"] = true,
+ ["g"] = true,
+ -- ["glyph"] = true,
+ -- ["glyphRef"] = true,
+ -- ["hkern"] = true,
+ ["image"] = true,
+ ["line"] = true,
+ ["linearGradient"] = true,
+ ["marker"] = true,
+ -- ["mask"] = true,
+ -- ["metadata"] = true,
+ -- ["missing-glyph"] = true,
+ -- ["mpath"] = true,
+ ["path"] = true,
+ -- ["pattern"] = true,
+ ["polygon"] = true,
+ ["polyline"] = true,
+ ["radialGradient"] = true,
+ ["rect"] = true,
+ -- ["script"] = true,
+ -- ["set"] = true,
+ ["stop"] = true,
+ ["style"] = true,
+ ["svg"] = true,
+ -- ["switch"] = true,
+ ["symbol"] = true,
+ ["text"] = true,
+ -- ["textPath"] = true,
+ -- ["title"] = true,
+ ["tspan"] = true,
+ ["use"] = true,
+ -- ["view"] = true,
+ -- ["vkern"] = true,
+ }
- -- todo: check use ... and make definitions[id] self resolving
+ local function handlechains(c)
+ if tags[c.tg] then
+ local at = c.at
+ local dt = c.dt
+ if at and dt then
+ -- at["inkscape:connector-curvature"] = nil -- cleare entry and might prevent table growth
+ local estyle = rawget(at,"style")
+ if estyle and estyle ~= "" then
+ for k, v in gmatch(estyle,"%s*([^:]+):%s*([^;]+);?") do
+ at[k] = v
+ end
+ end
+ local eclass = rawget(at,"class")
+ if eclass and eclass ~= "" then
+ for c in gmatch(eclass,"[^ ]+") do
+ local s = classstyles[c]
+ if s then
+ for k, v in next, s do
+ at[k] = v
+ end
+ end
+ end
+ end
+ local tstyle = tagstyles[tag]
+ if tstyle then
+ for k, v in next, tstyle do
+ at[k] = v
+ end
+ end
+ if trace_path and pathtracer then
+ for k, v in next, pathtracer do
+ at[k] = v
+ end
+ end
+ for i=1,#dt do
+ local dti = dt[i]
+ if type(dti) == "table" then
+ handlechains(dti)
+ end
+ end
+ end
+ end
+ end
+
+ local handlestyle do
+
+ -- It can also be CDATA but that is probably dealt with because we only
+ -- check for style entries and ignore the rest. But maybe we also need
+ -- to check a style at the outer level?
+
+ local p_key = C((R("az","AZ","09","__","--")^1))
+ local p_spec = P("{") * C((1-P("}"))^1) * P("}")
+ local p_valid = Carg(1) * P(".") * p_key + Carg(2) * p_key
+ local p_grab = ((p_valid * p_space^0 * p_spec / rawset) + p_space^1 + P(1))^1
+
+ local fontspecification = css.fontspecification
+
+ handlestyle = function(c)
+ local s = xmltext(c)
+ lpegmatch(p_grab,s,1,classstyles,tagstyles)
+ for k, v in next, classstyles do
+ local t = { }
+ for k, v in gmatch(v,"%s*([^:]+):%s*([^;]+);?") do
+ if k == "font" then
+ local s = fontspecification(v)
+ for k, v in next, s do
+ t["font-"..k] = v
+ end
+ else
+ t[k] = v
+ end
+ end
+ classstyles[k] = t
+ end
+ for k, v in next, tagstyles do
+ local t = { }
+ for k, v in gmatch(v,"%s*([^:]+):%s*([^;]+);?") do
+ if k == "font" then
+ local s = fontspecification(v)
+ for k, v in next, s do
+ t["font-"..k] = v
+ end
+ else
+ t[k] = v
+ end
+ end
+ tagstyles[k] = t
+ end
+ end
+
+ function handlers.style()
+ -- ignore
+ end
+
+ end
+
+ -- We can have root in definitions and then do a metatable lookup but use
+ -- is not used that often I guess.
local function locate(id)
+ local res = definitions[id]
+ if res then
+ return res
+ end
local ref = gsub(id,"^url%(#(.-)%)$","%1")
local ref = gsub(ref,"^#","")
+ -- we can make a fast id lookup
local res = xmlfirst(root,"**[@id='"..ref.."']")
if res then
definitions[id] = res
- return res
- else
- -- warning
end
+ return res
end
- local function clippath(id,a)
- local spec = definitions[id] or locate(id)
- if spec then
- local kind = spec.tg
- if kind == "clipPath" then
- ::again::
- for c in xmlcollected(spec,"/(path|use|g)") do
- local tg = c.tg
- if tg == "use" then
- local ca = c.at
- local id = ca["xlink:href"]
- if id then
- spec = locate(id)
- if spec then
- local sa = spec.at
- setmetatableindex(sa,ca)
- if spec.tg == "path" then
- local d = sa.d
- if d then
- local p = grabpath(d)
- p.evenodd = sa["clip-rule"] == "evenodd" or a["clip-rule"] == "evenodd"
- return p
- else
- goto done
- end
- else
- goto again
- end
+ -- also locate
+
+ local function handleclippath(at)
+ local clippath = at["clip-path"]
+
+ if not clippath then
+ return
+ end
+
+ local spec = definitions[clippath] or locate(clippath)
+
+ -- do we really need thsi crap
+ if not spec then
+ local index = match(clippath,"(%d+)")
+ if index then
+ spec = xmlfirst(root,"clipPath["..tostring(tonumber(index) or 0).."]")
+ end
+ end
+ -- so far for the crap
+
+ if not spec then
+ report("unknown clip %a",clippath)
+ return
+ elseif spec.tg ~= "clipPath" then
+ report("bad clip %a",clippath)
+ return
+ end
+
+ ::again::
+ for c in xmlcollected(spec,"/(path|use|g)") do
+ local tg = c.tg
+ if tg == "use" then
+ local ca = c.at
+ local id = ca["xlink:href"]
+ if id then
+ spec = locate(id)
+ if spec then
+ local sa = spec.at
+ setmetatableindex(sa,ca)
+ if spec.tg == "path" then
+ local d = sa.d
+ if d then
+ local p = grabpath(d)
+ p.evenodd = sa["clip-rule"] == "evenodd"
+ p.close = true
+ return p, clippath
+ else
+ return
end
- end
- -- break
- elseif tg == "path" then
- local ca = c.at
- local d = ca.d
- if d then
- local p = grabpath(d)
- p.evenodd = ca["clip-rule"] == "evenodd" or a["clip-rule"] == "evenodd"
- return p
else
- goto done
+ goto again
end
- else
- -- inherit?
end
end
- ::done::
+ -- break
+ elseif tg == "path" then
+ local ca = c.at
+ local d = ca.d
+ if d then
+ local p = grabpath(d)
+ p.evenodd = ca["clip-rule"] == "evenodd"
+ p.close = true
+ return p, clippath
+ else
+ return
+ end
else
- report("unknown clip %a",id)
+ -- inherit?
end
end
end
+ local s_shade_linear = ' withshademethod "linear" '
+ local s_shade_circular = ' withshademethod "circular" '
+ local f_shade_step = formatters['withshadestep ( withshadefraction %N withshadecolors(%s,%s) )']
+ local f_shade_one = formatters['withprescript "sh_center_a=%N %N"']
+ local f_shade_two = formatters['withprescript "sh_center_b=%N %N"']
+
+ local f_color = formatters['withcolor "%s"']
+ local f_opacity = formatters['withtransparency (1,%N)']
+ local f_pen = formatters['withpen pencircle scaled %N']
+
+ -- todo: gradient unfinished
+ -- todo: opacity but first we need groups in mp
+
local function gradient(id)
- local spec = definitions[id]
+ local spec = definitions[id] -- no locate !
if spec then
local kind = spec.tg
local shade = nil
@@ -1054,25 +1367,25 @@ do
if kind == "linearGradient" then
shade = { s_shade_linear }
--
- local x1 = a.x1
- local y1 = a.y1
- local x2 = a.x2
- local y2 = a.y2
+ local x1 = rawget(a,"x1")
+ local y1 = rawget(a,"y1")
+ local x2 = rawget(a,"x2")
+ local y2 = rawget(a,"y2")
if x1 and y1 then
- n = n + 1 shade[n] = f_shade_one(asnumber_vx(x1),asnumber_vy(y1))
+ n = n + 1 ; shade[n] = f_shade_one(asnumber_vx(x1),asnumber_vy(y1))
end
if x2 and y2 then
- n = n + 1 shade[n] = f_shade_one(asnumber_vx(x2),asnumber_vy(y2))
+ n = n + 1 ; shade[n] = f_shade_one(asnumber_vx(x2),asnumber_vy(y2))
end
--
elseif kind == "radialGradient" then
shade = { s_shade_circular }
--
- local cx = a.cx -- x center
- local cy = a.cy -- y center
- local r = a.r -- radius
- local fx = a.fx -- focal points
- local fy = a.fy -- focal points
+ local cx = rawget(a,"cx") -- x center
+ local cy = rawget(a,"cy") -- y center
+ local r = rawget(a,"r" ) -- radius
+ local fx = rawget(a,"fx") -- focal points
+ local fy = rawget(a,"fy") -- focal points
--
if cx and cy then
-- todo
@@ -1091,566 +1404,1328 @@ do
-- local gt = a.gradientTransform
-- local sm = a.spreadMethod
local colora, colorb
+ -- startcolor ?
for c in xmlcollected(spec,"/stop") do
local a = c.at
- local offset = a.offset
- local colorb = a["stop-color"]
- local opacity = a["stop-opacity"]
-
- colorb = colorb and (hexcolor3(colorb) or svgcolor[colorb] or colorb)
- colora = colora or colorb
-
+ local offset = rawget(a,"offset")
+ local colorb = rawget(a,"stop-color")
+ local opacity = rawget(a,"stop-opacity")
+ if colorb then
+ colorb = thecolor(colorb)
+ end
+ if not colora then
+ colora = colorb
+ end
-- what if no percentage
local fraction = offset and asnumber_r(offset)
-
if not fraction then
-- offset = tonumber(offset)
-- for now
fraction = xmlcount(spec,"/stop")/100
end
- n = n + 1 shade[n] = f_shade_step(fraction,colora,colorb)
+ if colora and colorb and color_a ~= "" and color_b ~= "" then
+ n = n + 1 ; shade[n] = f_shade_step(fraction,colora,colorb)
+ end
- prevcolor = color
+ colora = colorb
end
- return concat(shade)
+ return concat(shade," ")
end
end
- local function drawproperties(stroke,a)
- local w = a["stroke-width"]
- if w then
- w = f_pen(asnumber_r(w))
- else
- w = ""
- end
- local d = a["stroke-dasharray"]
- if d ~= "none" then
- local o = a["stroke-dashoffset"]
- if o ~= "none" then
+ local function drawproperties(stroke,at,opacity)
+ local p = at["stroke-width"]
+ if p then
+ p = f_pen(asnumber_r(p))
+ end
+ local d = at["stroke-dasharray"]
+ if d == "none" then
+ d = nil
+ elseif d then
+ local o = at["stroke-dashoffset"]
+ if o and o ~= "none" then
o = asnumber_r(o)
else
o = false
end
d = dashed(d,o)
- else
- d = ""
- end
- local c = hexcolor(stroke)
- if not c then
- c = rgbacolor(stroke)
- if not c then
- c = f_color(svgcolor[stroke] or stroke)
- end
end
- local o = a["stroke-opacity"] or a.opacity
- if o ~= "none" then
+ local c = withcolor(stroke)
+ local o = at["stroke-opacity"] or (opacity and at["opacity"])
+ if o == "none" then
+ o = nil
+ elseif o then
o = asnumber_r(o)
if o and o ~= 1 then
o = f_opacity(o)
else
- o = ""
+ o = nil
end
- else
- o = ""
end
- return w, d, c, o
+ return p, d, c, o
end
- local function fillproperties(fill,a)
- local c = gradient(fill)
- if not c then
- c = hexcolor(fill)
- if not c then
- c = f_color(svgcolor[fill] or fill)
+ local s_opacity_start = "draw image ("
+ local f_opacity_stop = formatters["setgroup currentpicture to boundingbox currentpicture withtransparency (1,%N)) ;"]
+
+ local function sharedopacity(at)
+ local o = at["opacity"]
+ if o and o ~= "none" then
+ o = asnumber_r(o)
+ if o and o ~= 1 then
+ return s_opacity_start, f_opacity_stop(o)
end
end
- local o = a["fill-opacity"] or a.opacity
- if o == "none" then
+ end
+
+ local function fillproperties(fill,at,opacity)
+ local c = c ~= "none" and (gradient(fill) or withcolor(fill)) or nil
+ local o = at["fill-opacity"] or (opacity and at["opacity"])
+ if o and o ~= "none" then
o = asnumber_r(o)
- if o and o ~= 1 then
- o = f_opacity(asnumber_r(o))
- else
- o = ""
+ if o == 1 then
+ return c
+ elseif o then
+ return c, f_opacity(o), o == 0
end
- else
- o = ""
end
- return c, o
+ return c
end
-- todo: clip = [ auto | rect(llx,lly,urx,ury) ]
- local function offset(a)
- local x = a.x
- local y = a.y
- if x then x = asnumber_vx(x) end
- if y then y = asnumber_vy(y) end
- if not x then x = 0 end
- if not y then y = 0 end
+ local s_offset_start = "draw image ( "
+ local f_offset_stop = formatters[") shifted (%N,%N) ;"]
+ local s_rotation_start = "draw image ( "
+ local f_rotation_stop = formatters[") rotatedaround((0,0),-angle((%N,%N))) ;"]
+ local f_rotation_angle = formatters[") rotatedaround((0,0),-%N) ;"]
+
+ local function offset(at)
+ local x = asnumber_vx(rawget(at,"x"))
+ local y = asnumber_vy(rawget(at,"y"))
if x ~= 0 or y ~= 0 then
- r = r + 1 ; result[r] = s_offset_start
- return function()
- r = r + 1 ; result[r] = f_offset_stop(x,-y)
- end
+ return s_offset_start, f_offset_stop(x,y)
end
end
- local function viewport(x,y,w,h,noclip)
- r = r + 1 ; result[r] = f_viewport_start
+ local s_viewport_start = "draw image ("
+ local s_viewport_stop = ") ;"
+ local f_viewport_shift = formatters["currentpicture := currentpicture shifted (%03N,%03N);"]
+ local f_viewport_scale = formatters["currentpicture := currentpicture xysized (%03N,%03N);"]
+ local f_viewport_clip = formatters["clip currentpicture to (unitsquare xyscaled (%03N,%03N));"]
+
+ local function viewport(x,y,w,h,noclip,scale)
+ r = r + 1 ; result[r] = s_viewport_start
return function()
+ local okay = w ~= 0 and h ~= 0
+ if okay and scale then
+ r = r + 1 ; result[r] = f_viewport_scale(w,h)
+ end
if x ~= 0 or y ~= 0 then
r = r + 1 ; result[r] = f_viewport_shift(-x,y)
end
- if not noclip then
+ if okay and not noclip then
r = r + 1 ; result[r] = f_viewport_clip(w,-h)
end
- r = r + 1 ; result[r] = f_viewport_stop
+
+ r = r + 1 ; result[r] = s_viewport_stop
end
end
- function handlers.defs(c,top)
+ -- maybe forget about defs and just always locate (and then backtrack
+ -- over <g> if needed)
+
+ function handlers.defs(c)
for c in xmlcollected(c,"/*") do
- local a = c.at
- local id = a.id
- -- setmetatableindex(a,top)
- if id then
- definitions["#" .. id ] = c
- definitions["url(#" .. id .. ")"] = c
+ local a = c.at
+ if a then
+ local id = rawget(a,"id")
+ if id then
+ definitions["#" .. id ] = c
+ definitions["url(#" .. id .. ")"] = c
+ end
end
end
end
- function handlers.use(c,top)
- local a = setmetatableindex(c.at,top)
- local id = a["xlink:href"] -- better a rawget
- if id then
- local d = definitions[id]
- if d then
- local h = handlers[d.tg]
- if h then
- h(d,a)
- end
- else
- local res = locate(id)
- if res then
- local wrapup = offset(a)
- process(res,"/*",top)
- if wrapup then
- wrapup()
- end
- else
- report("unknown definition %a",id)
- end
+ function handlers.symbol(c)
+ if uselevel == 0 then
+ local id = rawget(c.at,"id")
+ if id then
+ definitions["#" .. id ] = c
+ definitions["url(#" .. id .. ")"] = c
end
+ else
+ handlers.g(c)
end
end
- local linecaps = { butt = "butt", square = "squared", round = "rounded" }
- local linejoins = { miter = "mitered", bevel = "beveled", round = "rounded" }
+ local uselevel = 0
- local function stoplineproperties()
- r = r + 1 result[r] = s_endgroup
- end
+ function handlers.use(c)
+ local at = c.at
+ local id = rawget(at,"href") or rawget(at,"xlink:href") -- better a rawget
+ local res = locate(id)
+ if res then
+ -- width height ?
+ uselevel = uselevel + 1
+ local boffset, eoffset = offset(at)
+ local btransform, etransform, transform = handletransform(at)
- local function startlineproperties(a)
- local cap = a["stroke-linecap"]
- local join = a["stroke-linejoin"]
- local limit = a["stroke-miterlimit"]
- cap = cap ~= "none" and linecaps [cap] or false
- join = join ~= "none" and linejoins[join] or false
- limit = limit ~= "none" and asnumber_r(limit) or false
- if cap or join or limit then
- r = r + 1 result[r] = s_begingroup
- if cap then
- r = r + 1 result[r] = f_linecap(cap)
+ if boffset then
+ r = r + 1 result[r] = boffset
end
- if join then
- r = r + 1 result[r] = f_linejoin(join)
+
+ -- local clippath = at.clippath
+
+ if btransform then
+ r = r + 1 result[r] = btransform
+ end
+
+ local _transform = transform
+ local _clippath = clippath
+ at["transform"] = false
+ -- at["clip-path"] = false
+
+ process(res,"/*")
+
+ at["transform"] = _transform
+ -- at["clip-path"] = _clippath
+
+ if etransform then
+ r = r + 1 ; result[r] = etransform
end
- if limit then
- r = r + 1 result[r] = f_miterlimit(limit)
+
+ if eoffset then
+ r = r + 1 result[r] = eoffset
end
- return stoplineproperties
+
+ uselevel = uselevel - 1
+ else
+ report("use: unknown definition %a",id)
end
end
- local function flush(a,shape,nofill)
- local fill = not nofill and a.fill
- local stroke = a.stroke
- local cpath = a["clip-path"]
- local trans = a.transform
- local b, e = "", ""
+ local f_no_draw = formatters['nodraw (%s)']
+ local f_do_draw = formatters['draw (%s)']
+ local f_no_fill_c = formatters['nofill (%s..cycle)']
+ local f_do_fill_c = formatters['fill (%s..cycle)']
+ local f_eo_fill_c = formatters['eofill (%s..cycle)']
+ local f_no_fill_l = formatters['nofill (%s--cycle)']
+ local f_do_fill_l = formatters['fill (%s--cycle)']
+ local f_eo_fill_l = formatters['eofill (%s--cycle)']
+ local f_do_fill = f_do_fill_c
+ local f_eo_fill = f_eo_fill_c
+ local f_no_fill = f_no_fill_c
+ local s_clip_start = 'draw image ('
+ local f_clip_stop_c = formatters[') ; clip currentpicture to (%s..cycle) ;']
+ local f_clip_stop_l = formatters[') ; clip currentpicture to (%s--cycle) ;']
+ local f_clip_stop = f_clip_stop_c
+ local f_eoclip_stop_c = formatters[') ; eoclip currentpicture to (%s..cycle) ;']
+ local f_eoclip_stop_l = formatters[') ; eoclip currentpicture to (%s--cycle) ;']
+ local f_eoclip_stop = f_eoclip_stop_c
+
+ -- could be shared and then beginobject | endobject
+
+ local function flushobject(object,at,c,o)
+ local btransform, etransform = handletransform(at)
+ local cpath = handleclippath(at)
+
if cpath then
- cpath = clippath(cpath,a)
+ r = r + 1 ; result[r] = s_clip_start
end
- if cpath then
- r = r + 1 result[r] = s_clip_start
+
+ if btransform then
+ r = r + 1 ; result[r] = btransform
end
- if trans then
- b, e = transform(trans)
+
+ r = r + 1 ; result[r] = f_do_draw(object)
+
+ if c then
+ r = r + 1 ; result[r] = c
end
- if fill and fill ~= "none" then
- r = r + 1 result[r] = (a["fill-rule"] == "evenodd" and f_eofill or f_fill)(b,shape,e,fillproperties(fill,a))
+
+ if o then
+ r = r + 1 ; result[r] = o
end
- if stroke and stroke ~= "none" and stroke ~= 0 then
- local wrapup = startlineproperties(a)
- r = r + 1 result[r] = f_draw(b,shape,e,drawproperties(stroke,a))
- if wrapup then
- wrapup()
- end
+
+ if etransform then
+ r = r + 1 ; result[r] = etransform
end
+
+ r = r + 1 ; result[r] = ";"
+
if cpath then
- r = r + 1 result[r] = (cpath.evenodd and f_eoclip_stop or f_clip_stop)(cpath[1])
+ local f_done = cpath.evenodd
+ if cpath.curve then
+ f_done = f_done and f_eoclip_stop_c or f_clip_stop_c
+ else
+ f_done = f_done and f_eoclip_stop_l or f_clip_stop_l
+ end
+ r = r + 1 ; result[r] = f_done(cpath[1])
end
end
- -- todo: strokes in:
+ do
- local function flushpath(a,shape)
- local fill = a.fill
- local stroke = a.stroke
- local cpath = a["clip-path"]
- local trans = a.transform
- local b, e = "", ""
- if cpath then
- cpath = definitions[cpath]
- end
- if cpath then
- r = r + 1 result[r] = s_clip_start
- end
- -- todo: image (nicer for transform too)
- if trans then
- b, e = transform(trans)
- end
- if fill and fill ~= "none" then
- local n = #shape
- for i=1,n do
- r = r + 1
- if i == n then
- local f = a["fill-rule"] == "evenodd"
- if shape.closed then
- f = f and f_eofill or f_fill
- elseif shape.curve then
- f = f and f_eofill_cycle_c or f_fill_cycle_c
- else
- f = f and f_eofill_cycle_l or f_fill_cycle_l
- end
- result[r] = f(b,shape[i],e,fillproperties(fill,a))
- else
- result[r] = f_nofill(b,shape[i],e)
+ local flush
+
+ local f_linecap = formatters["interim linecap := %s ;"]
+ local f_linejoin = formatters["interim linejoin := %s ;"]
+ local f_miterlimit = formatters["interim miterlimit := %s ;"]
+
+ local s_begingroup = "begingroup;"
+ local s_endgroup = "endgroup;"
+
+ local linecaps = { butt = "butt", square = "squared", round = "rounded" }
+ local linejoins = { miter = "mitered", bevel = "beveled", round = "rounded" }
+
+ local function startlineproperties(at)
+ local cap = at["stroke-linecap"]
+ local join = at["stroke-linejoin"]
+ local limit = at["stroke-miterlimit"]
+ cap = cap and linecaps [cap]
+ join = join and linejoins[join]
+ limit = limit and asnumber_r(limit)
+ if cap or join or limit then
+ r = r + 1 ; result[r] = s_begingroup
+ if cap then
+ r = r + 1 ; result[r] = f_linecap(cap)
+ end
+ if join then
+ r = r + 1 ; result[r] = f_linejoin(join)
+ end
+ if limit then
+ r = r + 1 ; result[r] = f_miterlimit(limit)
+ end
+ return function()
+ at["stroke-linecap"] = false
+ at["stroke-linejoin"] = false
+ at["stroke-miterlimit"] = false
+ r = r + 1 ; result[r] = s_endgroup
+ at["stroke-linecap"] = cap
+ at["stroke-linejoin"] = join
+ at["stroke-miterlimit"] = limit
end
end
end
- if stroke and stroke ~= "none" and stroke ~= 0 then
- local wrapup = startlineproperties(a)
- local n = #shape
- for i=1,n do
- r = r + 1
- if i == n then
- result[r] = f_draw(b,shape[i],e,drawproperties(stroke,a))
+
+ -- markers are a quite rediculous thing .. let's assume simple usage for now
+
+ function handlers.marker()
+ -- todo: is just a def too
+ end
+
+ -- kind of local svg ... so make a generic one
+ --
+ -- todo: combine more (offset+scale+rotation)
+
+ local function makemarker(where,c,x1,y1,x2,y2,x3,y3)
+ local at = c.at
+ local refx = rawget(at,"refX")
+ local refy = rawget(at,"refY")
+ local width = rawget(at,"markerWidth")
+ local height = rawget(at,"markerHeight")
+ local view = rawget(at,"viewBox")
+ local orient = rawget(at,"orient")
+ -- local ratio = rawget(at,"preserveAspectRatio")
+ local units = at["markerUnits"]
+ local height = at["markerHeight"]
+ local angx = 0
+ local angy = 0
+ local angle = 0
+
+ if where == "beg" then
+ if orient == "auto" then -- unchecked
+ -- no angle
+ angx = x2 - x3
+ angy = y2 - y3
+ elseif orient == "auto-start-reverse" then -- checked
+ -- points to start
+ angx = x3 - x2
+ angy = y3 - y2
+ elseif orient then -- unchecked
+ angle = asnumber_r(orient)
+ end
+ elseif where == "end" then
+ if orient == "auto" then -- unchecked
+ -- no angle ?
+ angx = x1 - x2
+ angy = y1 - y2
+ elseif orient == "auto-start-reverse" then -- unchecked
+ -- points to end
+ angx = x2 - x1
+ angy = y2 - y1
+ elseif orient then -- unchecked
+ angle = asnumber_r(orient)
+ end
+ elseif orient then -- unchecked
+ angle = asnumber_r(orient)
+ end
+
+ -- what wins: viewbox or w/h
+
+ refx = asnumber_x(refx)
+ refy = asnumber_y(refy)
+
+ width = width and asnumber_x(width) or 3 -- defaults
+ height = height and asnumber_y(height) or 3 -- defaults
+
+ local x = 0
+ local y = 0
+ local w = width
+ local h = height
+
+ -- kind of like the main svg
+
+ r = r + 1 ; result[r] = s_offset_start
+
+ local wrapupviewport
+-- todo : better viewbox code
+ local xpct, ypct, rpct
+ if view then
+ x, y, w, h = handleviewbox(view)
+ end
+
+ if width ~= 0 then
+ w = width
+ end
+ if height ~= 0 then
+ h = height
+ end
+
+ if h then
+ xpct = percentage_x
+ ypct = percentage_y
+ rpct = percentage_r
+ percentage_x = w / 100
+ percentage_y = h / 100
+ percentage_r = (sqrt(w^2 + h^2) / sqrt(2)) / 100
+ wrapupviewport = viewport(x,y,w,h,true,true) -- no clip
+ end
+
+ -- we can combine a lot here:
+
+ local hasref = refx ~= 0 or refy ~= 0
+ local hasrot = angx ~= 0 or angy ~= 0 or angle ~= 0
+
+ local btransform, etransform, transform = handletransform(at)
+
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+
+ if hasrot then
+ r = r + 1 ; result[r] = s_rotation_start
+ end
+
+ if hasref then
+ r = r + 1 ; result[r] = s_offset_start
+ end
+
+ local _transform = transform
+ at["transform"] = false
+
+ handlers.g(c)
+
+ at["transform"] = _transform
+
+ if hasref then
+ r = r + 1 ; result[r] = f_offset_stop(-refx,refy)
+ end
+
+ if hasrot then
+ if angle ~= 0 then
+ r = r + 1 ; result[r] = f_rotation_angle(angle)
else
- result[r] = f_nodraw(b,shape[i],e)
+ r = r + 1 ; result[r] = f_rotation_stop(angx,angy)
end
end
- if wrapup then
- wrapup()
+
+ if etransform then
+ r = r + 1 ; result[r] = etransform
end
+
+ if h then
+ percentage_x = xpct
+ percentage_y = ypct
+ percentage_r = rpct
+ if wrapupviewport then
+ wrapupviewport()
+ end
+ end
+ r = r + 1 ; result[r] = f_offset_stop(x2,y2)
+
end
- if cpath then
- r = r + 1 result[r] = f_clip_stop(cpath[1])
- end
- end
- function handlers.line(c,top)
- local a = setmetatableindex(c.at,top)
- local x1 = asnumber_vx(a.x1)
- local y1 = asnumber_vy(a.y1)
- local x2 = asnumber_vx(a.x2)
- local y2 = asnumber_vy(a.y2)
- if trace then
- report("line: x1 %.3N, y1 %.3N, x2 %.3N, x3 %.3N",x1,y1,x2,y2)
+ local function addmarkers(list,begmarker,midmarker,endmarker)
+ local n = #list
+ if n > 3 then
+ if begmarker then
+ local m = locate(begmarker)
+ if m then
+ makemarker("beg",m,false,false,list[1],list[2],list[3],list[4])
+ end
+ end
+ if midmarker then
+ local m = locate(midmarker)
+ if m then
+ for i=3,n-2,2 do
+ makemarker("mid",m,list[i-2],list[i-1],list[i],list[i+1],list[i+2],list[i+3])
+ end
+ end
+ end
+ if endmarker then
+ local m = locate(endmarker)
+ if m then
+ makemarker("end",m,list[n-3],list[n-2],list[n-1],list[n],false,false)
+ end
+ end
+ else
+ -- no line
+ end
end
- flush(a,f_line(x1,y1,x2,y2),true)
- end
- function handlers.rect(c,top)
- local a = setmetatableindex(c.at,top)
- local w = asnumber_x(a.width)
- local h = asnumber_y(a.height)
- local x = asnumber_vx(a.x)
- local y = asnumber_vy(a.y) - h
- local rx = a.rx
- local ry = a.ry
- if rx == 0 then rx = false end -- maybe no default 0
- if ry == 0 then ry = false end -- maybe no default 0
- if rx or ry then
- rx = asnumber_x(rx or ry)
- ry = asnumber_y(ry or rx)
- if trace then
- report("rect: x %.3N, y %.3N, w %.3N, h %.3N, rx %.3N, ry %.3N",x,y,w,h,rx,ry)
+ local function flush(shape,dofill,at,list,begmarker,midmarker,endmarker)
+
+ local fill = dofill and (at["fill"] or "black")
+ local stroke = at["stroke"] or "none"
+
+ local btransform, etransform = handletransform(at)
+ local cpath = handleclippath(at)
+
+ if cpath then
+ r = r + 1 ; result[r] = s_clip_start
end
- flush(a,f_rounded(w,h,rx,ry,x,y))
- else
- if trace then
- report("rect: x %.3N, y %.3N, w %.3N, h %.3N",x,y,w,h)
+
+ local has_stroke = stroke and stroke ~= "none"
+ local has_fill = fill and fill ~= "none"
+
+ local bopacity, eopacity
+ if has_stroke and has_fill then
+ bopacity, eopacity = sharedopacity(at)
+ end
+
+ if bopacity then
+ r = r + 1 ; result[r] = bopacity
+ end
+
+ if has_fill then
+ local color, opacity = fillproperties(fill,at,not has_stroke)
+ local f_xx_fill = at["fill-rule"] == "evenodd" and f_eo_fill or f_do_fill
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+ r = r + 1 result[r] = f_xx_fill(shape)
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ r = r + 1 ; result[r] = etransform or ";"
+ end
+
+ if has_stroke then
+ local wrapup = startlineproperties(at)
+ local pen, dashing, color, opacity = drawproperties(stroke,at,not has_fill)
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+ r = r + 1 ; result[r] = f_do_draw(shape)
+ if pen then
+ r = r + 1 ; result[r] = pen
+ end
+ if dashing then
+ r = r + 1 ; result[r] = dashing
+ end
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ r = r + 1 ; result[r] = etransform or ";"
+ --
+ if list then
+ addmarkers(list,begmarker,midmarker,endmarker)
+ end
+ --
+ if wrapup then
+ wrapup()
+ end
+ end
+
+ if eopacity then
+ r = r + 1 ; result[r] = eopacity
+ end
+
+ if cpath then
+ r = r + 1 ; result[r] = (cpath.evenodd and f_eoclip_stop or f_clip_stop)(cpath[1])
end
- flush(a,f_rectangle(w,h,x,y))
- end
- end
- function handlers.ellipse(c,top)
- local a = setmetatableindex(c.at,top)
- local x = asnumber_vx(a.cx)
- local y = asnumber_vy(a.cy)
- local rx = asnumber_x (a.rx)
- local ry = asnumber_y (a.ry)
- if trace then
- report("ellipse: x %.3N, y %.3N, rx %.3N, ry %.3N",x,y,rx,ry)
end
- flush(a,f_ellipse(2*rx,2*ry,x,y))
- end
- function handlers.circle(c,top)
- local a = setmetatableindex(c.at,top)
- local x = asnumber_vx(a.cx)
- local y = asnumber_vy(a.cy)
- local r = asnumber_r (a.r)
- if trace then
- report("circle: x %.3N, y %.3N, r %.3N",x,y,r)
+ local f_rectangle = formatters['unitsquare xyscaled (%N,%N) shifted (%N,%N)']
+ local f_rounded = formatters['roundedsquarexy(%N,%N,%N,%N) shifted (%N,%N)']
+ local f_line = formatters['((%N,%N)--(%N,%N))']
+ local f_ellipse = formatters['(fullcircle xyscaled (%N,%N) shifted (%N,%N))']
+ local f_circle = formatters['(fullcircle scaled %N shifted (%N,%N))']
+
+ function handlers.line(c)
+ local at = c.at
+ local x1 = rawget(at,"x1")
+ local y1 = rawget(at,"y1")
+ local x2 = rawget(at,"x2")
+ local y2 = rawget(at,"y2")
+
+ x1 = x1 and asnumber_vx(x1) or 0
+ y1 = y1 and asnumber_vy(y1) or 0
+ x2 = x2 and asnumber_vx(x2) or 0
+ y2 = y2 and asnumber_vy(y2) or 0
+
+ flush(f_line(x1,y1,x2,y2),false,at)
end
- flush(a,f_circle(2*r,x,y))
- end
- function handlers.path(c,top)
- local a = setmetatableindex(c.at,top)
- local d = a.d
- if d then
- local p = grabpath(d)
- if trace then
- report("path: %i entries, %sclosed",p.entries,p.closed and "" or "not ")
+ function handlers.rect(c)
+ local at = c.at
+ local width = rawget(at,"width")
+ local height = rawget(at,"height")
+ local x = rawget(at,"x")
+ local y = rawget(at,"y")
+ local rx = rawget(at,"rx")
+ local ry = rawget(at,"ry")
+
+ width = width and asnumber_x(width) or 0
+ height = height and asnumber_y(height) or 0
+ x = x and asnumber_vx(x) or 0
+ y = y and asnumber_vy(y) or 0
+
+ y = y - height
+
+ if rx then rx = asnumber(rx) end
+ if ry then ry = asnumber(ry) end
+
+ if rx or ry then
+ if not rx then rx = ry end
+ if not ry then ry = rx end
+ flush(f_rounded(width,height,rx,ry,x,y),true,at)
+ else
+ flush(f_rectangle(width,height,x,y),true,at)
end
- flushpath(a,p)
end
- end
- do
+ function handlers.ellipse(c)
+ local at = c.at
+ local cx = rawget(at,"cx")
+ local cy = rawget(at,"cy")
+ local rx = rawget(at,"rx")
+ local ry = rawget(at,"ry")
+
+ cx = cx and asnumber_vx(cx) or 0
+ cy = cy and asnumber_vy(cy) or 0
+ rx = rx and asnumber_r (rx) or 0
+ ry = ry and asnumber_r (ry) or 0
- local p_pair = p_separator^0 * p_number_vx * p_separator^0 * p_number_vy
- local p_pair_z = p_pair / f_lineto_z
- local p_pair_n = p_pair / f_lineto_n
+ flush(f_ellipse(2*rx,2*ry,cx,cy),true,at)
+ end
+
+ function handlers.circle(c)
+ local at = c.at
+ local cx = rawget(at,"cx")
+ local cy = rawget(at,"cy")
+ local r = rawget(at,"r")
+
+ cx = cx and asnumber_vx(cx) or 0
+ cy = cy and asnumber_vy(cy) or 0
+ r = r and asnumber_r (r) or 0
+
+ flush(f_circle(2*r,cx,cy),true,at)
+ end
+
+ local f_lineto_z = formatters['(%N,%N)']
+ local f_lineto_n = formatters['--(%N,%N)']
+
+ local p_pair = p_optseparator * p_number_vx * p_optseparator * p_number_vy
local p_open = Cc("(")
local p_close = Carg(1) * P(true) / function(s) return s end
- local p_polyline = Cs(p_open * p_pair_z * p_pair_n^0 * p_close)
-
- function handlers.polyline(c,top)
- local a = setmetatableindex(c.at,top)
- local p = a.points
- if p then
- flush(a,lpegmatch(p_polyline,p,1,")"),true)
+ local p_polyline = Cs(p_open * (p_pair / f_lineto_z) * (p_pair / f_lineto_n)^0 * p_close)
+ local p_polypair = Ct(p_pair^0)
+
+ local function poly(c,final)
+ local at = c.at
+ local points = rawget(at,"points")
+ if points then
+ local path = lpegmatch(p_polyline,points,1,final)
+ local list = nil
+ local begmarker = rawget(at,"marker-start")
+ local midmarker = rawget(at,"marker-mid")
+ local endmarker = rawget(at,"marker-end")
+ if begmarker or midmarker or endmarker then
+ list = lpegmatch(p_polypair,points)
+ end
+ flush(path,true,at,list,begmarker,midmarker,endmarker)
end
end
- function handlers.polygon(c,top)
- local a = setmetatableindex(c.at,top)
- local p = a.points
- if p then
- flush(a,lpegmatch(p_polyline,p,1,"--cycle)"))
+ function handlers.polyline(c) poly(c, ")") end
+ function handlers.polygon (c) poly(c,"--cycle)") end
+
+ local s_image_start = "draw image ("
+ local s_image_stop = ") ;"
+
+ function handlers.path(c)
+ local at = c.at
+ local d = rawget(at,"d")
+ if d then
+ local shape, l = grabpath(d)
+ local fill = at["fill"] or "black"
+ local stroke = at["stroke"] or "none"
+ local n = #shape
+
+ local btransform, etransform = handletransform(at)
+ local cpath = handleclippath(at)
+
+ if cpath then
+ r = r + 1 ; result[r] = s_clip_start
+ end
+
+ -- todo: image (nicer for transform too)
+
+ if fill and fill ~= "none" then
+ local color, opacity = fillproperties(fill,at)
+ local f_xx_fill = at["fill-rule"] == "evenodd"
+ if shape.closed then
+ f_xx_fill = f_xx_fill and f_eo_fill or f_do_fill
+ elseif shape.curve then
+ f_xx_fill = f_xx_fill and f_eo_fill_c or f_do_fill_c
+ else
+ f_xx_fill = f_xx_fill and f_eo_fill_l or f_do_fill_l
+ end
+ if n == 1 then
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+ r = r + 1 result[r] = f_xx_fill(shape[1])
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ r = r + 1 ; result[r] = etransform or ";"
+ else
+ r = r + 1 ; result[r] = btransform or s_image_start
+ for i=1,n do
+ if i == n then
+ r = r + 1 ; result[r] = f_xx_fill(shape[i])
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ else
+ r = r + 1 ; result[r] = f_no_fill(shape[i])
+ end
+ r = r + 1 ; result[r] = ";"
+ end
+ r = r + 1 ; result[r] = etransform or s_image_stop
+ end
+ end
+
+ if stroke and stroke ~= "none" then
+ local begmarker = rawget(at,"marker-start")
+ local midmarker = rawget(at,"marker-mid")
+ local endmarker = rawget(at,"marker-end")
+ if begmarker or midmarker or endmarker then
+ list = grablist(l)
+ end
+ local wrapup = startlineproperties(at)
+ local pen, dashing, color, opacity = drawproperties(stroke,at)
+ if n == 1 and not list then
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+ r = r + 1 result[r] = f_do_draw(shape[1])
+ if pen then
+ r = r + 1 ; result[r] = pen
+ end
+ if dashing then
+ r = r + 1 ; result[r] = dashing
+ end
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ r = r + 1 result[r] = etransform or ";"
+ else
+ r = r + 1 result[r] = btransform or "draw image ("
+ for i=1,n do
+ r = r + 1 result[r] = f_do_draw(shape[i])
+ if pen then
+ r = r + 1 ; result[r] = pen
+ end
+ if dashing then
+ r = r + 1 ; result[r] = dashing
+ end
+ if color then
+ r = r + 1 ; result[r] = color
+ end
+ if opacity then
+ r = r + 1 ; result[r] = opacity
+ end
+ r = r + 1 ; result[r] = ";"
+ end
+ if list then
+ addmarkers(list,begmarker,midmarker,endmarker)
+ end
+ r = r + 1 ; result[r] = etransform or ") ;"
+ end
+ if wrapup then
+ wrapup()
+ end
+ end
+
+ if cpath then
+ r = r + 1 ; result[r] = f_clip_stop(cpath[1])
+ end
+
end
end
end
- function handlers.g(c,top)
- local a = c.at
- setmetatableindex(a,top)
- process(c,"/*",a)
- end
+ -- kind of special
+
+ do
+
+ -- some day:
+ --
+ -- specification = identifiers.jpg(data."string")
+ -- specification.data = data
+ -- inclusion takes from data
+ -- specification.data = false
+
+ local f_image = formatters[ [[figure("%s") xysized (%N,%N) shifted (%N,%N)]] ]
+
+ local nofimages = 0
+
+ function handlers.image(c)
+ local at = c.at
+ local im = rawget(at,"xlink:href")
+ if im then
+ local kind, data = match(im,"^data:image/([a-z]+);base64,(.*)$")
+ if kind == "png" then
+ -- ok
+ elseif kind == "jpeg" then
+ kind = "jpg"
+ else
+ kind = false
+ end
+ if kind and data then
+ local w = rawget(at,"width")
+ local h = rawget(at,"height")
+ local x = rawget(at,"x")
+ local y = rawget(at,"y")
+ w = w and asnumber_x(w)
+ h = h and asnumber_y(h)
+ x = x and asnumber_vx(x) or 0
+ y = y and asnumber_vy(y) or 0
+ nofimages = nofimages + 1
+ local name = "temp-svg-image-" .. nofimages .. "." .. kind
+ local data = mime.decode("base64")(data)
+ io.savedata(name,data)
+ if not w or not h then
+ local info = graphics.identifiers[kind](data,"string")
+ if info then
+ -- todo: keep aspect ratio attribute
+ local xsize = info.xsize
+ local ysize = info.ysize
+ if not w then
+ if not h then
+ w = xsize
+ h = ysize
+ else
+ w = (h / ysize) * xsize
+ end
+ else
+ h = (w / xsize) * ysize
+ end
+ end
+ end
+ -- safeguard:
+ if not w then w = h or 1 end
+ if not h then h = w or 1 end
+ luatex.registertempfile(name)
+ -- done:
+ flushobject(f_image(name,w,h,x,y - h),at)
+ else
+ -- nothing done
+ end
+ end
+ end
- function handlers.symbol(c,top)
- report("todo: %s","symbol")
end
- -- We only need to filter classes .. I will complete this when I really need
- -- it. Not hard to do but kind of boring.
+ -- these transform: g a text svg symbol
+
+ do
+
+ function handlers.a(c)
+ process(c,"/*")
+ end
+
+ function handlers.g(c) -- much like flushobject so better split and share
+ local at = c.at
+
+ local btransform, etransform, transform = handletransform(at)
+ local cpath, clippath = handleclippath(at)
+
+ if cpath then
+ r = r + 1 ; result[r] = s_clip_start
+ end
+
+ if btransform then
+ r= r + 1 result[r] = btransform
+ end
+
+ local _transform = transform
+ local _clippath = clippath
+ at["transform"] = false
+ at["clip-path"] = false
+
+ process(c,"/*")
- local p_class = P(".") * C((R("az","AZ","09","__","--")^1))
- local p_spec = P("{") * C((1-P("}"))^1) * P("}")
+ at["transform"] = _transform
+ at["clip-path"] = _clippath
- local p_grab = ((Carg(1) * p_class * p_space^0 * p_spec / function(t,k,v) t[k] = v end) + p_space^1 + P(1))^1
+ if etransform then
+ r = r + 1 ; result[r] = etransform
+ end
- function handlers.style(c,top)
- local s = xmltext(c)
- lpegmatch(p_grab,s,1,styles)
- for k, v in next, styles do
- -- todo: lpeg
- local t = { }
- for k, v in gmatch(v,"%s*([^:]+):%s*([^;]+);") do
- if k == "font" then
- v = xml.css.fontspecification(v)
+ if cpath then
+ local f_done = cpath.evenodd
+ if cpath.curve then
+ f_done = f_done and f_eoclip_stop_c or f_clip_stop_c
+ else
+ f_done = f_done and f_eoclip_stop_l or f_clip_stop_l
end
- t[k] = v
+ r = r + 1 ; result[r] = f_done(cpath[1])
end
- styles[k] = t
end
- bodyfont = tex.getdimen("bodyfontsize") / 65536
- end
- -- this will never really work out
-
- function handlers.text(c,top)
- local a = c.at
- local x = asnumber_vx(a.x)
- local y = asnumber_vy(a.y)
- local text = xmltext(c)
- local size = false
- local fill = a.fill
- -- escape text or keep it at the tex end
- local class = a.class
- if class then
- local style = styles[class]
- if style and next(style) then
- local font = style.font
- local s_family = font and font.family
- local s_style = font and font.style
- local s_weight = font and font.weight
- local s_size = font and font.size
- if s_size then
- local f = factors[s_size[2]]
- if f then
- size = f * s_size[1]
+ -- this will never really work out
+ --
+ -- todo: register text in lua in mapping with id, then draw mapping unless overloaded
+ -- using lmt_svglabel with family,style,weight,size,id passed
+
+ -- nested tspans are messy: they can have displacements but in inkscape we also
+ -- see x and y (inner and outer element)
+
+ -- The size is a bit of an issue. I assume that the specified size relates to the
+ -- designsize but we want to be able to use other fonts.
+
+ do
+
+ local f_styled = formatters["\\svgstyled{%s}{%s}{%s}{%s}"]
+ local f_colored = formatters["\\svgcolored{%N}{%N}{%N}{"]
+ local f_placed = formatters["\\svgplaced{%N}{%N}{}{"]
+ local f_poschar = formatters["\\svgposchar{%N}{%N}{%s}"]
+ local f_char = formatters["\\svgchar{%s}"]
+
+ local f_scaled = formatters["\\svgscaled{%N}{%s}{%s}{%s}"]
+ local f_normal = formatters["\\svgnormal{%s}{%s}{%s}"]
+
+ -- We move to the outer (x,y) and when we have an inner offset we
+ -- (need to) compensate for that outer offset.
+
+ -- local f_text_scaled_svg = formatters['(svgtext("%s") scaled %N shifted (%N,%N))']
+ -- 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")']
+
+ -- or just maptext
+
+ local f_mapped_normal_svg = formatters['(svgtext("%s") shifted (%N,%N))']
+ local f_mapped_simple_svg = formatters['svgtext("%s")']
+
+ local cssfamily = css.family
+ local cssstyle = css.style
+ local cssweight = css.weight
+ local csssize = css.size
+
+ local usedfonts = setmetatableindex(function(t,k)
+ local v = setmetatableindex("table")
+ t[k] = v
+ return v
+ end)
+
+ local p_texescape = lpegpatterns.texescape
+
+ -- For now as I need it for my (some 1500) test files.
+
+ local function checkedfamily(name)
+ if find(name,"^.-verdana.-$") then
+ name = "verdana"
+ end
+ return name
+ end
+
+ -- todo: only escape some chars and handle space
+
+ local defaultsize = 10
+
+ local function collect(t,c,x,y,size,scale,family,tx,ty)
+ local at = c.at
+ local ax = rawget(at,"x")
+ local ay = rawget(at,"y")
+ local dx = rawget(at,"dx")
+ local dy = rawget(at,"dy")
+ local v_fill = at["fill"]
+ local v_family = at["font-family"]
+ local v_style = at["font-style"]
+ local v_weight = at["font-weight"]
+ local v_size = at["font-size"]
+ --
+ ax = ax and asnumber_vx(ax) or x
+ ay = ay and asnumber_vy(ay) or y
+ dx = dx and asnumber_vx(dx) or 0
+ dy = dy and asnumber_vy(dy) or 0
+ --
+ if v_family then v_family = cssfamily(v_family) end
+ if v_style then v_style = cssstyle (v_style) end
+ if v_weight then v_weight = cssweight(v_weight) end
+ if v_size then v_size = csssize (v_size,factors) end
+ --
+ ax = ax - x
+ ay = ay - y
+ --
+ local elayered = ax ~= 0 or ay ~= 0 or false
+ local eplaced = dx ~= 0 or dy ~= 0 or false
+
+ local usedsize, usedscaled
+
+ if elayered then
+ -- we're now at the outer level again so we need to scale
+ -- back to the outer level values
+ t[#t+1] = formatters["\\svgsetlayer{%0N}{%0N}{"](ax,-ay)
+ usedsize = v_size or defaultsize
+ usedscale = usedsize / defaultsize
+ else
+ -- we're nested so we can be scaled
+ usedsize = v_size or size
+ usedscale = (usedsize / defaultsize) / scale
+ end
+ --
+ -- print("element ",c.tg)
+ -- print(" layered ",elayered)
+ -- print(" font size ",v_size)
+ -- print(" parent size ",size)
+ -- print(" parent scale",scale)
+ -- print(" used size ",usedsize)
+ -- print(" used scale ",usedscale)
+ --
+ if eplaced then
+ t[#t+1] = f_placed(dx,dy)
+ end
+ --
+ if not v_family then v_family = family end
+ if not v_weight then v_weight = "normal" end
+ if not v_style then v_style = "normal" end
+ --
+ if v_family then
+ v_family = fonts.names.cleanname(v_family)
+ v_family = checkedfamily(v_family)
+ end
+ --
+ usedfonts[v_family][v_weight][v_style] = true
+ --
+-- if usedscale == 1 then
+-- t[#t+1] = f_normal( v_family,v_weight,v_style)
+-- else
+ t[#t+1] = f_scaled(usedscale,v_family,v_weight,v_style)
+-- end
+ t[#t+1] = "{"
+ --
+ local ecolored = v_fill and v_fill ~= "" or false
+ if ecolored then
+ -- todo
+ local r, g, b = rgbcomponents(v_fill)
+ if r and g and b then
+ t[#t+1] = f_colored(r,g,b)
+ else
+ ecolored = false
end
end
- -- todo: family: serif | sans-serif | monospace : use mapping
- if s_family then
- if s_family == "serif" then
- text = "\\rm " .. text
- elseif s_family == "sans-serif" then
- text = "\\ss " .. text
+ --
+ local dt = c.dt
+ local nt = #dt
+ for i=1,nt do
+ local di = dt[i]
+ if type(di) == "table" then
+ -- can be a tspan (should we pass dx too)
+ collect(t,di,x,y,usedsize,usedscale,v_family)
else
- text = "\\tt " .. text
+ if i == 1 then
+ di = gsub(di,"^%s+","")
+ end
+ if i == nt then
+ di = gsub(di,"%s+$","")
+ end
+ local chars = utfsplit(di)
+ if tx then
+ for i=1,#chars do
+ chars[i] = f_poschar(
+ (tx[i] or 0) - x,
+ (ty[i] or 0) - y,
+ utfbyte(chars[i])
+ )
+ end
+ di = "{" .. concat(chars) .. "}"
+ else
+ -- this needs to be texescaped ! and even quotes and newlines
+ -- or we could register it but that's a bit tricky as we nest
+ -- and don't know what we can expect here
+ -- di = lpegmatch(p_texescape,di) or di
+ for i=1,#chars do
+ chars[i] = f_char(utfbyte(chars[i]))
+ end
+ di = concat(chars)
+ end
+ t[#t+1] = di
end
end
- if s_style or s_weight then
- text = formatters['\\style[%s%s]{%s}'](s_weight or "",s_style or "",text)
+ --
+ if ecolored then
+ t[#t+1] = "}"
end
- fill = style.fill or fill
+ --
+ t[#t+1] = "}"
+ --
+ if eplaced then
+ t[#t+1] = "}"
+ end
+ if elayered then
+ t[#t+1] = "}"
+ end
+ --
+ return t
end
- end
- if size then
- -- bodyfontsize
- size = size/bodyfont
- text = f_text_scaled(text,size,x,y)
- else
- text = f_text_normal(text,x,y)
- end
- if fill and fill ~= "none" then
- text = f_draw("",text,"",fillproperties(fill,a))
- else
- text = f_draw("",text,"","","","","")
- end
- if trace then
- report("text: x %.3N, y %.3N, text %s",x,y,text)
- end
- r = r + 1 ; result[r] = text
- end
- function handlers.svg(c,top,x,y,w,h,noclip,notransform,normalize)
- local a = setmetatableindex(c.at,top)
- local v = a.viewBox
- local t = a.transform
- local wrapupoffset
- local wrapupviewport
- local btransform
- local etransform
- local bhacked
- local ehacked
- local wd = w
- -- local ex, em
- local xpct, ypct, rpct
- if notransform then
--- t = nil
- end
- if trace then
- report("view: %s, xpct %.3N, ypct %.3N","before",percentage_x,percentage_y)
- end
- if v then
- x, y, w, h = viewbox(v)
- if trace then
- report("viewbox: x %.3N, y %.3N, width %.3N, height %.3N",x,y,w,h)
+ local s_startlayer = "\\svgstartlayer "
+ local s_stoplayer = "\\svgstoplayer "
+
+ function handlers.text(c)
+ local only = fullstrip(xmltextonly(c))
+ -- if metapost.processing() then
+ local at = c.at
+ local x = rawget(at,"x")
+ local y = rawget(at,"y")
+
+ local tx = asnumber_vx_t(x)
+ local ty = asnumber_vy_t(y)
+
+ x = tx[1] or 0 -- catch bad x/y spec
+ y = ty[1] or 0 -- catch bad x/y spec
+
+ local v_fill = at["fill"]
+ if not v_fill or v_fill == "none" then
+ v_fill = "black"
+ end
+ local color, opacity, invisible = fillproperties(v_fill,at)
+ local r = metapost.remappedtext(only)
+ if r then
+ if x == 0 and y == 0 then
+ only = f_mapped_simple_svg(r.index)
+ else
+ only = f_mapped_normal_svg(r.index,x,y)
+ end
+ flushobject(only,at,color,opacity)
+ if trace_text then
+ report("text: %s",only)
+ end
+ elseif not invisible then -- can be an option
+ local scale = 1
+ local textid = 0
+ local result = { }
+ local nx = #tx
+ local ny = #ty
+ --
+ result[#result+1] = s_startlayer
+ if nx > 1 or ny > 1 then
+ concat(collect(result,c,x,y,defaultsize,1,"serif",tx,ty))
+ else
+ concat(collect(result,c,x,y,defaultsize,1,"serif"))
+ end
+ result[#result+1] = s_stoplayer
+ result = concat(result)
+ if x == 0 and y == 0 then
+ result = f_text_simple_svg(result)
+ else
+ result = f_text_normal_svg(result,x,y)
+ end
+ flushobject(result,at,color,opacity)
+ if trace_text then
+ report("text: %s",result)
+ end
+ elseif trace_text then
+ report("invisible text: %s",only)
+ end
+ -- elseif trace_text then
+ -- report("ignored text: %s",only)
+ -- end
end
+
+ function metapost.reportsvgfonts()
+ for family, weights in sortedhash(usedfonts) do
+ for weight, styles in sortedhash(weights) do
+ for style in sortedhash(styles) do
+ report("used font: %s-%s-%s",family,weight,style)
+ end
+ end
+ end
+ end
+
+ statistics.register("used svg fonts",function()
+ if next(usedfonts) then
+ -- also in log file
+ logs.startfilelogging(report,"used svg fonts")
+ local t = { }
+ for family, weights in sortedhash(usedfonts) do
+ for weight, styles in sortedhash(weights) do
+ for style in sortedhash(styles) do
+ report("%s-%s-%s",family,weight,style)
+ t[#t+1] = formatters["%s-%s-%s"](family,weight,style)
+ end
+ end
+ end
+ logs.stopfilelogging()
+ return concat(t," ")
+ end
+ end)
+
end
- if h then
- --
- -- em = factors["em"]
- -- ex = factors["ex"]
- -- factors["em"] = em
- -- factors["ex"] = ex
- --
- xpct = percentage_x
- ypct = percentage_y
- rpct = percentage_r
- percentage_x = w / 100
- percentage_y = h / 100
- percentage_r = (sqrt(w^2 + h^2) / sqrt(2)) / 100
+
+ function handlers.svg(c,x,y,w,h,noclip,notransform,normalize,usetextindex)
+ local at = c.at
+
+ local wrapupviewport
+ local bhacked
+ local ehacked
+ local wd = w
+ -- local ex, em
+ local xpct, ypct, rpct
+
+ local btransform, etransform, transform = handletransform(at)
+
if trace then
- report("view: %s, xpct %.3N, ypct %.3N","inside",percentage_x,percentage_y)
+ report("view: %s, xpct %N, ypct %N","before",percentage_x,percentage_y)
end
- wrapupviewport = viewport(x,y,w,h,noclip)
- end
- -- todo: combine transform and offset here
- if t then
- btransform, etransform = transform(t,true)
- end
- -- some fonts need this (bad transforms + viewbox)
- if v and normalize and w and wd and w ~= wd and w > 0 and wd > 0 then
- bhacked = s_hacked_start
- ehacked = f_hacked_stop(y or 0,wd/w)
- end
- if btransform then
- r = r + 1 ; result[r] = btransform
- end
- if bhacked then
- r = r + 1 ; result[r] = bhacked
- end
- wrapupoffset = offset(a)
- process(c,"/*",top or defaults)
- if wrapupoffset then
- wrapupoffset()
- end
- if ehacked then
- r = r + 1 ; result[r] = ehacked
- end
- if etransform then
- r = r + 1 ; result[r] = etransform
- end
- if h then
- --
- -- factors["em"] = em
- -- factors["ex"] = ex
- --
- percentage_x = xpct
- percentage_y = ypct
- percentage_r = rpct
- if wrapupviewport then
- wrapupviewport()
+
+ local viewbox = at.viewBox
+
+ if viewbox then
+ x, y, w, h = handleviewbox(viewbox)
+ if trace then
+ report("viewbox: x %N, y %N, width %N, height %N",x,y,w,h)
+ end
+ end
+ if not w or not h or w == 0 or h == 0 then
+ noclip = true
+ end
+ if h then
+ --
+ -- em = factors["em"]
+ -- ex = factors["ex"]
+ -- factors["em"] = em
+ -- factors["ex"] = ex
+ --
+ xpct = percentage_x
+ ypct = percentage_y
+ rpct = percentage_r
+ percentage_x = w / 100
+ percentage_y = h / 100
+ percentage_r = (sqrt(w^2 + h^2) / sqrt(2)) / 100
+ if trace then
+ report("view: %s, xpct %N, ypct %N","inside",percentage_x,percentage_y)
+ end
+ wrapupviewport = viewport(x,y,w,h,noclip)
+ end
+ -- todo: combine transform and offset here
+
+ -- some fonts need this (bad transforms + viewbox)
+ if v and normalize and w and wd and w ~= wd and w > 0 and wd > 0 then
+ bhacked = s_wrapped_start
+ ehacked = f_wrapped_stop(y or 0,wd/w)
+ end
+ if btransform then
+ r = r + 1 ; result[r] = btransform
+ end
+ if bhacked then
+ r = r + 1 ; result[r] = bhacked
+ end
+ local boffset, eoffset = offset(at)
+ if boffset then
+ r = r + 1 result[r] = boffset
+ end
+ textindex = usetextindex and 0 or false
+
+ at["transform"] = false
+ at["viewBox"] = false
+
+ process(c,"/*")
+
+ at["transform"] = transform
+ at["viewBox"] = viewbox
+
+ if eoffset then
+ r = r + 1 result[r] = eoffset
+ end
+ if ehacked then
+ r = r + 1 ; result[r] = ehacked
+ end
+ if etransform then
+ r = r + 1 ; result[r] = etransform
+ end
+ if h then
+ --
+ -- factors["em"] = em
+ -- factors["ex"] = ex
+ --
+ percentage_x = xpct
+ percentage_y = ypct
+ percentage_r = rpct
+ if wrapupviewport then
+ wrapupviewport()
+ end
+ end
+ if trace then
+ report("view: %s, xpct %N, ypct %N","after",percentage_x,percentage_y)
end
end
- if trace then
- report("view: %s, xpct %.3N, ypct %.3N","after",percentage_x,percentage_y)
- end
+
end
- process = function(x,p,top)
+ process = function(x,p)
for c in xmlcollected(x,p) do
- local h = handlers[c.tg]
+ local tg = c.tg
+ local h = handlers[c.tg]
if h then
- h(c,top)
+ h(c)
end
end
end
+ -- For huge inefficient files there can be lots of garbage to collect so
+ -- maybe we should run the collector when a file is larger than say 50K.
+
function metapost.svgtomp(specification,pattern,notransform,normalize)
local mps = ""
local svg = specification.data
@@ -1660,21 +2735,33 @@ do
if svg then
local c = xmlfirst(svg,pattern or "/svg")
if c then
- root, result, r, definitions, styles, bodyfont = svg, { }, 0, { }, { }, 12
- -- print("default",x,y,w,h)
+ root = svg
+ result = { }
+ r = 0
+ definitions = { }
+ tagstyles = { }
+ classstyles = { }
+ for s in xmlcollected(c,"/style") do
+ handlestyle(c)
+ end
+ handlechains(c)
+ xmlinheritattributes(c) -- put this in handlechains
handlers.svg (
c,
- nil,
specification.x,
specification.y,
specification.width,
specification.height,
specification.noclip,
notransform,
- normalize
+ normalize,
+ specification.remap
)
+ if trace_result then
+ report("result graphic:\n %\n t",result)
+ end
mps = concat(result," ")
- root, result, r, definitions, styles, bodyfont = false, false, false, false, false, false
+ root, result, r, definitions, styles = false, false, false, false, false
else
report("missing svg root element")
end
@@ -1686,14 +2773,49 @@ do
end
--- These helpers might move to their own module .. some day ...
+-- These helpers might move to their own module .. some day ... also they will become
+-- 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
+ 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 [ 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 = "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 = dd.comment
- local offset = dd.pageoffset
- for i=1,#dd do
+ 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,
@@ -1701,6 +2823,10 @@ function metapost.showsvgpage(data)
}, 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))
@@ -1713,10 +2839,31 @@ function metapost.showsvgpage(data)
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]
+ 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
+
function metapost.svgtopdf(data,...)
local mps = metapost.svgtomp(data,...)
if mps then
- local pdf = metapost.simple("metafun",mps,true) -- todo: special instance, only basics needed
+ -- todo: special instance, only basics needed
+ local pdf = metapost.simple("metafun",mps,true,false,"svg")
if pdf then
return pdf
else
@@ -1867,7 +3014,7 @@ do
local svgshapes = svgfile and svgfile.svgshapes
if svgshapes then
if type(unicode) == "string" then
- unicode = utf.byte(unicode)
+ unicode = utfbyte(unicode)
end
local chardata = tfmdata.characters[unicode]
local index = chardata and chardata.index
diff --git a/tex/context/base/mkiv/mult-mps.lua b/tex/context/base/mkiv/mult-mps.lua
index 625e8ca65..6385d3fe5 100644
--- a/tex/context/base/mkiv/mult-mps.lua
+++ b/tex/context/base/mkiv/mult-mps.lua
@@ -23,7 +23,7 @@ return {
"transform", "transformed", "ulcorner", "uniformdeviate", "unknown",
"urcorner", "xpart", "xscaled", "xxpart", "xypart", "ypart", "yscaled", "yxpart",
"yypart", "zscaled",
- "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds",
+ "addto", "clip", "input", "interim", "let", "newinternal", "save", "setbounds", "setgroup",
"shipout", "show", "showdependencies", "showtoken", "showvariable",
"special",
"begingroup", "endgroup", "of", "curl", "tension", "and", "controls",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index 04044e2a9..7b30b232e 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -228,6 +228,7 @@ return {
"automatichyphenmode",
"automatichyphenpenalty",
"begincsname",
+ "beginlocalcontrol",
"boundary",
"boxattr",
"boxdirection",
@@ -319,6 +320,7 @@ return {
"matheqnogapstep",
"mathflattenmode",
"mathitalicsmode",
+ "mathlimitsmode",
"mathnolimitsmode",
"matholdmode",
"mathpenaltiesmode",
@@ -744,6 +746,7 @@ return {
"showboxbreadth",
"showboxdepth",
"showlists",
+ "shownodedetails",
"showthe",
"skewchar",
"skip",
diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua
index 02c2c6f6e..ce0a473ba 100644
--- a/tex/context/base/mkiv/node-ini.lua
+++ b/tex/context/base/mkiv/node-ini.lua
@@ -512,11 +512,6 @@ end
trackers.register("system.showcodes", nodes.showcodes)
-if not nodecodes.dir then
- report_codes("use a newer version of luatex")
- os.exit()
-end
-
-- We don't need this sanitize-after-callback in ConTeXt and by disabling it we
-- also have a way to check if LuaTeX itself does the right thing.
diff --git a/tex/context/base/mkiv/page-cst.lua b/tex/context/base/mkiv/page-cst.lua
index 583e6af0c..119e7fc2b 100644
--- a/tex/context/base/mkiv/page-cst.lua
+++ b/tex/context/base/mkiv/page-cst.lua
@@ -36,7 +36,6 @@ local nuts = nodes.nuts
local tonode = nuts.tonode
local tonut = nuts.tonut
-local hpack = nuts.hpack
local vpack = nuts.vpack
local flushlist = nuts.flush_list
----- removenode = nuts.remove
diff --git a/tex/context/base/mkiv/page-ffl.mkiv b/tex/context/base/mkiv/page-ffl.mkiv
index 414cae4ac..306c19790 100644
--- a/tex/context/base/mkiv/page-ffl.mkiv
+++ b/tex/context/base/mkiv/page-ffl.mkiv
@@ -180,6 +180,12 @@
\setbox\scratchbox\vbox{\directvspacing\p_spaceinbetween}%
\scratchdimen\htdp\scratchbox
\fi
+ \ifvoid\b_strc_floats_facing_l\else
+ \page_postprocessors_linenumbers_box\b_strc_floats_facing_l
+ \fi
+ \ifvoid\b_strc_floats_facing_r\else
+ \page_postprocessors_linenumbers_box\b_strc_floats_facing_r
+ \fi
\doloop{%
\strc_floats_facing_flush_wrap\b_strc_floats_facing_l\v!left
\strc_floats_facing_flush_wrap\b_strc_floats_facing_r\v!right
diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi
index 51f808df8..6a03d12e4 100644
--- a/tex/context/base/mkiv/page-lin.mkvi
+++ b/tex/context/base/mkiv/page-lin.mkvi
@@ -72,10 +72,22 @@
\newconditional\page_postprocessors_needed_box
-\unexpanded\def\page_postprocessors_linenumbers_page #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
-\unexpanded\def\page_postprocessors_linenumbers_box #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
-\unexpanded\def\page_postprocessors_linenumbers_deepbox#tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \plusone }
-\unexpanded\def\page_postprocessors_linenumbers_column #tag{\page_lines_add_numbers_to_box{#tag}\currentcolumn\nofcolumns\zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_page_indeed #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_box_indeed #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_deepbox_indeed#tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \plusone }
+\unexpanded\def\page_postprocessors_linenumbers_column_indeed #tag{\page_lines_add_numbers_to_box{#tag}\currentcolumn\nofcolumns\zerocount}
+
+\let\page_postprocessors_linenumbers_page \gobbleoneargument
+\let\page_postprocessors_linenumbers_box \gobbleoneargument
+\let\page_postprocessors_linenumbers_deepbox\gobbleoneargument
+\let\page_postprocessors_linenumbers_column \gobbleoneargument
+
+\unexpanded\def\page_postprocessors_linenumbers_check
+ {\glet\page_postprocessors_linenumbers_check \relax
+ \glet\page_postprocessors_linenumbers_page \page_postprocessors_linenumbers_page_indeed
+ \glet\page_postprocessors_linenumbers_box \page_postprocessors_linenumbers_box_indeed
+ \glet\page_postprocessors_linenumbers_deepbox\page_postprocessors_linenumbers_deepbox_indeed
+ \glet\page_postprocessors_linenumbers_column \page_postprocessors_linenumbers_column_indeed}
\def\page_lines_start_define
{\setxvalue{\??linenumberinginstance\currentlinenumbering}%
@@ -179,6 +191,7 @@
\unexpanded\def\startlinenumbering
{\begingroup
+ \page_postprocessors_linenumbers_check
\dodoubleempty\page_lines_start}
\newcount\c_pages_lines_nesting
diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua
index 51a12429e..d64646d8a 100644
--- a/tex/context/base/mkiv/page-mix.lua
+++ b/tex/context/base/mkiv/page-mix.lua
@@ -41,7 +41,6 @@ local nuts = nodes.nuts
local tonode = nuts.tonode
local listtoutf = nodes.listtoutf
-local hpack = nuts.hpack
local vpack = nuts.vpack
local flushnode = nuts.flush
local concatnodes = nuts.concat
@@ -800,7 +799,7 @@ local function finalize(result)
local t = { }
for i=1,#list do
local l = list[i]
- local h = new_hlist()
+ local h = new_vlist() -- was hlist but that's wrong
local g = getlist(l)
t[i] = h
setlist(h,g)
@@ -881,12 +880,12 @@ end
local function getsplit(result,n)
if not result then
- report_state("flush, column %s, no result",n)
+ report_state("flush, column %s, %s",n,"no result")
return
end
local r = result.results[n]
if not r then
- report_state("flush, column %s, empty",n)
+ report_state("flush, column %s, %s",n,"empty")
end
local h = r.head
if not h then
@@ -982,9 +981,8 @@ local function getsplit(result,n)
for i=1,#list-1 do
setdepth(list[i],0)
end
- local b = vpack(l) -- multiple arguments, todo: fastvpack
-setbox("global",c,b) -- when we wrap in a box
- -- setbox(c,b)
+ local b = vpack(l) -- multiple arguments, todo: fastvpack
+ setbox("global",c,b) -- when we wrap in a box
r.inserts[c] = nil
end
diff --git a/tex/context/base/mkiv/page-mix.mkiv b/tex/context/base/mkiv/page-mix.mkiv
index f41d739be..e3ed47835 100644
--- a/tex/context/base/mkiv/page-mix.mkiv
+++ b/tex/context/base/mkiv/page-mix.mkiv
@@ -242,7 +242,8 @@
\page_one_command_routine
\fi
\global\setbox\b_page_mix_preceding\vbox % pack ?
- {\page_otr_command_flush_top_insertions
+ {\forgetall
+ \page_otr_command_flush_top_insertions
\ifdim\htdp\b_page_mix_preceding=\zeropoint \else
\writestatus\m!columns{preceding error}%
\unvbox\b_page_mix_preceding
diff --git a/tex/context/base/mkiv/page-not.mkiv b/tex/context/base/mkiv/page-not.mkiv
index d7602bd26..d6f63846f 100644
--- a/tex/context/base/mkiv/page-not.mkiv
+++ b/tex/context/base/mkiv/page-not.mkiv
@@ -22,20 +22,20 @@
\unprotect
-\def\checkbegincolumnfootnotes % should happen inside otr
- {\ifcase\c_strc_notes_page_location
- \erasenotebackup
- \else
- \flushnotes
- \savenotecontent
- \fi
- \savenotedata}
+% \def\checkbegincolumnfootnotes % should happen inside otr
+% {\ifcase\c_strc_notes_page_location
+% \erasenotebackup
+% \else
+% \flushnotes
+% \savenotecontent
+% \fi
+% \savenotedata}
-\def\checkendcolumnfootnotes
- {\restorenotedata
- \ifcase\c_strc_notes_page_location\else
- \restorenotecontent
- \fi}
+% \def\checkendcolumnfootnotes
+% {\restorenotedata
+% \ifcase\c_strc_notes_page_location\else
+% \restorenotecontent
+% \fi}
\let\checksinglecolumnfootnotes\relax
diff --git a/tex/context/base/mkiv/page-run.mkiv b/tex/context/base/mkiv/page-run.mkiv
index eedcfa416..d3efe1698 100644
--- a/tex/context/base/mkiv/page-run.mkiv
+++ b/tex/context/base/mkiv/page-run.mkiv
@@ -206,16 +206,16 @@
\gdef\page_grids_add_to_one_indeed#1%
{\begingroup
\resetvisualizers
- \global\setbox#1\vpack{\backgroundline[layout:one]{\box#1}}%
+ \global\setbox#1\vpack{\noindent\backgroundline[layout:one]{\box#1}}%
\endgroup}
\gdef\page_grids_add_to_mix_indeed#1%
{\begingroup
\resetvisualizers
- \global\setbox#1\vpack{\backgroundline[layout:mix]{\box#1}}%
+ \global\setbox#1\vpack{\noindent\backgroundline[layout:mix]{\box#1}}%
\endgroup}
-%D Ths next command shows some statistics (we might add more in due time):
+%D The next command shows some statistics (we might add more in due time):
\unexpanded\gdef\showusage
{\gtoksapp\everyaftershipout{\ctxcommand{showusage()}}%
diff --git a/tex/context/base/mkiv/regi-ini.lua b/tex/context/base/mkiv/regi-ini.lua
index 7691e8765..4b2412ee8 100644
--- a/tex/context/base/mkiv/regi-ini.lua
+++ b/tex/context/base/mkiv/regi-ini.lua
@@ -16,9 +16,11 @@ runtime.</p>
local commands, context = commands, context
+
+local tostring = tostring
local utfchar = utf.char
local P, Cs, Cc, lpegmatch = lpeg.P, lpeg.Cs, lpeg.Cc, lpeg.match
-local char, gsub, format, gmatch, byte, match = string.char, string.gsub, string.format, string.gmatch, string.byte, string.match
+local char, gsub, format, gmatch, byte, match, lower = string.char, string.gsub, string.format, string.gmatch, string.byte, string.match, string.lower
local next = next
local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
local concat = table.concat
@@ -103,11 +105,14 @@ local synonyms = { -- backward compatibility list
["pdf"] = "pdfdoc",
+ ["437"] = "ibm",
}
local currentregime = "utf"
local function loadregime(mapping,regime)
+ regime = lower(tostring(regime))
+ regime = synonyms[regime] or synonyms["windows-"..regime] or regime
local name = resolvers.findfile(format("regi-%s.lua",regime)) or ""
local data = name ~= "" and dofile(name)
if data then
@@ -126,8 +131,11 @@ end
local function loadreverse(t,k)
local t = { }
- for k, v in next, mapping[k] do
- t[v] = k
+ local m = mapping[k]
+ if m then
+ for k, v in next, m do
+ t[v] = k
+ end
end
backmapping[k] = t
return t
@@ -141,7 +149,8 @@ regimes.backmapping = backmapping
local function fromregime(regime,line)
if line and #line > 0 then
- local map = mapping[regime and synonyms[regime] or regime or currentregime]
+-- local map = mapping[regime and synonyms[regime] or regime or currentregime]
+ local map = mapping[regime or currentregime]
if map then
line = gsub(line,".",map)
end
@@ -459,3 +468,21 @@ if interfaces then
}
end
+
+-- Actually we can have a function returned from the lookup but we don't
+-- really use this code so I'm in no hurry.
+
+if lua.getcodepage then
+ local cod, acp, map
+ function os.tocodepage(name)
+ if map == nil then
+ cod, acp = lua.getcodepage()
+ map = cod and cod ~= 65001 and regimes.toregime
+ end
+ return map and map(cod,name) or name
+ end
+else
+ function os.tocodepage(name)
+ return name
+ end
+end
diff --git a/tex/context/base/mkiv/regi-ini.mkiv b/tex/context/base/mkiv/regi-ini.mkiv
index 532a4db0b..fcdc2536f 100644
--- a/tex/context/base/mkiv/regi-ini.mkiv
+++ b/tex/context/base/mkiv/regi-ini.mkiv
@@ -30,4 +30,8 @@
\unexpanded\def\startregime [#1]{\clf_startregime{#1}}
\unexpanded\def\stopregime {\clf_stopregime}
+% only for diagnostics:
+
+\def\codepagename#1{\cldcontext{os.tocodepage("#1")}}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b209ac2ab..f337a1e15 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 2b57a46fb..4825b13c7 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/strc-itm.mklx b/tex/context/base/mkiv/strc-itm.mklx
index e5458b5dd..c456bf470 100644
--- a/tex/context/base/mkiv/strc-itm.mklx
+++ b/tex/context/base/mkiv/strc-itm.mklx
@@ -961,23 +961,23 @@
% symbols + states
\def\strc_itemgroups_store_global_symbol#symbol%
- {\letgvalue{\??itemgroupglobal\currentitemlevel}#symbol}
+ {\letgvalue{\??itemgroupglobal\currentitemgroup:\currentitemlevel}#symbol}
\def\strc_itemgroups_store_local_symbol#symbol%
- {\letgvalue{\??itemgrouplocal\currentitemlevel}#symbol}
+ {\letgvalue{\??itemgrouplocal\currentitemgroup:\currentitemlevel}#symbol}
\def\strc_itemgroups_fetch_global_symbol
- {\csname\??itemgroupglobal\currentitemlevel\endcsname}
+ {\csname\??itemgroupglobal\currentitemgroup:\currentitemlevel\endcsname}
\def\strc_itemgroups_fetch_local_symbol
- {\csname\??itemgrouplocal\currentitemlevel\endcsname}
+ {\csname\??itemgrouplocal\currentitemgroup:\currentitemlevel\endcsname}
\def\strc_itemgroups_setup_symbol_default
{\edef\strc_itemgroups_asked_symbol{\itemgroupparameter\c!symbol}%
\strc_itemgroups_store_global_symbol\empty}
\def\strc_itemgroups_setup_symbol_continue
- {\ifcsname\??itemgroupglobal\currentitemlevel\endcsname
+ {\ifcsname\??itemgroupglobal\currentitemgroup:\currentitemlevel\endcsname
\let\strc_itemgroups_asked_symbol\strc_itemgroups_fetch_global_symbol
\else
\let\strc_itemgroups_asked_symbol\currentitemlevel
@@ -1859,4 +1859,26 @@
\defineitemgroup
[\v!itemize]
+%D This is really ugly I should get rid of the global mess, whuch is a side
+%D effect of the simple \type {\item} interface that we're stuck with for
+%D compatibility reasons. See footnotes for usage. It's probablynot robust
+%D for mixed itemgroups so in the end I need to get rid of the globals. One
+%D problem is that counters are set.
+
+\defineitemgroup
+ [\v!itemize:\v!note]
+
+\def\strc_itemgroups_push
+ {\edef\strc_itemgroups_pop
+ {\xdef\noexpand\currentitemlevel{\currentitemlevel}%
+ \global\c_strc_itemgroups_nesting \the\c_strc_itemgroups_nesting \relax
+ \global\c_strc_itemgroups_column_depth\the\c_strc_itemgroups_column_depth\relax}%
+ \global\c_strc_itemgroups_column_depth\zerocount
+ \global\c_strc_itemgroups_nesting \zerocount
+ \glet\currentitemlevel\!!zerocount
+ \unexpanded\def\startitemize{\startitemgroup[\v!itemize:\v!note]}%
+ \unexpanded\def\stopitemize {\stopitemgroup}}
+
+\let\strc_itemgroups_pop\relax
+
\protect \endinput
diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index f11c831dd..48151c76e 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -943,11 +943,22 @@
\letvalue{\??notepenalty\v!verystrict}\notepenaltyverystrict
\letvalue{\??notepenalty }\notepenaltytolerant
+% \def\strc_notes_set_width
+% {\edef\p_width{\noteparameter\c!width}%
+% \ifx\p_width\empty
+% \setnoteparameter\c!width{\hsize}%
+% \fi}
+
+\setupnotes
+ [\c!width=\v!auto]
+
\def\strc_notes_set_width
{\edef\p_width{\noteparameter\c!width}%
- \ifx\p_width\empty
+ \ifx\p_width\v!auto
+ \setnoteparameter\c!width{\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi}%
+ \else\ifx\p_width\empty
\setnoteparameter\c!width{\hsize}%
- \fi}
+ \fi\fi}
\appendtoks
\strc_notes_set_width
@@ -1390,9 +1401,8 @@
%D Nasty, the might be more:
-\appendtoks
- \c_strc_itemgroups_nesting\zerocount
-\to \everyinsidenoteinsert
+\appendtoks \strc_itemgroups_push \to \everybeforenoteinsert
+\appendtoks \strc_itemgroups_pop \to \everyafternoteinsert
% maybe but better use [scope=local] here
%
diff --git a/tex/context/base/mkiv/strc-tag.lua b/tex/context/base/mkiv/strc-tag.lua
index 0453640ca..88e0f108d 100644
--- a/tex/context/base/mkiv/strc-tag.lua
+++ b/tex/context/base/mkiv/strc-tag.lua
@@ -124,10 +124,18 @@ local properties = allocate { -- todo: more "record = true" to improve forma
table = { pdf = "Table", nature = "display" },
tablerow = { pdf = "TR", nature = "display" },
tablecell = { pdf = "TD", nature = "mixed" },
+ tableheadcell = { pdf = "TH", nature = "mixed" },
+ tablehead = { pdf = "THEAD", nature = "display" },
+ tablebody = { pdf = "TBODY", nature = "display" },
+ tablefoot = { pdf = "TFOOT", nature = "display" },
tabulate = { pdf = "Table", nature = "display" },
tabulaterow = { pdf = "TR", nature = "display" },
tabulatecell = { pdf = "TD", nature = "mixed" },
+ tabulateheadcell = { pdf = "TH", nature = "mixed" },
+ tabulatehead = { pdf = "THEAD", nature = "display" },
+ tabulatebody = { pdf = "TBODY", nature = "display" },
+ tabulatefoot = { pdf = "TFOOT", nature = "display" },
list = { pdf = "TOC", nature = "display" },
listitem = { pdf = "TOCI", nature = "display" },
diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv
index 621a54040..021245f29 100644
--- a/tex/context/base/mkiv/strc-tag.mkiv
+++ b/tex/context/base/mkiv/strc-tag.mkiv
@@ -83,9 +83,19 @@
\def\t!table {table} % Table
\def\t!tablerow {tablerow} % TR
\def\t!tablecell {tablecell} % TD
+\def\t!tableheadcell {tableheadcell} % TH
+\def\t!tablehead {tablehead} % THEAD
+\def\t!tablebody {tablebody} % TBODY
+\def\t!tablefoot {tablefoot} % TFOOT
+
+
\def\t!tabulate {tabulate} % Table
\def\t!tabulaterow {tabulaterow} % TR
\def\t!tabulatecell {tabulatecell} % TD
+\def\t!tabulateheadcell {tabulateheadcell} % TH
+\def\t!tabulatehead {tabulatehead} % THEAD
+\def\t!tabulatebody {tabulatebody} % TBODY
+\def\t!tabulatefoot {tabulatefoot} % TFOOT
\def\t!math {math} % math
\def\t!mathtable {mtable} % Table
diff --git a/tex/context/base/mkiv/syst-ini.mkxl b/tex/context/base/mkiv/syst-ini.mkxl
index 22b3ba039..0befec48c 100644
--- a/tex/context/base/mkiv/syst-ini.mkxl
+++ b/tex/context/base/mkiv/syst-ini.mkxl
@@ -370,6 +370,7 @@
\newdimen\scratchwidth
\newdimen\scratchheight
\newdimen\scratchdepth
+\newdimen\scratchtotal
\newdimen\scratchoffset
\newdimen\scratchleftoffset
diff --git a/tex/context/base/mkiv/tabl-ntb.mkiv b/tex/context/base/mkiv/tabl-ntb.mkiv
index 113b7a364..8162f3964 100644
--- a/tex/context/base/mkiv/tabl-ntb.mkiv
+++ b/tex/context/base/mkiv/tabl-ntb.mkiv
@@ -200,6 +200,13 @@
\newbox\b_tabl_ntb_final
+%D For tagging and export:
+
+\newconstant \c_tabl_ntb_head
+\newconstant \c_tabl_ntb_body
+\newconstant \c_tabl_ntb_foot
+\newconditional \c_tabl_ntb_okay
+
%D We have already prepared the previous macros for nesting, so we only have to pop
%D in the right ones:
@@ -1007,19 +1014,30 @@
\unexpanded\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
{% tricky and dirty order -)
+ \setfalse\c_tabl_ntb_okay
+ % head
\doifelsesometoks\t_tabl_ntb_head % slow, better a flag
- {\the\t_tabl_ntb_head
+ {\c_tabl_ntb_head\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
+ \the\t_tabl_ntb_head
\c_tabl_ntb_n_of_head_lines\c_tabl_ntb_maximum_row\relax
\doifelsesometoks\t_tabl_ntb_next
{\the\t_tabl_ntb_next
\c_tabl_ntb_n_of_next_lines\numexpr\c_tabl_ntb_maximum_row-\c_tabl_ntb_n_of_head_lines\relax}%
{\c_tabl_ntb_n_of_next_lines\zerocount}% was 1
\c_tabl_ntb_n_of_hdnx_lines\c_tabl_ntb_maximum_row}
- {\c_tabl_ntb_n_of_head_lines\zerocount % was 1
+ {\c_tabl_ntb_head\zerocount
+ \c_tabl_ntb_n_of_head_lines\zerocount % was 1
\c_tabl_ntb_n_of_next_lines\zerocount
\c_tabl_ntb_n_of_hdnx_lines\zerocount}%
+ % body
+ \c_tabl_ntb_body\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
\the\t_tabl_ntb_body
- \the\t_tabl_ntb_foot
+ % foot
+ \doifelsesometoks\t_tabl_ntb_foot
+ {\c_tabl_ntb_foot\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
+ \the\t_tabl_ntb_foot}%
+ {\c_tabl_ntb_foot\zerocount}%
+ % done
\removeunwantedspaces % only if hmode
% finish cells
\tabl_ntb_loop_one
@@ -1235,19 +1253,65 @@
\let\m_tabl_ntb_saved_row\!!zerocount
\let\m_tabl_ntb_saved_col\!!zerocount
+\def\tabl_ntb_start_tagged
+ {\scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
+ \ifnum\scratchcounter=\c_tabl_ntb_head
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablehead\empty
+ \else\ifnum\scratchcounter=\c_tabl_ntb_body
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablebody\empty
+ \else\ifnum\scratchcounter=\c_tabl_ntb_foot
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablefoot\empty
+ \fi\fi\fi
+ \dostarttagged\t!tablerow\empty}
+
+\def\tabl_ntb_stop_tagged
+ {\dostoptagged
+ \ifconditional\c_tabl_ntb_okay
+ \scratchcounter\numexpr\c_tabl_ntb_row+\plustwo\relax
+ \ifnum\scratchcounter=\c_tabl_ntb_body
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \else\ifnum\scratchcounter=\c_tabl_ntb_foot
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \else\ifnum\scratchcounter>\c_tabl_ntb_maximum_row
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \fi\fi\fi
+ \fi}
+
\unexpanded\def\tabl_ntb_row_align_start
{\global\advance\c_tabl_ntb_row\plusone
\global\c_tabl_ntb_col\plusone
\global\c_tabl_ntb_spn\zerocount
\tabl_ntb_row_align_start_inject
- \dostarttagged\t!tablerow\empty
+ \ifconditional\c_strc_tags_enabled
+ \tabl_ntb_start_tagged
+ \fi
\hbox\bgroup
\kern\dimexpr\d_tabl_ntb_leftmargindistance\relax}
\unexpanded\def\tabl_ntb_row_align_stop
{\kern\dimexpr\d_tabl_ntb_rightmargindistance-\d_tabl_ntb_columndistance\relax
\egroup
- \dostoptagged
+ \ifconditional\c_strc_tags_enabled
+ \tabl_ntb_stop_tagged
+ \fi
\tabl_ntb_row_align_stop_inject}
\unexpanded\def\tabl_ntb_before_page
diff --git a/tex/context/base/mkiv/tabl-ntb.mkxl b/tex/context/base/mkiv/tabl-ntb.mkxl
index d7ba548d2..6b84411b2 100644
--- a/tex/context/base/mkiv/tabl-ntb.mkxl
+++ b/tex/context/base/mkiv/tabl-ntb.mkxl
@@ -198,6 +198,13 @@
\newbox\b_tabl_ntb_final
+%D For tagging and export:
+
+\newconstant \c_tabl_ntb_head
+\newconstant \c_tabl_ntb_body
+\newconstant \c_tabl_ntb_foot
+\newconditional \c_tabl_ntb_okay
+
%D We have already prepared the previous macros for nesting, so we only have to pop
%D in the right ones:
@@ -1005,19 +1012,30 @@
\unexpanded\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
{% tricky and dirty order -)
+ \setfalse\c_tabl_ntb_okay
+ % head
\doifelsesometoks\t_tabl_ntb_head % slow, better a flag
- {\the\t_tabl_ntb_head
+ {\c_tabl_ntb_head\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
+ \the\t_tabl_ntb_head
\c_tabl_ntb_n_of_head_lines\c_tabl_ntb_maximum_row\relax
\doifelsesometoks\t_tabl_ntb_next
{\the\t_tabl_ntb_next
\c_tabl_ntb_n_of_next_lines\numexpr\c_tabl_ntb_maximum_row-\c_tabl_ntb_n_of_head_lines\relax}%
{\c_tabl_ntb_n_of_next_lines\zerocount}% was 1
\c_tabl_ntb_n_of_hdnx_lines\c_tabl_ntb_maximum_row}
- {\c_tabl_ntb_n_of_head_lines\zerocount % was 1
+ {\c_tabl_ntb_head\zerocount
+ \c_tabl_ntb_n_of_head_lines\zerocount % was 1
\c_tabl_ntb_n_of_next_lines\zerocount
\c_tabl_ntb_n_of_hdnx_lines\zerocount}%
+ % body
+ \c_tabl_ntb_body\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
\the\t_tabl_ntb_body
- \the\t_tabl_ntb_foot
+ % foot
+ \doifelsesometoks\t_tabl_ntb_foot
+ {\c_tabl_ntb_foot\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
+ \the\t_tabl_ntb_foot}%
+ {\c_tabl_ntb_foot\zerocount}%
+ % done
\removeunwantedspaces % only if hmode
% finish cells
\tabl_ntb_loop_one
@@ -1233,19 +1251,65 @@
\let\m_tabl_ntb_saved_row\!!zerocount
\let\m_tabl_ntb_saved_col\!!zerocount
+\def\tabl_ntb_start_tagged
+ {\scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
+ \ifnum\scratchcounter=\c_tabl_ntb_head
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablehead\empty
+ \orelse\ifnum\scratchcounter=\c_tabl_ntb_body
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablebody\empty
+ \orelse\ifnum\scratchcounter=\c_tabl_ntb_foot
+ \ifconditional\c_tabl_ntb_okay
+ \dostoptagged
+ \else
+ \settrue\c_tabl_ntb_okay
+ \fi
+ \dostarttagged\t!tablefoot\empty
+ \fi
+ \dostarttagged\t!tablerow\empty}
+
+\def\tabl_ntb_stop_tagged
+ {\dostoptagged
+ \ifconditional\c_tabl_ntb_okay
+ \scratchcounter\numexpr\c_tabl_ntb_row+\plustwo\relax
+ \ifnum\scratchcounter=\c_tabl_ntb_body
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \orelse\ifnum\scratchcounter=\c_tabl_ntb_foot
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \orelse\ifnum\scratchcounter>\c_tabl_ntb_maximum_row
+ \dostoptagged
+ \setfalse\c_tabl_ntb_okay
+ \fi
+ \fi}
+
\unexpanded\def\tabl_ntb_row_align_start
{\global\advance\c_tabl_ntb_row\plusone
\global\c_tabl_ntb_col\plusone
\global\c_tabl_ntb_spn\zerocount
\tabl_ntb_row_align_start_inject
- \dostarttagged\t!tablerow\empty
+ \ifconditional\c_strc_tags_enabled
+ \tabl_ntb_start_tagged
+ \fi
\hbox\bgroup
\kern\dimexpr\d_tabl_ntb_leftmargindistance\relax}
\unexpanded\def\tabl_ntb_row_align_stop
{\kern\dimexpr\d_tabl_ntb_rightmargindistance-\d_tabl_ntb_columndistance\relax
\egroup
- \dostoptagged
+ \ifconditional\c_strc_tags_enabled
+ \tabl_ntb_stop_tagged
+ \fi
\tabl_ntb_row_align_stop_inject}
\unexpanded\def\tabl_ntb_before_page
diff --git a/tex/context/base/mkiv/typo-chr.mkiv b/tex/context/base/mkiv/typo-chr.mkiv
index 365c79e51..7da783ceb 100644
--- a/tex/context/base/mkiv/typo-chr.mkiv
+++ b/tex/context/base/mkiv/typo-chr.mkiv
@@ -1,4 +1,3 @@
-
%D \module
%D [ file=typo-chr,
%D version=2015.01.01, % or about that time
diff --git a/tex/context/base/mkiv/typo-del.mkiv b/tex/context/base/mkiv/typo-del.mkiv
index 2ce98841e..9320c37ee 100644
--- a/tex/context/base/mkiv/typo-del.mkiv
+++ b/tex/context/base/mkiv/typo-del.mkiv
@@ -674,22 +674,29 @@
\dostoptagged}
\def\typo_delimited_nextleft_symbol#1%
- {\localleftbox\bgroup
+ {\let\typo_delimited_reset_next_symbol\typo_delimited_reset_next_symbol_indeed
+ \localleftbox\bgroup
\swapmacros\leftboundarycharacter\rightboundarycharacter
\boundarycharactermode\plusone
\typo_delimited_left_symbol#1%
\egroup}
\def\typo_delimited_nextright_symbol#1%
- {\localrightbox\bgroup
+ {\let\typo_delimited_reset_next_symbol\typo_delimited_reset_next_symbol_indeed
+ \localrightbox\bgroup
\swapmacros\leftboundarycharacter\rightboundarycharacter
\boundarycharactermode\plusone
\typo_delimited_right_symbol#1%
\egroup}
+\unexpanded\def\typo_delimited_reset_next_symbol_indeed
+ {\localleftbox {}%
+ \localrightbox{}}%
+
+\let\typo_delimited_reset_next_symbol\relax
+
\appendtoks
- \localleftbox {}%
- \localrightbox{}%
+ \typo_delimited_reset_next_symbol
\to \everyforgetall
% \starttext
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index df76d474e..966b2ae73 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 99f21c336..f65eb65f8 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/common/s-abbreviations-logos.tex b/tex/context/modules/common/s-abbreviations-logos.tex
index 9cf7085f5..81fb060d8 100644
--- a/tex/context/modules/common/s-abbreviations-logos.tex
+++ b/tex/context/modules/common/s-abbreviations-logos.tex
@@ -146,6 +146,7 @@
\logo [INITEX] {ini\TeXsuffix}
\logo [INRSTEX] {inrs\TeXsuffix}
\logo [IO] {io}
+\logo [INKSCAPE] {Inkscape}
\logo [IRCNET] {IRCnet}
\logo [ISO] {iso}
\logo [JAVA] {Java}
@@ -335,6 +336,7 @@
%logo [WINNX] {Win9x}
\logo [WTHREEC] {W3C}
\logo [WWW] {www}
+\logo [WIKIPEDIA] {Wikipedia} % WikipediA (looks too weird)
\logo [WYSIWYG] {wysiwyg}
%logo [XDVI] {Xdvi}
\logo [XETEX] {\XeTeX}
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index c43682b9d..e856248cb 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 : 10/11/19 15:47:37
+-- merge date : 10/28/19 18:12:38
do -- begin closure to overcome local limits and interference
@@ -21092,6 +21092,9 @@ local function checklookups(fontdata,missing,nofmissing)
end
end
end
+local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst=0xE000
+local pualast=0xF8FF
local function unifymissing(fontdata)
if not fonts.mappings then
require("font-map")
@@ -21102,18 +21105,19 @@ local function unifymissing(fontdata)
resources.unicodes=unicodes
for unicode,d in next,fontdata.descriptions do
if unicode<privateoffset then
- local name=d.name
- if name then
- unicodes[name]=unicode
+ if unicode>=puafirst and unicode<=pualast then
+ else
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
end
+ else
end
end
fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
resources.unicodes=nil
end
-local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
-local puafirst=0xE000
-local pualast=0xF8FF
local function unifyglyphs(fontdata,usenames)
local private=fontdata.private or privateoffset
local glyphs=fontdata.glyphs
@@ -23082,7 +23086,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.109
+otf.version=3.110
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)