summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-02-27 20:17:05 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-02-27 20:17:05 +0100
commit4f7f67101a808c6b6c89d64ad5ee1f1701d8f632 (patch)
treec5f90a0b8e8a4e9d2cab82a0abebc65c6a93288e
parentc3ae4997f73041c6b97d8aec055ba24096602ab4 (diff)
downloadcontext-4f7f67101a808c6b6c89d64ad5ee1f1701d8f632.tar.gz
2021-02-27 19:30:00
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-metafun.lua2
-rw-r--r--context/data/scite/context/scite-context-data-metafun.properties23
-rw-r--r--context/data/textadept/context/data/scite-context-data-metafun.lua2
-rw-r--r--context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json2
-rw-r--r--doc/context/documents/general/manuals/lowlevel-paragraphs.pdfbin0 -> 140547 bytes
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex10
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex423
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-basics.tex66
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-debugging.tex163
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-examples.tex253
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-lua.tex276
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-macros.tex13
-rw-r--r--metapost/context/base/mpiv/mp-luas.mpiv5
-rw-r--r--metapost/context/base/mpxl/mp-luas.mpxl10
-rw-r--r--metapost/context/base/mpxl/mp-text.mpxl157
-rw-r--r--scripts/context/lua/mtxrun.lua62
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua62
-rw-r--r--scripts/context/stubs/unix/mtxrun62
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua62
-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/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/mlib-mpf.lua10
-rw-r--r--tex/context/base/mkiv/mtx-context-select.tex2
-rw-r--r--tex/context/base/mkiv/mult-fun.lua1
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25351 -> 25335 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin256039 -> 256139 bytes
-rw-r--r--tex/context/base/mkiv/util-str.lua70
-rw-r--r--tex/context/base/mkxl/bibl-tra.mkxl9
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/meta-imp-txt.lmt86
-rw-r--r--tex/context/base/mkxl/meta-imp-txt.mkxl339
-rw-r--r--tex/context/base/mkxl/mlib-lua.lmt72
-rw-r--r--tex/context/base/mkxl/mlib-mpf.lmt6
-rw-r--r--tex/context/base/mkxl/mlib-pps.lmt20
-rw-r--r--tex/context/base/mkxl/mlib-run.lmt2
-rw-r--r--tex/context/base/mkxl/mult-sys.mkxl2
-rw-r--r--tex/context/base/mkxl/node-par.lmt88
-rw-r--r--tex/context/base/mkxl/pack-mrl.mkxl2
-rw-r--r--tex/context/base/mkxl/page-imp.mkxl25
-rw-r--r--tex/context/base/mkxl/spac-def.mkxl2
-rw-r--r--tex/context/base/mkxl/spac-grd.mkxl8
-rw-r--r--tex/context/base/mkxl/spac-par.mkxl55
-rw-r--r--tex/context/base/mkxl/spac-ver.mkxl40
-rw-r--r--tex/context/base/mkxl/syst-ini.mkxl6
-rw-r--r--tex/context/base/mkxl/tabl-tbl.mkxl75
-rw-r--r--tex/context/base/mkxl/typo-par.lmt177
-rw-r--r--tex/context/base/mkxl/typo-par.mkxl30
-rw-r--r--tex/context/modules/mkxl/s-colors-show.mkxl4
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua58
52 files changed, 2622 insertions, 232 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
index a253f95b0..e4bdafaa8 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
@@ -1,4 +1,4 @@
return {
- ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "shownshadedirection", "shownshadecenter", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "rawmadetext", "validtexbox", "onetimetextext", "rawfmttext", "thefmttext", "fmttext", "onetimefmttext", "notcached", "keepcached", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "withopacity", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "dofill", "fillup", "eofillup", "nodraw", "dodraw", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath", "theoffset", "texmode", "systemmode", "texvar", "texstr", "isarray", "prefix", "dimension", "getmacro", "getdimen", "getcount", "gettoks", "setmacro", "setdimen", "setcount", "settoks", "positionpath", "positioncurve", "positionxy", "positionpxy", "positionwhd", "positionpage", "positionregion", "positionbox", "positionanchor", "positioninregion", "positionatanchor", "wdpart", "htpart", "dppart", "texvar", "texstr", "inpath", "pointof", "leftof", "rightof", "utfnum", "utflen", "utfsub", "newhash", "disposehash", "inhash", "tohash", "isarray", "prefix", "isobject", "comment", "report", "lua", "lualist", "mp", "MP", "luacall", "mirrored", "mirroredabout", "scriptindex", "newscriptindex", "newcolor", "newrgbcolor", "newcmykcolor", "newnumeric", "newboolean", "newtransform", "newpath", "newpicture", "newstring", "newpair", "mpvar" },
+ ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "shownshadedirection", "shownshadecenter", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "rawmadetext", "validtexbox", "onetimetextext", "rawfmttext", "thefmttext", "fmttext", "onetimefmttext", "notcached", "keepcached", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "withopacity", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "dofill", "fillup", "eofillup", "nodraw", "dodraw", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath", "theoffset", "texmode", "systemmode", "texvar", "texstr", "isarray", "prefix", "dimension", "getmacro", "getdimen", "getcount", "gettoks", "setmacro", "setdimen", "setcount", "settoks", "setglobalmacro", "setglobaldimen", "setglobalcount", "setglobaltoks", "positionpath", "positioncurve", "positionxy", "positionpxy", "positionwhd", "positionpage", "positionregion", "positionbox", "positionanchor", "positioninregion", "positionatanchor", "wdpart", "htpart", "dppart", "texvar", "texstr", "inpath", "pointof", "leftof", "rightof", "utfnum", "utflen", "utfsub", "newhash", "disposehash", "inhash", "tohash", "isarray", "prefix", "isobject", "comment", "report", "lua", "lualist", "mp", "MP", "luacall", "mirrored", "mirroredabout", "scriptindex", "newscriptindex", "newcolor", "newrgbcolor", "newcmykcolor", "newnumeric", "newboolean", "newtransform", "newpath", "newpicture", "newstring", "newpair", "mpvar" },
["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "shadeoffset", "textextoffset", "textextanchor", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption", "contextlmtxmode", "metafunversion", "minifunversion", "getparameters", "presetparameters", "hasparameter", "hasoption", "getparameter", "getparameterdefault", "getparametercount", "getmaxparametercount", "getparameterpath", "getparameterpen", "getparametertext", "applyparameters", "pushparameters", "popparameters", "definecolor" },
} \ No newline at end of file
diff --git a/context/data/scite/context/scite-context-data-metafun.properties b/context/data/scite/context/scite-context-data-metafun.properties
index 92de8db85..7b09abc2d 100644
--- a/context/data/scite/context/scite-context-data-metafun.properties
+++ b/context/data/scite/context/scite-context-data-metafun.properties
@@ -68,17 +68,18 @@ uniquelist circularpath squarepath linearpath theoffset \
texmode systemmode texvar texstr isarray \
prefix dimension getmacro getdimen getcount \
gettoks setmacro setdimen setcount settoks \
-positionpath positioncurve positionxy positionpxy positionwhd \
-positionpage positionregion positionbox positionanchor positioninregion \
-positionatanchor wdpart htpart dppart texvar \
-texstr inpath pointof leftof rightof \
-utfnum utflen utfsub newhash disposehash \
-inhash tohash isarray prefix isobject \
-comment report lua lualist mp \
-MP luacall mirrored mirroredabout scriptindex \
-newscriptindex newcolor newrgbcolor newcmykcolor newnumeric \
-newboolean newtransform newpath newpicture newstring \
-newpair mpvar
+setglobalmacro setglobaldimen setglobalcount setglobaltoks positionpath \
+positioncurve positionxy positionpxy positionwhd positionpage \
+positionregion positionbox positionanchor positioninregion positionatanchor \
+wdpart htpart dppart texvar texstr \
+inpath pointof leftof rightof utfnum \
+utflen utfsub newhash disposehash inhash \
+tohash isarray prefix isobject comment \
+report lua lualist mp MP \
+luacall mirrored mirroredabout scriptindex newscriptindex \
+newcolor newrgbcolor newcmykcolor newnumeric newboolean \
+newtransform newpath newpicture newstring newpair \
+mpvar
keywordclass.metafun.internals=\
nocolormodel greycolormodel graycolormodel rgbcolormodel \
diff --git a/context/data/textadept/context/data/scite-context-data-metafun.lua b/context/data/textadept/context/data/scite-context-data-metafun.lua
index a253f95b0..e4bdafaa8 100644
--- a/context/data/textadept/context/data/scite-context-data-metafun.lua
+++ b/context/data/textadept/context/data/scite-context-data-metafun.lua
@@ -1,4 +1,4 @@
return {
- ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "shownshadedirection", "shownshadecenter", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "rawmadetext", "validtexbox", "onetimetextext", "rawfmttext", "thefmttext", "fmttext", "onetimefmttext", "notcached", "keepcached", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "withopacity", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "dofill", "fillup", "eofillup", "nodraw", "dodraw", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath", "theoffset", "texmode", "systemmode", "texvar", "texstr", "isarray", "prefix", "dimension", "getmacro", "getdimen", "getcount", "gettoks", "setmacro", "setdimen", "setcount", "settoks", "positionpath", "positioncurve", "positionxy", "positionpxy", "positionwhd", "positionpage", "positionregion", "positionbox", "positionanchor", "positioninregion", "positionatanchor", "wdpart", "htpart", "dppart", "texvar", "texstr", "inpath", "pointof", "leftof", "rightof", "utfnum", "utflen", "utfsub", "newhash", "disposehash", "inhash", "tohash", "isarray", "prefix", "isobject", "comment", "report", "lua", "lualist", "mp", "MP", "luacall", "mirrored", "mirroredabout", "scriptindex", "newscriptindex", "newcolor", "newrgbcolor", "newcmykcolor", "newnumeric", "newboolean", "newtransform", "newpath", "newpicture", "newstring", "newpair", "mpvar" },
+ ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "shownshadedirection", "shownshadecenter", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "rawmadetext", "validtexbox", "onetimetextext", "rawfmttext", "thefmttext", "fmttext", "onetimefmttext", "notcached", "keepcached", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "withopacity", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "dofill", "fillup", "eofillup", "nodraw", "dodraw", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath", "theoffset", "texmode", "systemmode", "texvar", "texstr", "isarray", "prefix", "dimension", "getmacro", "getdimen", "getcount", "gettoks", "setmacro", "setdimen", "setcount", "settoks", "setglobalmacro", "setglobaldimen", "setglobalcount", "setglobaltoks", "positionpath", "positioncurve", "positionxy", "positionpxy", "positionwhd", "positionpage", "positionregion", "positionbox", "positionanchor", "positioninregion", "positionatanchor", "wdpart", "htpart", "dppart", "texvar", "texstr", "inpath", "pointof", "leftof", "rightof", "utfnum", "utflen", "utfsub", "newhash", "disposehash", "inhash", "tohash", "isarray", "prefix", "isobject", "comment", "report", "lua", "lualist", "mp", "MP", "luacall", "mirrored", "mirroredabout", "scriptindex", "newscriptindex", "newcolor", "newrgbcolor", "newcmykcolor", "newnumeric", "newboolean", "newtransform", "newpath", "newpicture", "newstring", "newpair", "mpvar" },
["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "shadeoffset", "textextoffset", "textextanchor", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption", "contextlmtxmode", "metafunversion", "minifunversion", "getparameters", "presetparameters", "hasparameter", "hasoption", "getparameter", "getparameterdefault", "getparametercount", "getmaxparametercount", "getparameterpath", "getparameterpen", "getparametertext", "applyparameters", "pushparameters", "popparameters", "definecolor" },
} \ 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 bcc2c9ede..6e414689d 100644
--- a/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json
+++ b/context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json
@@ -60,7 +60,7 @@
"name" : "context.extra"
},
"helper" : {
- "match" : "(zmod|ystretched|ysized|xysized|xyscaled|xstretched|xsized|withtransparency|withshadevector|withshadetransform|withshadestep|withshaderadius|withshadeorigin|withshademethod|withshadefraction|withshadefactor|withshadedomain|withshadedirection|withshadecolors|withshadecenter|withshade|withproperties|withopacity|withmask|withlinearshade|withgrey|withgray|withcircularshade|whitecolor|wdpart|visualizepaths|visualizedfill|visualizeddraw|verbatim|validtexbox|utfsub|utfnum|utflen|urtriangle|urmoved|urenlarged|urcircle|uptriangle|unspiked|unitvector|unittriangle|unitdiamond|unitcircle|uniquelist|undrawfill|undecorated|undashed|uncolored|ultriangle|ulmoved|ulenlarged|ulcircle|tripled|triangle|transparent|transparency|tostring|topenlarged|topboundary|topath|topair|tolist|tohash|tocycle|thetextext|thetexbox|theoffset|thelabel|thefmttext|texvar|texvar|textextoffset|textext|texstr|texstr|texmode|texbox|tensecircle|tcircle|tanh|tand|tan|systemmode|superellipsed|strut|stretched|straightpath|straightpairs|straightfunction|stoppassingvariable|startpassingvariable|squeezed|squarepath|sqr|spotcolor|space|sortlist|softened|snapped|smoothed|sized|sinh|sin|simplified|shownshadevector|shownshadeorigin|shownshadedirection|shownshadecenter|shortened|shapedlist|shadedup|shadedright|shadedleft|shadedinto|shadeddown|shaded|settoks|setmacro|setdimen|setcount|scriptindex|rule|roundedsquare|righttriangle|rightof|rightenlarged|rightboundary|rightarrow|resolvedcolor|resetdrawoptions|resetarrows|report|register|redecorated|readfile|rcircle|rawtextext|rawtexbox|rawmadetext|rawfmttext|randomshifted|randomizedcontrols|randomized|radian|quote|quotation|pushcurrentpicture|pushboundingbox|punked|property|properties|prefix|prefix|pow|positionxy|positionwhd|positionregion|positionpxy|positionpath|positionpage|positioninregion|positioncurve|positionbox|positionatanchor|positionanchor|popcurrentpicture|popboundingbox|pointof|pi|perpendicular|percent|penpoint|pencilled|peepholed|pathconnectors|passvariable|passarrayvariable|paralleled|paired|outsideof|outlinetexttopath|outlinetext|outerboundingbox|originpath|onlayer|onetimetextext|onetimefmttext|oddly|nothing|notcached|normalfill|normaldraw|nofill|nodraw|newtransform|newstring|newscriptindex|newrgbcolor|newpicture|newpath|newpair|newnumeric|newhash|newcolor|newcmykcolor|newboolean|naturalizepaths|namedcolor|multitonecolor|mpvar|mp|mirroredabout|mirrored|lualist|luacall|lua|lrtriangle|lrmoved|lrenlarged|lrcircle|log|loadmodule|loadimage|loadfile|loadfigure|ln|lltriangle|llmoved|llenlarged|llcircle|listtolines|listtocurves|listsize|listlast|linearpath|lefttriangle|leftof|leftenlarged|leftboundary|leftarrow|lcircle|laddered|label|keepcached|istextext|isobject|isarray|isarray|invtan|invsin|inverted|invcos|inv|intersection_point|intersection_found|interpolated|insideof|inpath|innerboundingbox|inhash|infont|infinite|htpart|greyscale|greyed|grayscale|grayed|graphictext|gettoks|getmacro|getdimen|getcount|function|fulltriangle|fullsquare|fulldiamond|formatted|format|fmttext|fillup|filloutlinetext|figure|externalfigure|exp|evenly|epsed|eofillup|eofill|eoclip|enlonged|enlarged|drawwholepath|drawpoints|drawpointoptions|drawpointlabels|drawpoint|drawpathoptions|drawpathonly|drawpath|drawoutlinetext|draworiginoptions|draworigin|drawlineoptions|drawlabeloptions|drawfill|drawdoublearrows|drawcontrolpoints|drawcontroloptions|drawcontrollines|drawboundoptions|drawboundingbox|drawboundary|dquote|dppart|downtriangle|dofill|dodraw|disposehash|dispose|dimension|detailpaths|detaileddraw|defineshade|decorated|ddecimal|dddecimal|ddddecimal|cutends|curvedpath|curvedpairs|curvedfunction|curved|crossingunder|crossed|crlf|cotd|cot|cosh|cos|cornered|copylist|constructedpath|constructedpairs|constructedfunction|condition|complemented|complementary|comment|colortype|colorpart|colorlike|colordecimalslist|colordecimals|cmyk|clearxy|circularpath|checkedbounds|checkbounds|centerarrow|center|break|boundingradius|boundingpoint|boundingcircle|boundingbox|bottomenlarged|bottomboundary|blownup|blackcolor|bitmapimage|bcircle|bbwidth|bbheight|basiccolors|autoalign|atan|asinh|asin|asgroup|arrowpath|area|anchored|along|addbackground|acosh|acos|SPACE|PERCENT|MP|DQUOTE|CRLF)(?=[^a-zA-Z\u005C_@!?-ÿ])",
+ "match" : "(zmod|ystretched|ysized|xysized|xyscaled|xstretched|xsized|withtransparency|withshadevector|withshadetransform|withshadestep|withshaderadius|withshadeorigin|withshademethod|withshadefraction|withshadefactor|withshadedomain|withshadedirection|withshadecolors|withshadecenter|withshade|withproperties|withopacity|withmask|withlinearshade|withgrey|withgray|withcircularshade|whitecolor|wdpart|visualizepaths|visualizedfill|visualizeddraw|verbatim|validtexbox|utfsub|utfnum|utflen|urtriangle|urmoved|urenlarged|urcircle|uptriangle|unspiked|unitvector|unittriangle|unitdiamond|unitcircle|uniquelist|undrawfill|undecorated|undashed|uncolored|ultriangle|ulmoved|ulenlarged|ulcircle|tripled|triangle|transparent|transparency|tostring|topenlarged|topboundary|topath|topair|tolist|tohash|tocycle|thetextext|thetexbox|theoffset|thelabel|thefmttext|texvar|texvar|textextoffset|textext|texstr|texstr|texmode|texbox|tensecircle|tcircle|tanh|tand|tan|systemmode|superellipsed|strut|stretched|straightpath|straightpairs|straightfunction|stoppassingvariable|startpassingvariable|squeezed|squarepath|sqr|spotcolor|space|sortlist|softened|snapped|smoothed|sized|sinh|sin|simplified|shownshadevector|shownshadeorigin|shownshadedirection|shownshadecenter|shortened|shapedlist|shadedup|shadedright|shadedleft|shadedinto|shadeddown|shaded|settoks|setmacro|setglobaltoks|setglobalmacro|setglobaldimen|setglobalcount|setdimen|setcount|scriptindex|rule|roundedsquare|righttriangle|rightof|rightenlarged|rightboundary|rightarrow|resolvedcolor|resetdrawoptions|resetarrows|report|register|redecorated|readfile|rcircle|rawtextext|rawtexbox|rawmadetext|rawfmttext|randomshifted|randomizedcontrols|randomized|radian|quote|quotation|pushcurrentpicture|pushboundingbox|punked|property|properties|prefix|prefix|pow|positionxy|positionwhd|positionregion|positionpxy|positionpath|positionpage|positioninregion|positioncurve|positionbox|positionatanchor|positionanchor|popcurrentpicture|popboundingbox|pointof|pi|perpendicular|percent|penpoint|pencilled|peepholed|pathconnectors|passvariable|passarrayvariable|paralleled|paired|outsideof|outlinetexttopath|outlinetext|outerboundingbox|originpath|onlayer|onetimetextext|onetimefmttext|oddly|nothing|notcached|normalfill|normaldraw|nofill|nodraw|newtransform|newstring|newscriptindex|newrgbcolor|newpicture|newpath|newpair|newnumeric|newhash|newcolor|newcmykcolor|newboolean|naturalizepaths|namedcolor|multitonecolor|mpvar|mp|mirroredabout|mirrored|lualist|luacall|lua|lrtriangle|lrmoved|lrenlarged|lrcircle|log|loadmodule|loadimage|loadfile|loadfigure|ln|lltriangle|llmoved|llenlarged|llcircle|listtolines|listtocurves|listsize|listlast|linearpath|lefttriangle|leftof|leftenlarged|leftboundary|leftarrow|lcircle|laddered|label|keepcached|istextext|isobject|isarray|isarray|invtan|invsin|inverted|invcos|inv|intersection_point|intersection_found|interpolated|insideof|inpath|innerboundingbox|inhash|infont|infinite|htpart|greyscale|greyed|grayscale|grayed|graphictext|gettoks|getmacro|getdimen|getcount|function|fulltriangle|fullsquare|fulldiamond|formatted|format|fmttext|fillup|filloutlinetext|figure|externalfigure|exp|evenly|epsed|eofillup|eofill|eoclip|enlonged|enlarged|drawwholepath|drawpoints|drawpointoptions|drawpointlabels|drawpoint|drawpathoptions|drawpathonly|drawpath|drawoutlinetext|draworiginoptions|draworigin|drawlineoptions|drawlabeloptions|drawfill|drawdoublearrows|drawcontrolpoints|drawcontroloptions|drawcontrollines|drawboundoptions|drawboundingbox|drawboundary|dquote|dppart|downtriangle|dofill|dodraw|disposehash|dispose|dimension|detailpaths|detaileddraw|defineshade|decorated|ddecimal|dddecimal|ddddecimal|cutends|curvedpath|curvedpairs|curvedfunction|curved|crossingunder|crossed|crlf|cotd|cot|cosh|cos|cornered|copylist|constructedpath|constructedpairs|constructedfunction|condition|complemented|complementary|comment|colortype|colorpart|colorlike|colordecimalslist|colordecimals|cmyk|clearxy|circularpath|checkedbounds|checkbounds|centerarrow|center|break|boundingradius|boundingpoint|boundingcircle|boundingbox|bottomenlarged|bottomboundary|blownup|blackcolor|bitmapimage|bcircle|bbwidth|bbheight|basiccolors|autoalign|atan|asinh|asin|asgroup|arrowpath|area|anchored|along|addbackground|acosh|acos|SPACE|PERCENT|MP|DQUOTE|CRLF)(?=[^a-zA-Z\u005C_@!?-ÿ])",
"name" : "context.command.metafun.helper.mps"
},
"identifier" : {
diff --git a/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf b/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf
new file mode 100644
index 000000000..95888d64e
--- /dev/null
+++ b/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
index 9de79c5ee..9a097b878 100644
--- a/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
@@ -9,9 +9,7 @@
[title=boxes,
color=middlered]
-\startsection[title=Preamble]
-
-\startsubsection[title=Introduction]
+\startsection[title=Introduction]
An average \CONTEXT\ user will not use the low level box primitives but a basic
understanding of how \TEX\ works doesn't hurt. In fact, occasionally using a box
@@ -25,9 +23,9 @@ about all kind of glues, kerns and penalties, just boxes it is.
This explanation will be extended when I feel the need (or users have questions
that can be answered here).
-\stopsubsection
+\stopsection
-\startsubsection[title=Boxes]
+\startsection[title=Boxes]
This paragraph of text is made from lines that contain words that themselves
contain symbolic representations of characters. Each line is wrapped in a so
@@ -68,7 +66,7 @@ other hand wraps a linked list of so called nodes: glyphs, kerns, glue,
penalties, rules, boxes, etc. It is a container with properties like width,
height, depth and shift.
-\stopsubsection
+\stopsection
\stopsection
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex
new file mode 100644
index 000000000..a7a7fddf3
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex
@@ -0,0 +1,423 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=paragraphs,
+ color=middlecyan]
+
+\startsection[title=Introduction]
+
+This manual is mostly discussing a few wrappers around low level \TEX\ features.
+Its writing is triggered by an update to the \METAFUN\ and \LUAMETAFUN\ manuals
+where we mess a bit with shapes. It gave a good reason to also cover some more
+paragraph related topics but it might take a while to complete. Remind me if you
+feel that takes too much time.
+
+\stopsection
+
+\startsection[title=Properties]
+
+A paragraph is just a collection of lines that result from one input line that
+got broken. This process of breaking into lines is influenced by quite some
+parameters. In traditional \TEX\ and also in \LUAMETATEX\ by default the values
+that are in effect when the end of the paragraph is met are used. So, when you
+change them in a group and then ends the paragraph after the group, the values
+you've set in the group are not used.
+
+However, in \LUAMETATEX\ we can optionally store them with the paragraph. When
+that happens the values current at the start are frozen. You can still overload
+them but that has to be done explicitly then. The advantage is that grouping no
+longer interferes with the line break algorithm. The magic primitive is \type
+{\snapshotpar}.
+
+\starttabulate
+\NC \type {\hsize} \NC \NC \NR
+\NC \type {\leftskip} \NC \NC \NR
+\NC \type {\rightskip} \NC \NC \NR
+\NC \type {\hangindent} \NC \NC \NR
+\NC \type {\hangafter} \NC \NC \NR
+\NC \type {\parindent} \NC \NC \NR
+\NC \type {\parfillleftskip} \NC \NC \NR
+\NC \type {\parfillrightskip} \NC \NC \NR
+\NC \type {\adjustspacing} \NC \NC \NR
+\NC \type {\protrudechars} \NC \NC \NR
+\NC \type {\pretolerance} \NC \NC \NR
+\NC \type {\tolerance} \NC \NC \NR
+\NC \type {\emergencystretch} \NC \NC \NR
+\NC \type {\looseness} \NC \NC \NR
+\NC \type {\lastlinefit} \NC \NC \NR
+\NC \type {\linepenalty} \NC \NC \NR
+\NC \type {\interlinepenalty} \NC \NC \NR
+\NC \type {\clubpenalty} \NC \NC \NR
+\NC \type {\widowpenalty} \NC \NC \NR
+\NC \type {\displaywidowpenalty} \NC \NC \NR
+\NC \type {\brokenpenalty} \NC \NC \NR
+\NC \type {\adjdemerits} \NC \NC \NR
+\NC \type {\doublehyphendemerits} \NC \NC \NR
+\NC \type {\finalhyphendemerits} \NC \NC \NR
+\NC \type {\parshape} \NC \NC \NR
+\NC \type {\interlinepenalties} \NC \NC \NR
+\NC \type {\clubpenalties} \NC \NC \NR
+\NC \type {\widowpenalties} \NC \NC \NR
+\NC \type {\displaywidowpenalties} \NC \NC \NR
+\NC \type {\baselineskip} \NC \NC \NR
+\NC \type {\lineskip} \NC \NC \NR
+\NC \type {\lineskiplimit} \NC \NC \NR
+\NC \type {\adjustspacingstep} \NC \NC \NR
+\NC \type {\adjustspacingshrink} \NC \NC \NR
+\NC \type {\adjustspacingstretch} \NC \NC \NR
+\NC \type {\hyphenationmode} \NC \NC \NR
+\stoptabulate
+
+There are more paragraph related parameters than in for instance \PDFTEX\ and
+\LUATEX\ and these are (to be) explained in the \LUAMETATEX\ manual. You can
+imagine that keeping this around with the paragraph adds some extra overhead to
+the machinery but most users won't notice that because is is compensated by gains
+elsewhere.
+
+In \LMTX\ taking these snapshots is turned on by default and because it thereby
+fundamentally influences the par builder, users can run into compatibility issues
+but in practice there has been no complaints (and this feature has been in use
+quite a while before this document was written). One reason for users not
+noticing is that one of the big benefits is probably handled by tricks mentioned on the
+mailing list. Imagine that you have this:
+
+\starttyping[option=TEX]
+{\bf watch out:} here is some text
+\stoptyping
+
+In this small example the result will be as expected. But what if something magic
+with the start of a paragraph is done? Like this:
+
+\starttyping[option=TEX]
+\placefigure[left]{A cow!}{\externalfigure[cow.pdf]}
+
+{\bf watch out:} here is some text ... of course much more is needed to
+ get a flow around the figure!
+\stoptyping
+
+The figure will hang at the left side of the paragraph but it is put there when
+the text starts and that happens inside the bold group. It means that the
+properties we set in order to get the shape around the figure are lost as soon as
+we're at \quote{\type {here is some text}} and definitely is wrong when the
+paragraph ends and the par builder has to use them to get the shape right. We get
+text overlapping the figure. A trick to overcome this is:
+
+\starttyping[option=TEX]
+\dontleavehmode {\bf watch out:} here is some text ... of course much
+ more is needed to get a flow around the figure!
+\stoptyping
+
+where the first macro makes sure we already start a paragraph before the group is
+entered (using a \type {\strut} also works). It's not nice and I bet users have
+been bitten by this and by now know the tricks. But, with snapshots such fuzzy
+hacks are not needed any more! The same is true with this:
+
+\starttyping[option=TEX]
+{\leftskip 1em some text \par}
+\stoptyping
+
+where we had to explicitly end the paragraph inside the group in order to retain
+the skip. I suppose that users normally use the high level environments so they
+never had to worry about this. It's also why users probably won't notice that
+this new mechanism has been active for a while. Actually, when you now change a
+parameter inside the paragraph will not be applied (unless you prefix it with
+\type {\frozen}) but no one did that anyway.
+
+{\em todo: freeze categories, overloading, turning on and off, etc}
+
+\stopsection
+
+\startsection[title=Wraping up]
+
+In \CONTEXT\ \LMTX\ we have a mechanism to exercise macros (or content) before a
+paragraph ends. This is implemented using the \type {\wrapuppar} primitive. The
+to be wrapped up material is bound to the current paragraph which in order to
+get this done has to be started when this primitive is used.
+
+Although the high level interface has been around for a while it still needs a
+bit more testing (read: use cases are needed). In the few cases where we already
+use it application can be different because again it relates to snapshots. This
+because in the past we had to use tricks that also influenced the user interface
+of some macros (which made them less natural as one would expect). So the
+question is: where do we apply it in old mechanisms and where not.
+
+{\em todo: accumulation, interference, where applied, limitations}
+
+% \vbox {vbox : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% \vtop {vtop : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% \vcenter{vcenter : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% $$x = \vcenter{vcenter : \wrapuppar{1}test\par x\wrapuppar{2}test}$$\blank
+% x\vadjust{vadjust : \wrapuppar{1}test\par x\wrapuppar{2}test}x\blank
+
+\stopsection
+
+\startsection[title=Shapes]
+
+In \CONTEXT\ we don't use \type {\parshape} a lot. It is used in for instance
+side floats but even then not in all cases. It's more meant for special
+applications. This means that in \MKII\ and \MKIV\ we don't have some high level
+interface. However, when \METAFUN\ got upgraded to \LUAMETAFUN, and the manual
+also needed an update, one of the examples in that manual that used shapes also
+got done differently (read: nicer). And that triggered the arrival of a new high
+level shape mechanism.
+
+One important property of the \type {\parshape} mechanism is that it works per
+paragraph. You define a shape in terms of a left margin and width of a line. The
+shape has a fixed number of such pairs and when there is more content, the last one
+is used for the rest of the lines. When the paragraph is finished, the shape is
+forgotten.
+
+{\em Not discussed here is a variant that will end up in \LUAMETATEX\ that works
+with the progression, i.e.\ takes the height of the content so far into account.
+This is somewhat tricky because for that to work vertical skips need to be
+frozen, which is no real big deal but has to be done careful in the code.}
+
+The high level interface is a follow up on the example in the \METAFUN\ manual and
+uses shapes that carry over to the next paragraph. In addition we can cycle over
+a shape. In this interface shapes are defined using keyword. Here are some
+examples:
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 5mm right 5mm
+\stopparagraphshape
+\stoptyping
+
+This shape has only two entries so the first line will have a 1mm margin while
+later lines will get 5mm margins. This translates into a \type {\parshape} like:
+
+\starttyping[option=TEX]
+\parshape 2
+ 1mm \dimexpr\hsize-1mm\relax
+ 5mm \dimexpr\hsize-5mm\relax
+\stoptyping
+
+Watch the number \type {2}: it tells how many specification lines follow. As you
+see, we need to calculate the width.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 5mm right 5mm
+ repeat
+\stopparagraphshape
+\stoptyping
+
+This variant will alternate between 1mm and 5mm margins. The repeating feature is
+translated as follows. Maybe at some point I will introduce a few more options.
+
+\starttyping[option=TEX]
+\parshape 2 options 1
+ 1mm \dimexpr\hsize-1mm\relax
+ 5mm \dimexpr\hsize-5mm\relax
+\stoptyping
+
+A shape can have some repetition, and we can save keystrokes by copying the last
+entry. The resulting \type {\parshape} becomes rather long.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 2mm right 2mm
+ left 3mm right 3mm
+ copy 8
+ left 4mm right 4mm
+ left 5mm right 5mm
+ left 5mm hsize 10cm
+\stopparagraphshape
+\stoptyping
+
+Also watch the \type {hsize} keyword: we don't calculate the hsize from the \type
+{left} and \type {right} values but explicitly set it.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ right 3mm
+ left 5mm right 5mm
+ repeat
+\stopparagraphshape
+\stoptyping
+
+When a \type {right} keywords comes first the \type {left} is assumed to be zero.
+In the examples that follow we will use a couple of definitions:
+
+\startbuffer[setup]
+\startparagraphshape[test]
+ both 1mm both 2mm both 3mm both 4mm both 5mm both 6mm
+ both 7mm both 6mm both 5mm both 4mm both 3mm both 2mm
+\stopparagraphshape
+\stopbuffer
+
+\startbuffer[setup-repeat]
+\startparagraphshape[test-repeat]
+ both 1mm both 2mm both 3mm both 4mm both 5mm both 6mm
+ both 7mm both 6mm both 5mm both 4mm both 3mm both 2mm
+ repeat
+\stopparagraphshape
+\stopbuffer
+
+\typebuffer[setup,setup-repeat][option=TEX]
+
+The last one could also be defines as:
+
+\starttyping[option=TEX]
+\startparagraphshape[test-repeat]
+ \rawparagraphshape{test} repeat
+\stopparagraphshape
+\stoptyping
+
+In the previous code we already introduced the \type {repeat} option. This will
+make the shape repeat at the engine level when the shape runs out of specified
+lines. In the application of a shape definition we can specify a \type {method}
+to be used and that determine if the next paragraph will start where we left off
+and discard afterwards (\type {shift}) or that we move the discarded lines up
+front so that we never run out of lines (\type {cycle}). It sounds complicated
+but just keep in mind that \type {repeat} is part of the \type {\parshape} and
+act within a paragraph while \type {shift} and \type {cycle} are applied when a
+new paragraph is started.
+
+\startbuffer[demo]
+\startshapedparagraph[list=test]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-repeat]
+\startshapedparagraph[list=test-repeat]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+In \in {figure} [fig:shape:discard] you see the following applied:
+
+\typebuffer[demo,demo-repeat][option=TEX]
+
+\startplacefigure[title=Discarded shaping,reference=fig:shape:discard]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup,demo][page=1,width=.4\textwidth,frame=on]} {discard, finite shape, page 1}
+ {\typesetbuffer[setup,demo][page=2,width=.4\textwidth,frame=on]} {discard, finite shape, page 2}
+ {\typesetbuffer[setup-repeat,demo-repeat][page=1,width=.4\textwidth,frame=on]} {discard, repeat in shape, page 1}
+ {\typesetbuffer[setup-repeat,demo-repeat][page=2,width=.4\textwidth,frame=on]} {discard, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+In \in {figure} [fig:shape:shift] we use this instead:
+
+\startbuffer[demo]
+\startshapedparagraph[list=test,method=shift]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-shift]
+\startshapedparagraph[list=test-repeat,method=shift]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[demo,demo-repeat][option=TEX]
+
+\startplacefigure[title=Shifted shaping,,reference=fig:shape:shift]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup,demo][page=1,width=.4\textwidth,frame=on]} {shift, finite shape, page 1}
+ {\typesetbuffer[setup,demo][page=2,width=.4\textwidth,frame=on]} {shift, finite shape, page 2}
+ {\typesetbuffer[setup-repeat,demo-shift][page=1,width=.4\textwidth,frame=on]} {shift, repeat in shape, page 1}
+ {\typesetbuffer[setup-repeat,demo-shift][page=2,width=.4\textwidth,frame=on]} {shift, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+Finally, in \in {figure} [fig:shape:cycle] we use:
+
+\startbuffer[demo]
+\startshapedparagraph[list=test,method=cycle]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-cycle]
+\startshapedparagraph[list=test-repeat,method=cycle]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[demo,demo-repeat][option=TEX]
+
+\startplacefigure[title=Cycled shaping,reference=fig:shape:cycle]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup,demo][page=1,width=.4\textwidth,frame=on]} {cycle, finite shape, page 1}
+ {\typesetbuffer[setup,demo][page=2,width=.4\textwidth,frame=on]} {cycle, finite shape, page 2}
+ {\typesetbuffer[setup-repeat,demo-cycle][page=1,width=.4\textwidth,frame=on]} {cycle, repeat in shape, page 1}
+ {\typesetbuffer[setup-repeat,demo-cycle][page=2,width=.4\textwidth,frame=on]} {cycle, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+These examples are probably too small to see the details but you can run them
+yourself or zoom in on the details. In the margin we show the values used. Here
+is a simple example of (non) poetry. There are other environments that can be
+used instead but this makes a good example anyway.
+
+\startbuffer
+\startparagraphshape[test]
+ left 0em right 0em
+ left 1em right 0em
+ repeat
+\stopparagraphshape
+
+\startshapedparagraph[list=test,method=cycle]
+ verse line 1.1\crlf verse line 2.1\crlf
+ verse line 3.1\crlf verse line 4.1\par
+ verse line 1.2\crlf verse line 2.2\crlf
+ verse line 3.2\crlf verse line 4.2\crlf
+ verse line 5.2\crlf verse line 6.2\par
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\getbuffer
+
+{\em todo: move the new (still in {\em \type {meta-imp-txt.mkxl})} code into the
+core and integrate it in {\em \type {\startshapedparagraph}} as method {\em \type
+{mp}} in which case the list is a list of graphics.}
+
+\starttyping[option=TEX]
+\startshapedparagraph[list={test 1,test 2,test 3,test 4},method=mp]
+ .....
+\stopshapedparagraph
+\stoptyping
+
+{\em So methods then become kind of plugins.}
+
+A mechanism like this is often never completely automatic in the sense that you
+need to keep an eye on the results. Depending on user demands more features can
+be added. With weird shapes you might want to set up the alignment to be \type
+{tolerant} and have some \type {stretch}.
+
+\stopsection
+
+% \startsection[title=Linebreaks]
+\startsection[title=Modes]
+
+% \ruledvbox{1\ifhmode\writestatus{!}{HMODE 1}\fi} % hsize
+% \ruledvbox{\hbox{\strut 2}\ifhmode\writestatus{!}{HMODE 2}\fi} % fit
+% \ruledvbox{\hbox{\strut 3}\hbox{\strut 3}\ifhmode\writestatus{!}{HMODE 3}\fi} % fit
+% \ruledvbox{\hbox{\strut 4}4\ifhmode\writestatus{!}{HMODE 4}\fi} % hsize
+% \ruledvbox{\hbox{\strut 5}5\hbox{\strut 5}\ifhmode\writestatus{!}{HMODE 5}\fi} % hsize
+% \ruledvbox{6\hbox{\strut 6}\ifhmode\writestatus{!}{HMODE 6}\fi} % hsize
+
+{\em todo: some of the side effects of so called modes}
+
+\stopsection
+
+\startsection[title=Normalization]
+
+{\em todo: users don't need to bother about this but it might be interesting anyway}
+
+\stopsection
+
+\stopdocument
+
diff --git a/doc/context/sources/general/manuals/metafun/metafun-basics.tex b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
index 27d2f5fdf..92d2f2c07 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-basics.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
@@ -463,7 +463,7 @@ draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
You can consider the \type {boundingcircle} to be a round boundingbox.
-\startlinecorrection
+\startlinecorrection[blank]
\startcombination[nx=3,ny=1,location=middle]
{\processMPbuffer[a]} {square}
{\processMPbuffer[b]} {circle}
@@ -3596,6 +3596,70 @@ a default value of 20.
\stopsection
+\startsection[title=Grouping]
+
+The grouping model in \METAPOST\ is kind of special. Basically anything that
+happens in a group is processed in some nested action and doesn't interfere with
+the outside. However, the last value put (back) into the input is picked up after
+the group. A \type {vardef} acts that way:
+
+\startbuffer
+vardef foo (expr i, j) =
+ save ii, jj ; ii := 2*i ; jj :=j/2 ;
+ (i, j) -- (ii,jj)
+enddef ;
+
+draw (foo(1,2) .. foo(5,1) .. foo(12,3))
+ ysized 1cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+
+draw boundingbox currentpicture withcolor darkyellow ;
+\stopbuffer
+
+\typebuffer
+
+This weird shape comes out:
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+We save two variables, and then give new local numerics with their names some
+values. Then we \quote {return} a path. A \type {vardef} automatically starts
+with a \type {begingroup} and ends with an \type {endgroup}. The next example
+shows how we can use that grouping trick directly. The \type {--} has to come
+before the \type {begingroup}.
+
+\startbuffer
+vardef turtle expr p =
+ save a ; pair a ; a := point 0 of p ; a
+ for i = 1 upto length(p) if cycle p : - 1 fi :
+ -- begingroup a := a shifted point i of p ; a endgroup
+ endfor
+ if cycle p : -- cycle fi
+enddef ;
+
+draw ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
+ withpen pencircle scaled 2 withcolor darkred ;
+draw turtle ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
+ withpen pencircle scaled 2 withcolor darkyellow ;
+\stopbuffer
+
+\typebuffer
+
+Turtle graphics use relative positions. Actually they use one number and switch
+direction but the above is okay too. Effectively we loop over the path and use
+each point as a relative move, so we recalculate it.
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+We could have said \type {-- hide(a := a shifted point i of p) a} because the
+\type {hide} macro does that the grouping trick.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-debugging.tex b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
index 4174d34e1..de863aea0 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
@@ -56,9 +56,8 @@ parent point with thin lines.
\processMPbuffer
\stoplinecorrection
-You can deduce the direction of a path from the way the
-points are numbered, but using an arrow to indicate the
-direction is more clear.
+You can deduce the direction of a path from the way the points are numbered, but
+using an arrow to indicate the direction is more clear.
\startbuffer
path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
@@ -378,6 +377,164 @@ When we overlay these three we get. The envelope only returns the outer curve.
\stopsection
+\startsection[title=Performance]
+
+On the average performance of \METAPOST\ is quite okay. The original program uses
+scaled numbers, which are floats packed into an integer. The library also
+supports doubles, decimal and binary number models. In \CONTEXT\ we only support
+scaled, double and decimal. Because the library has to support multiple models
+there is more overhead and therefore it is also slower. There's also more dynamic
+memory allocation going on. In the transition from \MKII\ to \MKIV\ some of the
+critical code (like the code involved in passing \TEX\ states to \METAPOST) had
+to be optimized, although when the \LUA\ interface was added, betters ways became
+possible. We have to accept the penalty in performance and often can gain back a
+lot because we have the \LUA\ interface.
+
+One of the main bottlenecks in storing quantities. \footnote {Recently, Taco
+Hoekwater has done some excellent explanations about the way \METAPOST\ scans the
+input and create variables and you can find his presentations at meetings on the
+\CONTEXT\ garden.} When we see something \type {a[1]} and \type {a[3]} the \type
+{a} is a root variable and the \type {1} and {3} are entries in a linked list
+from that root. It's not an array in the sense that there is some upper bound and
+that there's also a slot \type {2}. There is order but the list is sparse. When
+access is needed, for instance to do some calculations, a linear lookup (from the
+head of the list) takes place. This is quite okay performance wise because
+normally these list are small. The same is true for a path, which is also a
+linked list. If you need point 25, it is looked up by starting at the first knot
+of the path. The longer the path, the more time it takes to reach arbitrary
+points. In the \LUA\ chapter we give an example of how to get around that
+limitation.
+
+Concerning the arrays, here is s trick to get around a performance bottleneck:
+
+\starttyping
+numeric foo[];
+
+def set_foo(expr c, s) =
+ foo[c] := s ;
+enddef ;
+
+def get_foo(expr c) =
+ foo[c]
+enddef ;
+\stoptyping
+
+If you use this as follows:
+
+\starttyping
+numeric n ; n = 123 ;
+
+for i=1 upto 20000 :
+ set_foo(i,n) ;
+endfor ;
+
+for i=1 upto 20000 :
+ n := get_foo(i) ;
+endfor ;
+\stoptyping
+
+the runtime can (for instance) be 3.3 seconds, but when you use the following
+variant, it goes down to 0.13 seconds.
+
+\starttyping
+numeric foo[][][][]; % 12345 : 1 12 123 44 instead of 12344
+
+def set_foo(expr c, s) =
+ foo[c div 10000][c div 1000][c div 100][c] := s ;
+enddef ;
+def get_foo(expr c) =
+ foo[c div 10000][c div 1000][c div 100][c]
+enddef ;
+\stoptyping
+
+This time the lookup is not split into phases each being relatively fast. So, in
+order to reach slot 1234 the engine doesn't have to check and jump over what
+comes before that. You basically create a tree here: 0 (hit), 1000 (hit in one),
+200 (hit in two), 34 (hit in 34). We could go to a single digit but that doesn't
+save much. Before we had ways to store data at the \LUA\ end we used this a few
+times in macros that dealt with data (like Alan Braslau's node and graphics
+modules). This is typically something one can figure out by looking at the (non
+trivial) source code.
+
+Here is another example. In \LUA\ we can easily create a large file, like this:
+
+\starttyping
+\startluacode
+ local t = { }
+ for i=1,10000 do
+ t[i] = string.rep(
+ "here we have number " ..
+ tostring(i) ..
+ " out of the 10000 numbers that we will test"
+ ,100)
+ end
+ t = table.concat(t,"\n")
+ io.savedata("foo1.tmp",t)
+ io.savedata("foo2.tmp",t)
+ io.savedata("foo3.tmp",t)
+\stopluacode
+\stoptyping
+
+We make two copies because we do two experiments and we want to treat them equal with
+respect to caching.
+
+\starttyping
+\startMPcode
+ string f ; f := "foo1.tmp" ;
+ string s[] ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ s[i] := readfrom f ;
+ exitif s[i] = EOF ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+Say that this runs in 2.2 seconds, how come that the next one runs in 1.7 seconds
+instead?
+
+\starttyping
+\startMPcode
+ string f ; f := "foo2.tmp" ;
+ string s[] ;
+ string ss ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ ss := readfrom f ;
+ exitif ss = EOF ;
+ s[i] := ss ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+The main reason is that the first case we have two lookups in the linked list
+that determines variable \type {s} and the longer the list, the more time it will
+take. In the second case we use an intermediate variable. Although that means
+extra memory (de)allocation it still pays of. In practice you don't need to worry
+too much about it but of course we can again follow the tree approach:
+
+\startMPcode
+ string f ; f := "foo3.tmp" ;
+ string s[][][] ;
+ string ss ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ ss := readfrom f ;
+ exitif ss = EOF ;
+ s[i div 1000][i div 100][i] := ss ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+
+This time we go down to 1.5 second. Timings could be a bit different in \MKIV\ and
+\LMTX\ because in \LUAMETATEX\ all \METAPOST\ file \IO\ goes through \LUA\ but the
+relative performance gains are the same. With \LUATEX\ and \MKIV\ I measures
+2.9, 2.5 and 2.1 and with \LUAMETATEX\ and \LMTX\ I got 2.3, 1.7 and 1.5.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-examples.tex b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
index 4e5e0eed3..5549a3bdd 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-examples.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
@@ -3264,6 +3264,259 @@ We get:
\stopsection
+\startsection[title=Educational]
+
+I made this example long ago, when some family member had to learn tables by
+heart. For some reason, at school, this is made into a complex issue, with tricks
+and such, even it if only involves only a few numbers. My own experience (if I
+remember right) was that some of these numbers are trivial, and that there is
+quite some symmetry, so in practice only a quarter needs to be remembered. And,
+assuming that you can easily deduct the trivial cases, one can just calculate the
+rest if needed.
+
+\startbuffer
+\start \ttbf \startMPcode
+ def MyDraw(expr i, j, c) =
+ fill fullsquare shifted (i,j) withcolor c withtransparency (1,.5) ;
+ enddef ;
+
+ for i = 1 upto 10 :
+ for j = 1 upto 10 : MyDraw( i, -j, "middlered" ) ; endfor ; endfor ;
+
+ for j = 1 upto 10 : MyDraw( 1, -j, "middleblue" ) ; endfor ;
+ for i = 1 upto 10 : MyDraw( i, -10, "middlegreen" ) ; endfor ;
+ for i = 1 upto 10 : MyDraw( i, -1, "middleyellow") ; endfor ;
+ for j = 1 upto 10 : MyDraw(10, -j, "middlecyan" ) ; endfor ;
+ for j = 1 upto 10 : MyDraw( 5, -j, "middlegray" ) ; endfor ;
+ for j = 1 upto 10 : MyDraw( j, -j, "middlegray" ) ; endfor ;
+
+ draw image ( for i = 1 upto 10 : for j = 1 upto 10 :
+ draw textext(decimal (i*j)) ysized .25 shifted (i,-j) ;
+ endfor ; endfor ; ) withcolor white ;
+
+ currentpicture := currentpicture ysized 10cm ;
+\stopMPcode \stop
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:tentable]
+ \getbuffer
+\stopplacefigure
+
+Here we use both transparency and colors to stress the reduction of cases. The
+named colors resolve to ones defined at the \TEX\ end. We see the redndering
+\in {figure} [fig:tentable].
+
+\startsection[title=Glyph magic]
+
+The next example is the result of a tread on the mailing list. After Henri Menke
+posted a some glyph overlap code, I made a variant that more suited the way we do
+it in \METAFUN. In the meantime Floris van Maanen had found out that some glyphs
+need a more inventive solution so after that the code evolved. By then the \type
+{outlinetext}, \type {drawoutlinetext} and \type {filloutlinetext} helpers had
+been added to the code base.
+
+Because this is complicated stuff, we just show the two solutions. The first one
+is a relative simple one, the second one uses an approach suggested by Alan
+Braslau and therefore uses some of the code that can be found in the \type
+{crossingunder} macro.
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlapInOutlinesA(expr first, second) =
+ path p_i, p_j, s_i, s_j ;
+ numeric n_i, n_j, index ;
+ pair found ;
+ index := 0 ;
+ for i within first :
+ for j within second :
+ p_i := pathpart i ; n_i := length(p_i) ;
+ p_j := pathpart j ; n_j := length(p_j) ;
+ for ii = 0 upto n_i - 1 :
+ s_i := subpath(ii,ii+1) of p_i ;
+ for jj = 0 upto n_j - 1 :
+ s_j := subpath(jj,jj+1) of p_j ;
+ found := s_i intersection_point s_j ;
+ if intersection_found :
+ index := index + 1 ;
+ drawdot found
+ withpen pencircle scaled 4 withcolor white ;
+ draw textext("\strut\ttbf " & decimal index) ysized 3
+ shifted found ;
+ fi ;
+ endfor ;
+ endfor ;
+ endfor ;
+ endfor ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This is the solution based on \type {crossingunder}, a macro that has been
+introduced as part of Alan's neat node module.
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlapInOutlinesB(expr first, second) =
+ begingroup ;
+ save p, q, n, t, a, b, c, bcuttings, hold, found ;
+ path p, q ;
+ numeric n, hold ;
+ path a, b, c, bcuttings ;
+ pair found ;
+ c := makepath(currentpen scaled crossingscale) ;
+ for f within first :
+ numeric t[];
+ path hold[];
+ t[0] := n := hold := 0 ;
+ for s within second :
+ p := pathpart f ;
+ q := pathpart s ;
+ a := p ;
+ for i=1 upto crossingnumbermax : % safeguard
+ clearxy ; z = a intersectiontimes q ;
+ if x < 0 :
+ exitif hold < 1 ;
+ a := hold[hold] ; hold := hold - 1 ;
+ clearxy ; z = a intersectiontimes q ;
+ fi
+ (t[incr n], whatever) = p intersectiontimes point x of a ;
+ if x = 0 :
+ a := a cutbefore c shifted point x of a ;
+ elseif x = length a :
+ a := a cutafter c shifted point x of a ;
+ else : % before or after?
+ b := subpath (0,x) of a cutafter c shifted point x of a ;
+ bcuttings := cuttings ;
+ a := subpath (x,length a) of a cutbefore c shifted point x of a ;
+ clearxy ; z = a intersectiontimes q ;
+ if x < 0 :
+ a := b ;
+ cuttings := bcuttings ;
+ elseif length bcuttings > 0 :
+ clearxy ; z = b intersectiontimes q ;
+ if x >= 0 :
+ hold[incr hold] := b ;
+ fi
+ fi
+ fi
+ if length cuttings = 0 :
+ exitif hold < 1 ;
+ a := hold[hold] ; hold := hold - 1 ;
+ fi
+ endfor ;
+ endfor ;
+ t[incr n] = length p ;
+ for i=1 upto n :
+ found := point t[i] of p ;
+ drawdot found
+ withpen pencircle scaled 4 withcolor white ;
+ draw textext("\strut\ttbf " & decimal i) ysized 3
+ shifted found ;
+ endfor ;
+ endfor ;
+ endgroup ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We demonstrate the differences with an example. The result can be seen in
+\in {figure} [fig:overlapping:a].
+
+\startbuffer
+\startcombination
+ {\startMPcode
+ picture first, second ;
+ first := outlinetext.p("N") ; first := first scaled 10 ;
+ second := outlinetext.p("T") ; second := second scaled 10 ;
+ second := second rotatedaround(center second, 5) shifted (1,-1) ;
+ filloutlinetext(first ) withcolor .5[darkblue,white] ;
+ filloutlinetext(second) withcolor .5[darkred,white] ;
+ drawoutlinetext(first ) ;
+ drawoutlinetext(second) ;
+ ShowOverlapInOutlinesA(first, second) ;
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture scaled 2.5 ;
+ \stopMPcode} {Method A}
+ {\startMPcode
+ picture first, second ;
+ first := outlinetext.p("N") ; first := first scaled 10 ;
+ second := outlinetext.p("T") ; second := second scaled 10 ;
+ second := second rotatedaround(center second, 5) shifted (1,-1) ;
+ filloutlinetext(first ) withcolor .5[darkgreen,white] ;
+ filloutlinetext(second) withcolor .5[darkyellow,white] ;
+ drawoutlinetext(first ) ;
+ drawoutlinetext(second) ;
+ ShowOverlapInOutlinesB(first, second) ;
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture scaled 2.5 ;
+ \stopMPcode} {Method B}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:overlapping:a]
+ \getbuffer
+\stopplacefigure
+
+We duplicate some code because the pictures will change in the process of
+analyzing. Let's make a helper for that:
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlap(expr f, s, m) =
+ picture first, second ;
+ first := outlinetext.p(f) ; first := first scaled 10 ;
+ second := outlinetext.p(s) ; second := second scaled 10 ;
+
+ filloutlinetext(first ) withcolor darkblue ;
+ drawoutlinetext(first ) ;
+
+ filloutlinetext(second) withcolor darkred ;
+ drawoutlinetext(second) ;
+
+ if m == 2 :
+ ShowOverlapInOutlinesB
+ else :
+ ShowOverlapInOutlinesA
+ fi (first, second) ;
+
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture ysized 4cm ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Again we demonstrate the differences with some examples. The result can be seen in
+\in {figure} [fig:overlapping:b].
+
+\startbuffer
+ \startcombination[nx=3,ny=2]
+ {\startMPcode ShowOverlap("N","T",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("\$","Q",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("\tttf ABC","\tttf PQR",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("N","T",2) ; \stopMPcode} {Method 2}
+ {\startMPcode ShowOverlap("\$","Q",2) ; \stopMPcode} {Method 2}
+ {\startMPcode ShowOverlap("\tttf ABC","\tttf PQR",2) ; \stopMPcode} {Method 2}
+ \stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:overlapping:b]
+ \getbuffer
+\stopplacefigure
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
index 7cd915005..e445cef53 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-lua.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
@@ -1211,6 +1211,282 @@ just mimicking drawing the path.
\processMPbuffer
\stoplinecorrection
+\stopsection
+
+\startsection[title=Acessing \TEX]
+
+In \MKIV\ and \LMTX\ it is possible to access \TEX\ registers and macros from the
+\METAPOST\ end. Let's first define and set some:
+
+\startbuffer
+\newdimen\MyMetaDimen \MyMetaDimen = 2mm
+\newcount\MyMetaCount \MyMetaCount = 10
+\newtoks \MyMetaToks \MyMetaToks = {\bfd \TeX}
+ \def\MyMetaMacro {not done}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startMPcode
+ for i=1 upto getcount("MyMetaCount") :
+ draw fullcircle scaled (i * getdimen("MyMetaDimen")) ;
+ endfor ;
+ draw textext(gettoks("MyMetaToks")) xsized 15mm withcolor darkred ;
+ setglobaldimen("MyMetaDimen", bbwidth(currentpicture)) ;
+ setglobalmacro("MyMetaMacro", "done") ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+We can now look at the two updated globals where \type {\MyMetaMacro: \the\MyMetaDimen}
+typesets: {\tttf \MyMetaMacro: \the\MyMetaDimen}. As demonstrated you can best define your
+own registers but in principle you can also access system ones, like \type {\scratchdimen}
+and friends.
+
+\stopsection
+
+\startsection[title=Abstraction]
+
+We will now stepwise implement some simple helpers for accessing data in files.
+The examples are kind of useless but demonstrate how interfaces evolved. The
+basic command to communicate with \LUA\ is \type {runscript}. In this example
+we will load a (huge) file and run over the lines.
+
+\starttyping
+\startMPcode{doublefun}
+ save q ; string q ; q := "'\\" & ditto & "'" ;
+ runscript (
+ "GlobalData = string.splitlines(io.loaddata('foo.tmp')) return ''"
+ ) ;
+ numeric l ; l = runscript (
+ "return string.format('\letterpercent q',\letterhash GlobalData)"
+ );
+ for i=1 step 1 until l :
+ l := length ( runscript (
+ "return string.format('\letterpercent q',GlobalData[" & decimal i & "])"
+ ) ) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+The \type {runscript} primitive takes a string and should return a string (in
+\LUAMETATEX\ you can also return nothing). This low level solution will serve as
+our benchmark: it takes 2.04 seconds on the rather large (64MB) test file with
+10.000 lines.
+
+The code looks somewhat clumsy. This is because in \METAPOST\ escaping is not
+built in so one has to append a double quote character using \type {char 34} and
+the \type {ditto} string is defined as such. This mess is why in \CONTEXT\ we
+have an interface:
+
+\starttyping
+\startMPcode{doublefun}
+ lua("GlobalData = string.splitlines(io.loaddata('foo.tmp'))") ;
+ numeric l ;
+ for i=1 step 1 until lua("mp.print(\#GlobalData)") :
+ l := length(lua("mp.quoted(GlobalData[" & decimal i & "])")) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+As expected we pay a price for the additional overhead, so this time we need 2.28
+seconds to process the file. The return value of a run is a string that is fed
+into \type {scantokens}. Here \type {print} function prints the number as string
+and that gets scanned back to a number. The \type {quoted} function returns a
+string in a string so when we're back in \METAPOST\ that gets scanned as string.
+
+When code is used more frequently, we can make a small library, like this:
+
+\starttyping
+\startluacode
+ local MyData = { }
+ function mp.LoadMyData(filename)
+ MyData = string.splitlines(io.loaddata(filename))
+ end
+ local mpprint = mp.print
+ local mpquoted = mp.quoted
+ function mp.MyDataSize()
+ mpprint(#MyData)
+ end
+ function mp.MyDataString(i)
+ mpquoted(MyData[i] or "")
+ end
+\stopluacode
+\stoptyping
+
+It is not that hard to imagine a more advanced mechanisms where data from multiple
+files can be handled at the same time. This code is used as:
+
+\starttyping
+\startMPcode{doublefun}
+ lua.mp.LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until lua.mp.MyDataSize() :
+ l := length(lua.mp.MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+The \type {mp} namespace at the \LUA\ end is a subnamespace at the \METAPOST\
+end. This solution needs 2.20 seconds so we're still slower than the first one,
+but in \LUAMETATEX\ with \LMTX we can do better. First the \LUA\ code:
+
+\starttyping
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local MyData = { }
+ function mp.LoadMyData(filename)
+ MyData = string.splitlines(io.loaddata(filename))
+ end
+ function mp.MyDataSize()
+ injectnumeric(#MyData)
+ end
+ function mp.MyDataString(i)
+ injectstring(MyData[i] or "")
+ end
+\stopluacode
+\stoptyping
+
+This time we use injectors. The mentioned \type {print} helpers serialize data so
+numbers, pairs, colors etc are converted to a string that represents them that is
+fed back to \METAPOST\ after the snippet is run. Multiple prints are collected
+into one string. An injecter follows a more direct route: it pushes back a proper
+\METAPOST\ data type.
+
+\starttyping
+\startMPcode{doublefun}
+ lua.mp.LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until lua.mp.MyDataSize() :
+ l := length(lua.mp.MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+This usage brings us down to 1.14 seconds, so we're still not good. The next
+variant is performing similar: 1.05 seconds.
+
+\starttyping
+\startMPcode{doublefun}
+ runscript("mp.LoadMyData('foo.tmp')") ;
+ numeric l ;
+ for i=1 step 1 until runscript("mp.MyDataSize()") :
+ l := length(runscript("mp.MyDataString(" & decimal i & ")")) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+We will now delegate scanning to the \LUA\ end.
+
+\starttyping
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local scannumeric = mp.scan.numeric
+ local scanstring = mp.scan.string
+ local MyData = { }
+ function mp.LoadMyData()
+ MyData = string.splitlines(io.loaddata(scanstring()))
+ end
+ function mp.MyDataSize()
+ injectnumeric(#MyData)
+ end
+ function mp.MyDataString()
+ injectstring(MyData[scannumeric()] or "")
+ end
+\stopluacode
+\stoptyping
+
+This time we are faster than the clumsy code we started with: 0.87 seconds.
+
+\starttyping
+\startMPcode{doublefun}
+ runscript("mp.LoadMyData()") "foo.tmp" ;
+ numeric l ;
+ for i=1 step 1 until runscript("mp.MyDataSize()") :
+ l := length(runscript("mp.MyDataString()") i) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+In \LMTX\ we can add some more abstraction. Performance is about the same and
+sometimes a bit faster but that depends on extreme usage: you need thousands of
+call to notice.
+
+\starttyping
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local scannumeric = mp.scan.numeric
+ local scanstring = mp.scan.string
+ local MyData = { }
+ metapost.registerscript("LoadMyData", function()
+ MyData = string.splitlines(io.loaddata(scanstring()))
+ end)
+ metapost.registerscript("MyDataSize", function()
+ injectnumeric(#MyData)
+ end)
+ metapost.registerscript("MyDataString", function()
+ injectstring(MyData[scannumeric()] or "")
+ end)
+\stopluacode
+\stoptyping
+
+We have the same scripts but we register them. At the \METAPOST\ end we resolve
+the registered scripts and then call \type {runscript} with the (abstract) numeric
+value:
+
+\starttyping
+\startMPcode{doublefun}
+ newscriptindex my_script_LoadMyData ;
+ newscriptindex my_script_MyDataSize ;
+ newscriptindex my_script_MyDataString ;
+
+ my_script_LoadMyData := scriptindex "LoadMyData" ;
+ my_script_MyDataSize := scriptindex "MyDataSize" ;
+ my_script_MyDataString := scriptindex "MyDataString" ;
+
+ runscript my_script_LoadMyData "foo.tmp" ;
+ numeric l ;
+ for i=1 step 1 until runscript my_script_MyDataSize :
+ l := length(my_script_MyDataString i) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+This is of course nicer:
+
+\starttyping
+\startMPcode{doublefun}
+ def LoadMyData (expr s) = runscript my_script_LoadMyData s enddef ;
+ def MyDataSize = runscript my_script_MyDataSize enddef ;
+ def MyDataString(expr i) = runscript my_script_MyDataString i enddef ;
+
+ LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until MyDataSize :
+ l := length(MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
+\stoptyping
+
+So, to sumarize, there are many ways to look at this: verbose direct ones
+but also nicely abstract ones.
\stopsection
diff --git a/doc/context/sources/general/manuals/metafun/metafun-macros.tex b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
index e1df13c92..969e7d1b1 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-macros.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
@@ -31,12 +31,13 @@ There are several ways to use the power of \METAFUN, either or not using
\stopitem
\startitem
- You can embed the graphic in a \type {\startMPpage} construct and process it
- with \CONTEXT\ \MKIV. In that case you have the full \METAFUN\ functionality
- available. If for some reason you still want to use \MKII, you need to use
- \TEXEXEC\ as before processing the file, it will do a couple of checks on the
- file. It will also make sure that the temporary files (\type {mpt} for \type
- {textext}'s and \type {mpo} for outline fonts) are taken care of too.
+ You can embed the graphic in a \type {\startMPpage} \unknown \type
+ {\stopMPpage} construct and process it with \CONTEXT\ \MKIV. In that case you
+ have the full \METAFUN\ functionality available. If for some reason you still
+ want to use \MKII, you need to use \TEXEXEC\ as before processing the file,
+ it will do a couple of checks on the file. It will also make sure that the
+ temporary files (\type {mpt} for \type {textext}'s and \type {mpo} for
+ outline fonts) are taken care of too.
\stopitem
\startitem
diff --git a/metapost/context/base/mpiv/mp-luas.mpiv b/metapost/context/base/mpiv/mp-luas.mpiv
index 57937c0c1..2b1266a6c 100644
--- a/metapost/context/base/mpiv/mp-luas.mpiv
+++ b/metapost/context/base/mpiv/mp-luas.mpiv
@@ -149,6 +149,11 @@ def setdimen(expr k,v) = lua.mp._set_dimen_(k,v) enddef ;
def setcount(expr k,v) = lua.mp._set_count_(k,v) enddef ;
def settoks (expr k,v) = lua.mp._set_toks_ (k,v) enddef ;
+def setglobalmacro(expr k,v) = lua.mp._set_global_macro_(k,v) enddef ;
+def setglobaldimen(expr k,v) = lua.mp._set_global_dimen_(k,v) enddef ;
+def setglobalcount(expr k,v) = lua.mp._set_global_count_(k,v) enddef ;
+def setglobaltoks (expr k,v) = lua.mp._set_global_toks_ (k,v) enddef ;
+
vardef positionpath (expr name) = lua.mp.positionpath (name) enddef ;
vardef positioncurve (expr name) = lua.mp.positioncurve (name) enddef ;
vardef positionxy (expr name) = lua.mp.positionxy (name) enddef ;
diff --git a/metapost/context/base/mpxl/mp-luas.mpxl b/metapost/context/base/mpxl/mp-luas.mpxl
index 3e99ae7f7..9d013a790 100644
--- a/metapost/context/base/mpxl/mp-luas.mpxl
+++ b/metapost/context/base/mpxl/mp-luas.mpxl
@@ -161,7 +161,15 @@ newscriptindex mfid_setdimen ; mfid_setdimen := scriptindex "setdimen" ; def set
newscriptindex mfid_setcount ; mfid_setcount := scriptindex "setcount" ; def setcount(expr k, v) = runscript mfid_setcount k v ; enddef ;
newscriptindex mfid_settoks ; mfid_settoks := scriptindex "settoks" ; def settoks (expr k, v) = runscript mfid_settoks k v ; enddef ;
-permanent getmacro, getdimen, getcount, gettoks, setmacro, setdimen, setcount, settoks ;
+newscriptindex mfid_setglobalmacro ; mfid_setglobalmacro := scriptindex "setglobalmacro" ; def setglobalmacro(expr k, v) = runscript mfid_setglobalmacro k v ; enddef ;
+newscriptindex mfid_setglobaldimen ; mfid_setglobaldimen := scriptindex "setglobaldimen" ; def setglobaldimen(expr k, v) = runscript mfid_setglobaldimen k v ; enddef ;
+newscriptindex mfid_setglobalcount ; mfid_setglobalcount := scriptindex "setglobalcount" ; def setglobalcount(expr k, v) = runscript mfid_setglobalcount k v ; enddef ;
+newscriptindex mfid_setglobaltoks ; mfid_setglobaltoks := scriptindex "setglobaltoks" ; def setglobaltoks (expr k, v) = runscript mfid_setglobaltoks k v ; enddef ;
+
+permanent
+ getmacro, getdimen, getcount, gettoks,
+ setmacro, setdimen, setcount, settoks,
+ setglobalmacro, setglobaldimen, setglobalcount, setglobaltoks ;
vardef positionpath (expr name) = lua.mp.positionpath (name) enddef ;
vardef positioncurve (expr name) = lua.mp.positioncurve (name) enddef ;
diff --git a/metapost/context/base/mpxl/mp-text.mpxl b/metapost/context/base/mpxl/mp-text.mpxl
new file mode 100644
index 000000000..92329c9da
--- /dev/null
+++ b/metapost/context/base/mpxl/mp-text.mpxl
@@ -0,0 +1,157 @@
+%D \module
+%D [ file=mp-text.mpiv,
+%D version=2000.07.10,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=text support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D This one is only used in metafun so it will become a module.
+
+if known context_text : endinput ; fi ;
+
+boolean context_text ; context_text := true ;
+
+% This is still mostly the same as the one discussed in the good old \METAFUN\
+% example code but modernized abit to suit \LMTX.
+
+newscriptindex mfid_setparshapeproperty ; mfid_setparshapeproperty := scriptindex "setparshapeproperty" ;
+
+def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, strutdepth, topskip) =
+
+ if unknown trace_parshape :
+ boolean trace_parshape ; trace_parshape := false ;
+ fi ;
+
+ begingroup ;
+
+ save
+ q, l, r, line, tt, bb,
+ n, hsize, vsize, vvsize, voffset, hoffset, width, indent,
+ ll, lll, rr, rrr, cp, cq, t, b ;
+
+ path
+ q, l, r, line, tt, bb ;
+ numeric
+ n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ;
+ pair
+ ll, lll, rr, rrr, cp, cq, t, b ;
+
+ n := 0 ;
+ cp := center p ;
+
+ if path offset_or_path :
+ q := offset_or_path ;
+ cq := center q ;
+ voffset := dy ;
+ hoffset := dx ;
+ else :
+ q := p ;
+ cq := center q ;
+ hoffset := offset_or_path + dx ;
+ voffset := offset_or_path + dy ;
+ fi ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+
+ q := p shifted - cp ;
+
+ runscript mfid_setparshapeproperty "voffset" voffset ;
+ runscript mfid_setparshapeproperty "hoffset" hoffset ;
+ runscript mfid_setparshapeproperty "width" hsize ;
+ runscript mfid_setparshapeproperty "height" vsize ;
+
+ if not path offset_or_path :
+ q := q xscaled ((hsize-2hoffset)/hsize) yscaled ((vsize-2voffset)/vsize) ;
+ fi ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+
+ t := (ulcorner q -- urcorner q) intersection_point q ;
+ b := (llcorner q -- lrcorner q) intersection_point q ;
+
+ if xpart directionpoint t of q < 0 :
+ q := reverse q ;
+ fi ;
+
+ l := q cutbefore t ;
+ l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
+
+ r := q cutbefore b ;
+ r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
+
+ vardef found_point (expr lin, pat, sig) =
+ pair a, b ;
+ a := pat intersection_point (lin shifted (0,strutheight)) ;
+ if intersection_found :
+ a := a shifted (0,-strutheight) ;
+ else :
+ a := pat intersection_point lin ;
+ fi ;
+ b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ if intersection_found :
+ if sig :
+ if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ else :
+ if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ fi ;
+ fi ;
+ a
+ enddef ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ runscript mfid_setparshapeproperty "first" false ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i-eps) ;
+
+ ll := found_point(line,l,true ) ;
+ rr := found_point(line,r,false) ;
+
+ if trace_parshape :
+ fill (ll--rr--rr shifted (0,strutheight)--ll shifted (0,strutheight)--cycle) shifted cp withcolor .6white ;
+ fill (ll--rr--rr shifted (0,-strutdepth)--ll shifted (0,-strutdepth)--cycle) shifted cp withcolor .8white ;
+ draw ll shifted cp withpen pencircle scaled 2pt ;
+ draw rr shifted cp withpen pencircle scaled 2pt ;
+ draw (ll--rr) shifted cp withpen pencircle scaled .5pt ;
+ fi ;
+
+ n := n + 1 ;
+ indent[n] := abs(xpart ll - xpart llcorner q) ;
+ width[n] := abs(xpart rr - xpart ll) ;
+
+ if (i=strutheight) and (width[n]<baselineskip) :
+ n := n - 1 ;
+ runscript mfid_setparshapeproperty "first" true ;
+ fi ;
+
+ endfor ;
+
+ if trace_parshape :
+ drawarrow p withpen pencircle scaled 2pt withcolor red ;
+ drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ;
+ fi ;
+
+ runscript mfid_setparshapeproperty "lines" n ;
+
+ for i=1 upto n:
+ runscript mfid_setparshapeproperty "line" i (indent[i]) (width[i]) ;
+ endfor ;
+
+ endgroup ;
+
+enddef ;
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 588b8e7fd..aeb27924f 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -6590,7 +6590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43947, stripped down to: 22741
+-- original size: 45129, stripped down to: 23525
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6642,25 +6642,59 @@ local function points(n)
n=n*ptf
if n%1==0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+ end
+end
+local function nupoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
if n==0 then
- return "0pt"
+ return "0bp"
end
n=tonumber(n)
if not n or n==0 then
- return "0pt"
+ return "0bp"
end
n=n*bpf
if n%1==0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+ end
+end
+local function nubasepoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
+number.nupoints=nupoints
number.basepoints=basepoints
+number.nubasepoints=nubasepoints
local rubish=spaceortab^0*newline
local anyrubish=spaceortab+newline
local stripped=(spaceortab^1/"")*newline
@@ -6938,7 +6972,9 @@ local environment={
concat=table.concat,
signed=number.signed,
points=number.points,
+ nupoints=number.nupoints,
basepoints=number.basepoints,
+ nubasepoints=number.nubasepoints,
utfchar=utf.char,
utfbyte=utf.byte,
lpegmatch=lpeg.match,
@@ -7133,10 +7169,18 @@ local format_p=function()
n=n+1
return format("points(a%s)",n)
end
+local format_P=function()
+ n=n+1
+ return format("nupoints(a%s)",n)
+end
local format_b=function()
n=n+1
return format("basepoints(a%s)",n)
end
+local format_B=function()
+ n=n+1
+ return format("nubasepoints(a%s)",n)
+end
local format_t=function(f)
n=n+1
if f and f~="" then
@@ -7289,7 +7333,7 @@ local builder=Cs { "start",
+V("n")
+V("N")
+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("P")+V("b")+V("B")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
+V("A")
@@ -7327,7 +7371,9 @@ local builder=Cs { "start",
["u"]=(prefix_any*P("u"))/format_u,
["U"]=(prefix_any*P("U"))/format_U,
["p"]=(prefix_any*P("p"))/format_p,
+ ["P"]=(prefix_any*P("P"))/format_P,
["b"]=(prefix_any*P("b"))/format_b,
+ ["B"]=(prefix_any*P("B"))/format_B,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
["l"]=(prefix_any*P("l"))/format_l,
@@ -25779,8 +25825,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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1024020
--- stripped bytes : 405030
+-- original bytes : 1025202
+-- stripped bytes : 405428
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 588b8e7fd..aeb27924f 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -6590,7 +6590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43947, stripped down to: 22741
+-- original size: 45129, stripped down to: 23525
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6642,25 +6642,59 @@ local function points(n)
n=n*ptf
if n%1==0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+ end
+end
+local function nupoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
if n==0 then
- return "0pt"
+ return "0bp"
end
n=tonumber(n)
if not n or n==0 then
- return "0pt"
+ return "0bp"
end
n=n*bpf
if n%1==0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+ end
+end
+local function nubasepoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
+number.nupoints=nupoints
number.basepoints=basepoints
+number.nubasepoints=nubasepoints
local rubish=spaceortab^0*newline
local anyrubish=spaceortab+newline
local stripped=(spaceortab^1/"")*newline
@@ -6938,7 +6972,9 @@ local environment={
concat=table.concat,
signed=number.signed,
points=number.points,
+ nupoints=number.nupoints,
basepoints=number.basepoints,
+ nubasepoints=number.nubasepoints,
utfchar=utf.char,
utfbyte=utf.byte,
lpegmatch=lpeg.match,
@@ -7133,10 +7169,18 @@ local format_p=function()
n=n+1
return format("points(a%s)",n)
end
+local format_P=function()
+ n=n+1
+ return format("nupoints(a%s)",n)
+end
local format_b=function()
n=n+1
return format("basepoints(a%s)",n)
end
+local format_B=function()
+ n=n+1
+ return format("nubasepoints(a%s)",n)
+end
local format_t=function(f)
n=n+1
if f and f~="" then
@@ -7289,7 +7333,7 @@ local builder=Cs { "start",
+V("n")
+V("N")
+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("P")+V("b")+V("B")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
+V("A")
@@ -7327,7 +7371,9 @@ local builder=Cs { "start",
["u"]=(prefix_any*P("u"))/format_u,
["U"]=(prefix_any*P("U"))/format_U,
["p"]=(prefix_any*P("p"))/format_p,
+ ["P"]=(prefix_any*P("P"))/format_P,
["b"]=(prefix_any*P("b"))/format_b,
+ ["B"]=(prefix_any*P("B"))/format_B,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
["l"]=(prefix_any*P("l"))/format_l,
@@ -25779,8 +25825,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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1024020
--- stripped bytes : 405030
+-- original bytes : 1025202
+-- stripped bytes : 405428
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 588b8e7fd..aeb27924f 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -6590,7 +6590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43947, stripped down to: 22741
+-- original size: 45129, stripped down to: 23525
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6642,25 +6642,59 @@ local function points(n)
n=n*ptf
if n%1==0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+ end
+end
+local function nupoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
if n==0 then
- return "0pt"
+ return "0bp"
end
n=tonumber(n)
if not n or n==0 then
- return "0pt"
+ return "0bp"
end
n=n*bpf
if n%1==0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+ end
+end
+local function nubasepoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
+number.nupoints=nupoints
number.basepoints=basepoints
+number.nubasepoints=nubasepoints
local rubish=spaceortab^0*newline
local anyrubish=spaceortab+newline
local stripped=(spaceortab^1/"")*newline
@@ -6938,7 +6972,9 @@ local environment={
concat=table.concat,
signed=number.signed,
points=number.points,
+ nupoints=number.nupoints,
basepoints=number.basepoints,
+ nubasepoints=number.nubasepoints,
utfchar=utf.char,
utfbyte=utf.byte,
lpegmatch=lpeg.match,
@@ -7133,10 +7169,18 @@ local format_p=function()
n=n+1
return format("points(a%s)",n)
end
+local format_P=function()
+ n=n+1
+ return format("nupoints(a%s)",n)
+end
local format_b=function()
n=n+1
return format("basepoints(a%s)",n)
end
+local format_B=function()
+ n=n+1
+ return format("nubasepoints(a%s)",n)
+end
local format_t=function(f)
n=n+1
if f and f~="" then
@@ -7289,7 +7333,7 @@ local builder=Cs { "start",
+V("n")
+V("N")
+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("P")+V("b")+V("B")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
+V("A")
@@ -7327,7 +7371,9 @@ local builder=Cs { "start",
["u"]=(prefix_any*P("u"))/format_u,
["U"]=(prefix_any*P("U"))/format_U,
["p"]=(prefix_any*P("p"))/format_p,
+ ["P"]=(prefix_any*P("P"))/format_P,
["b"]=(prefix_any*P("b"))/format_b,
+ ["B"]=(prefix_any*P("B"))/format_B,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
["l"]=(prefix_any*P("l"))/format_l,
@@ -25779,8 +25825,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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1024020
--- stripped bytes : 405030
+-- original bytes : 1025202
+-- stripped bytes : 405428
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 588b8e7fd..aeb27924f 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -6590,7 +6590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43947, stripped down to: 22741
+-- original size: 45129, stripped down to: 23525
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -6642,25 +6642,59 @@ local function points(n)
n=n*ptf
if n%1==0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+ end
+end
+local function nupoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
if n==0 then
- return "0pt"
+ return "0bp"
end
n=tonumber(n)
if not n or n==0 then
- return "0pt"
+ return "0bp"
end
n=n*bpf
if n%1==0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+ end
+end
+local function nubasepoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
+number.nupoints=nupoints
number.basepoints=basepoints
+number.nubasepoints=nubasepoints
local rubish=spaceortab^0*newline
local anyrubish=spaceortab+newline
local stripped=(spaceortab^1/"")*newline
@@ -6938,7 +6972,9 @@ local environment={
concat=table.concat,
signed=number.signed,
points=number.points,
+ nupoints=number.nupoints,
basepoints=number.basepoints,
+ nubasepoints=number.nubasepoints,
utfchar=utf.char,
utfbyte=utf.byte,
lpegmatch=lpeg.match,
@@ -7133,10 +7169,18 @@ local format_p=function()
n=n+1
return format("points(a%s)",n)
end
+local format_P=function()
+ n=n+1
+ return format("nupoints(a%s)",n)
+end
local format_b=function()
n=n+1
return format("basepoints(a%s)",n)
end
+local format_B=function()
+ n=n+1
+ return format("nubasepoints(a%s)",n)
+end
local format_t=function(f)
n=n+1
if f and f~="" then
@@ -7289,7 +7333,7 @@ local builder=Cs { "start",
+V("n")
+V("N")
+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("P")+V("b")+V("B")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
+V("A")
@@ -7327,7 +7371,9 @@ local builder=Cs { "start",
["u"]=(prefix_any*P("u"))/format_u,
["U"]=(prefix_any*P("U"))/format_U,
["p"]=(prefix_any*P("p"))/format_p,
+ ["P"]=(prefix_any*P("P"))/format_P,
["b"]=(prefix_any*P("b"))/format_b,
+ ["B"]=(prefix_any*P("B"))/format_B,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
["l"]=(prefix_any*P("l"))/format_l,
@@ -25779,8 +25825,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 libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1024020
--- stripped bytes : 405030
+-- original bytes : 1025202
+-- stripped bytes : 405428
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 6c083cd0b..b1c603769 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{2021.02.23 17:41}
+\newcontextversion{2021.02.27 19:27}
%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 4b20c792e..8486049d0 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{2021.02.23 17:41}
+\edef\contextversion{2021.02.27 19:27}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 60bb0d85d..c984f50cf 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{2021.02.23 17:41}
+\newcontextversion{2021.02.27 19:27}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index b5d86869c..e2afeb0d4 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{2021.02.23 17:41}
+\edef\contextversion{2021.02.27 19:27}
%D Kind of special:
diff --git a/tex/context/base/mkiv/mlib-mpf.lua b/tex/context/base/mkiv/mlib-mpf.lua
index 00ebb1ae5..7452c0111 100644
--- a/tex/context/base/mkiv/mlib-mpf.lua
+++ b/tex/context/base/mkiv/mlib-mpf.lua
@@ -927,6 +927,11 @@ do
function mp.setcount(k,v) setcount(k,v) end
function mp.settoks (k,v) settoks (k,v) end
+ function mp.setglobalmacro(k,v) setmacro(k,v,"global") end
+ function mp.setglobaldimen(k,v) setdimen("global",k,v/bpfactor) end
+ function mp.setglobalcount(k,v) setcount("global",k,v) end
+ function mp.setglobaltoks (k,v) settoks ("global",k,v) end
+
-- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
mp._get_macro_ = mp.getmacro
@@ -939,6 +944,11 @@ do
mp._set_count_ = mp.setcount
mp._set_toks_ = mp.settoks
+ mp._set_global_macro_ = mp.setglobalmacro
+ mp._set_global_dimen_ = mp.setglobaldimen
+ mp._set_global_count_ = mp.setglobalcount
+ mp._set_global_toks_ = mp.setglobaltoks
+
end
-- position fun
diff --git a/tex/context/base/mkiv/mtx-context-select.tex b/tex/context/base/mkiv/mtx-context-select.tex
index 5ae151f90..61f58d61f 100644
--- a/tex/context/base/mkiv/mtx-context-select.tex
+++ b/tex/context/base/mkiv/mtx-context-select.tex
@@ -1,5 +1,3 @@
-% engine=luatex
-
%D \module
%D [ file=mtx-context-select,
%D version=2008.11.10, % about that time i started playing with this
diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua
index 7bfda80bc..4ecbb1abd 100644
--- a/tex/context/base/mkiv/mult-fun.lua
+++ b/tex/context/base/mkiv/mult-fun.lua
@@ -176,6 +176,7 @@ return {
"isarray", "prefix", "dimension",
"getmacro", "getdimen", "getcount", "gettoks",
"setmacro", "setdimen", "setcount", "settoks",
+ "setglobalmacro", "setglobaldimen", "setglobalcount", "setglobaltoks",
--
"positionpath", "positioncurve", "positionxy", "positionpxy",
"positionwhd", "positionpage", "positionregion", "positionbox",
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b1533b02b..0b1992890 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 a2c0ea9a5..b52a1d01d 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/util-str.lua b/tex/context/base/mkiv/util-str.lua
index 2d3f4d669..0d1f39de9 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -70,27 +70,63 @@ local function points(n)
n = n * ptf
if n % 1 == 0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt
+ end
+end
+
+local function nupoints(n)
+ if n == 0 then
+ return "0"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0"
+ end
+ n = n * ptf
+ if n % 1 == 0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n) -- no strip
end
- return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt
end
local function basepoints(n)
if n == 0 then
- return "0pt"
+ return "0bp"
end
n = tonumber(n)
if not n or n == 0 then
- return "0pt"
+ return "0bp"
end
n = n * bpf
if n % 1 == 0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt
+ end
+end
+
+local function nubasepoints(n)
+ if n == 0 then
+ return "0"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0"
+ end
+ n = n * bpf
+ if n % 1 == 0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n) -- no strip
end
- return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt
end
-number.points = points
-number.basepoints = basepoints
+number.points = points
+number.nupoints = nupoints
+number.basepoints = basepoints
+number.nubasepoints = nubasepoints
-- str = " \n \ntest \n test\ntest "
-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]")
@@ -357,7 +393,9 @@ end
-- U+hexadecimal %...u character number
-- U+HEXADECIMAL %...U character number
-- points %p number (scaled points)
+-- nupoints %P number (scaled points) / without unit / always 5 decimals
-- basepoints %b number (scaled points)
+-- nubasepoints %B number (scaled points) / without unit / always 5 decimals
-- table concat %...t table
-- table concat %{.}t table
-- serialize %...T sequenced (no nested tables)
@@ -616,7 +654,9 @@ local environment = {
concat = table.concat,
signed = number.signed,
points = number.points,
+ nupoints = number.nupoints,
basepoints = number.basepoints,
+ nubasepoints = number.nubasepoints,
utfchar = utf.char,
utfbyte = utf.byte,
lpegmatch = lpeg.match,
@@ -879,11 +919,21 @@ local format_p = function()
return format("points(a%s)",n)
end
+local format_P = function()
+ n = n + 1
+ return format("nupoints(a%s)",n)
+end
+
local format_b = function()
n = n + 1
return format("basepoints(a%s)",n)
end
+local format_B = function()
+ n = n + 1
+ return format("nubasepoints(a%s)",n)
+end
+
local format_t = function(f)
n = n + 1
if f and f ~= "" then
@@ -1125,7 +1175,7 @@ local builder = Cs { "start",
--
+ V("r")
+ V("h") + V("H") + V("u") + V("U")
- + V("p") + V("b")
+ + V("p") + V("P") + V("b") + V("B")
+ V("t") + V("T")
+ V("l") + V("L")
+ V("I")
@@ -1174,8 +1224,10 @@ local builder = Cs { "start",
["H"] = (prefix_any * P("H")) / format_H, -- %H => 0x0A1B2 (when - no 0x) was V
["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+)
["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+)
- ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units)
- ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units)
+ ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt
+ ["P"] = (prefix_any * P("P")) / format_P, -- %p => 12.345
+ ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp
+ ["B"] = (prefix_any * P("B")) / format_B, -- %b => 12.342
["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat
["T"] = (prefix_tab * P("T")) / format_T, -- %t => sequenced
["l"] = (prefix_any * P("l")) / format_l, -- %l => boolean
diff --git a/tex/context/base/mkxl/bibl-tra.mkxl b/tex/context/base/mkxl/bibl-tra.mkxl
index 8c24024fd..536de8d31 100644
--- a/tex/context/base/mkxl/bibl-tra.mkxl
+++ b/tex/context/base/mkxl/bibl-tra.mkxl
@@ -354,9 +354,10 @@
\protected\def\dousepublications#1%
{\doonlyonce{#1.\f!bibextension}{\dodousepublications{#1}}}
+\pushoverloadmode
+
\protected\def\dodousepublications#1% brr, this par stuff
- {\let\@@savedpar\par
- \let\par\ignorespaces
+ {\enforced\let\par\ignorespaces
\ifhmode\kern\zeropoint\fi
\pushcatcodetable
\setcatcodetable\ctxcatcodes
@@ -365,7 +366,9 @@
{\showmessage\m!publications{2}{#1.\f!bibextension}}%
\popcatcodetable
\ifhmode\removeunwantedspaces\fi
- \let\par\@@savedpar}
+ \enforced\let\par\normalpar}
+
+\popoverloadmode
%D \macros{setuppublicationlist}
%D
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 26de0b443..8e2816e46 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.02.23 17:41}
+\newcontextversion{2021.02.27 19:27}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index f72721c9c..4976b707d 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.02.23 17:41}
+\immutable\edef\contextversion{2021.02.27 19:27}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/meta-imp-txt.lmt b/tex/context/base/mkxl/meta-imp-txt.lmt
new file mode 100644
index 000000000..f7721956f
--- /dev/null
+++ b/tex/context/base/mkxl/meta-imp-txt.lmt
@@ -0,0 +1,86 @@
+if not modules then modules = { } end modules ['meta-imp-txt'] = {
+ version = 1.001,
+ comment = "companion to meta-imp-txt.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+local setmetatableindex = table.setmetatableindex
+
+local texset = tex.set
+
+local scannumeric = mp.scan.numeric
+local scaninteger = mp.scan.integer
+local scanboolean = mp.scan.boolean
+local scanstring = mp.scan.string
+
+local bpfactor = number.dimenfactors.bp
+
+local metapost = metapost
+
+local parshapes = { }
+local properties = { }
+
+-- initialize shapes to 0 hsize
+
+metapost.parshapes = { }
+
+function metapost.parshapes.reset()
+ parshapes = { }
+ properties = { }
+end
+
+function metapost.parshapes.next()
+ properties = { }
+ parshapes[#parshapes+1] = properties
+end
+
+function metapost.parshapes.inspect()
+ inspect(parshapes)
+end
+
+function metapost.parshapes.get(index,name)
+ local v = parshapes[index][name]
+ if type(v) == "boolean" then
+ context(v and 1 or 0)
+ else
+ context(v)
+ end
+end
+
+function metapost.parshapes.wholeshape() -- maybe just collect them earlier
+ local t, n = { }, 0
+ for i=1,#parshapes do
+ local s = parshapes[i].shape
+ for i=1,#s do
+ n = n + 1
+ t[n] = s[i]
+ end
+ end
+ texset("parshape",t)
+end
+
+metapost.registerscript("setparshapeproperty", function()
+ local k = scanstring()
+ if k == "line" then
+ local entry = properties.shape[scannumeric()]
+ local indent = scannumeric() / bpfactor
+ local width = scannumeric() / bpfactor
+ entry[1] = indent
+ entry[2] = width
+ elseif k == "lines" then
+ properties.lines = scaninteger()
+ properties.shape = setmetatableindex(function(t,k)
+ local v = { 0, properties.width or 0 }
+ t[k] = v
+ return v
+ end)
+ elseif k == "first" then
+ properties[k] = scanboolean()
+ elseif k == "inspect" then
+ inspect(properties)
+ else
+ properties[k] = scannumeric() / bpfactor
+ end
+end)
diff --git a/tex/context/base/mkxl/meta-imp-txt.mkxl b/tex/context/base/mkxl/meta-imp-txt.mkxl
new file mode 100644
index 000000000..4654ca722
--- /dev/null
+++ b/tex/context/base/mkxl/meta-imp-txt.mkxl
@@ -0,0 +1,339 @@
+%D \module
+%D [ file=meta-txt,
+%D version=2000.07.06,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Text Tricks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D See comments in the \MKIV\ module. This is an upgraded version for \LMTX,
+%D where we can so some things nicer.
+
+\unprotect
+
+%D Text in shapes. Here we use the option to prune a parshape when a new paragraph
+%D is seen. It's an experimental feature so I need to keep an eye on how it evolves.
+%D This time we combine \TEX, \METAPOST\ and \LUA, so we do't need a temporary file
+%D to communicate from \METAPOST\ to \TEX. We just store information in \LUA\ tables.
+
+\ifdefined\startshapetext
+
+ % now moved into the core
+
+\else
+
+ \ifdefined\shapetextbox \else
+ \newbox \shapetextbox
+ \newcount\shapetextindex
+ \fi
+
+ \ctxloadluafile{meta-imp-txt.lmt}
+
+ \startMPextensions loadmodule "text" ; \stopMPextensions
+
+ \protected\def\startshapetext[#1]%
+ {\begingroup
+ \global\shapetextindex\zerocount
+ \global\setbox\shapetextbox\vbox\bgroup
+ % analyze the mp shapes
+ \ctxlua{metapost.parshapes.reset()}
+ \def\docommand##1%
+ {\ctxlua{metapost.parshapes.next()}%
+ \startMPcalculation
+ \includeMPgraphic{##1}%
+ \stopMPcalculation}%
+ \processcommalist[#1]\docommand
+ \forgetall
+ \dontcomplain
+ % setup tex part (maybe just enable grid snapping)
+ \setuptolerance[\v!verytolerant,\v!stretch]% default
+ \setuplayout[\c!grid=\v!yes]%
+ \ctxlua{metapost.parshapes.wholeshape()}%
+ \pushparagraphtweak {prune}}
+
+ \protected\def\stopshapetext
+ {\popparagraphtweak
+ \egroup
+ \endgroup}
+
+ \def\getshapeparameter#1{\ctxlua{metapost.parshapes.get(\number\shapetextindex,"#1")}}
+
+ \protected\def\getshapetext
+ {\vbox\bgroup
+ \forgetall
+ \dontcomplain
+ \global\advance\shapetextindex\plusone
+ \scratchcounter\getshapeparameter{lines}\relax
+ \scratchwidth \getshapeparameter{width}\scaledpoint\relax
+ \scratchheight \getshapeparameter{height}\scaledpoint\relax
+ \setbox\scratchbox\vpack to \scratchheight
+ {\splittopskip\strutheight
+ \vskip\dimexpr\getshapeparameter{voffset}\scaledpoint\relax
+ \ifcase\numexpr\getshapeparameter{first}\relax\else
+ \vskip\lineheight
+ \fi
+ \hskip\dimexpr\getshapeparameter{hoffset}\scaledpoint\relax
+ \hpack{\vsplit\shapetextbox to \scratchcounter\lineheight}}%
+ \wd\scratchbox\scratchwidth
+ \ht\scratchbox\scratchheight
+ \dp\scratchbox\zeropoint
+ \box\scratchbox
+ \egroup}
+
+\fi
+
+%D Following:
+
+% \doifundefined{RotFont}{\definefont[RotFont][RegularBold*default]}
+%
+% \unexpanded\def\getfollowtoken#1%
+% {\hbox\bgroup
+% \strut
+% \ctxlua{mp.follow_text(#1)}%
+% \egroup}
+
+\definefontfeature[mp:tp][liga=no]
+
+% if unknown RotPath : path RotPath ; RotPath := origin ; fi ;
+% if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ;
+% if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ;
+% if al < len[n]:
+% RotPath := RotPath scaled ((len[n]+ExtraRot)/al) ;
+% al := arclength RotPath ;
+% fi ;
+% if TraceRot :
+% draw RotPath withpen pencircle scaled 1pt withcolor blue ;
+% fi ;
+% if TraceRot :
+% draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ;
+% fi ;
+
+\protected\def\dofollowtokens#1#2%
+ {\dontleavehmode
+ \vpack\bgroup
+ \forgetall
+ \dontcomplain
+ \addff{mp:tp}%
+ \startMPcode
+ \includeMPgraphic{followtokens}
+ draw lmt_followtext [ path = RotPath, text = "#2", spread = #1 ] ;
+ \stopMPcode
+ \egroup}
+
+\protected\def\followtokens {\dofollowtokens{true}}
+\protected\def\followtokenscentered{\dofollowtokens{false}}
+
+%D Fuzzy counters:
+
+\startuseMPgraphic{fuzzycount}
+ begingroup
+ save height, span, drift, d, cp ;
+ height := 3/ 5 * LineHeight ;
+ span := 1/ 3 * height ;
+ drift := 1/10 * height ;
+ pickup pencircle scaled (1/12 * height) ;
+ def d = (uniformdeviate drift) enddef ;
+ for i := 1 upto \MPvar{n} :
+ draw
+ if (i mod 5)=0 : ((-d - 4.5span,d) -- (d -0.5span,height - d))
+ else : ((-d, d) -- (d, height - d)) fi
+ shifted (span*i,d-drift) ;
+ endfor;
+ picture cp ; cp := currentpicture ; % for readability
+ setbounds currentpicture to
+ (llcorner cp shifted (0,-ypart llcorner cp) --
+ lrcorner cp shifted (0,-ypart lrcorner cp) --
+ urcorner cp --
+ ulcorner cp -- cycle) ;
+ endgroup ;
+\stopuseMPgraphic
+
+\setupMPvariables
+ [fuzzycount]
+ [n=10]
+
+\protected\def\fuzzycount#1%
+ {\dontleavehmode\bgroup
+ \tx
+ \useMPgraphic{fuzzycount}{n=#1}%
+ \egroup}
+
+\defineconversion[fuzzy][\fuzzycount]
+
+%D English rules:
+
+\setupMPvariables
+ [EnglishRule]
+ [height=1ex,
+ width=\localhsize,
+ color=darkgray]
+
+\defineblank
+ [EnglishRule]
+ [medium]
+
+\startuniqueMPgraphic{EnglishRule}{height,width,color}
+ x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ;
+ y1 = y3 = 0 ; y2 = -y4 = \MPvar{height} / 2 ;
+ fill z1 .. z2 .. z3 & z3 .. z4 .. z1 & cycle withcolor \MPvar{color} ;
+\stopuniqueMPgraphic
+
+\protected\def\EnglishRule
+ {\startlinecorrection[EnglishRule]%
+ \setlocalhsize
+ \noindentation
+ \reuseMPgraphic{EnglishRule}%
+ \stoplinecorrection}
+
+%D Tight text (for old times sake): the following macro returns a tight bound
+%D character sequence.
+%D
+%D \useMPlibrary[txt]
+%D
+%D \startlinecorrection
+%D \TightText{\ss\bf 123}{0cm}{3cm}{red}
+%D \stoplinecorrection
+
+\protected\def\TightText#1#2#3#4%
+ {\hpack
+ {\startMPcode
+ picture p ; p := image (graphictext "#1" withfillcolor red) ;
+ draw p xsized #2 ysized #3 withcolor \MPcolor{#4} ;
+ \stopMPcode}}
+
+\protected\def\TightText#1#2#3#4%
+ {\dontleavehmode
+ \startMPcode
+ draw outlinetext.f ("#1") (\iftok{#4}\emptytoks \else withcolor \MPcolor{#4} \fi)
+ \iftok{#2}\emptytoks \else xsized #2 \fi
+ \iftok{#3}\emptytoks \else ysized #3 \fi
+ ;
+ \stopMPcode}
+
+\protect
+
+\continueifinputfile{meta-imp-txt.mkxl}
+
+\setupbodyfont[pagella,10pt]
+
+% \useMPlibrary[txt]
+
+\starttext
+
+%D Shapes:
+
+\startuseMPgraphic{test 1}
+ path p ; p := fullcircle scaled 6cm ;
+
+ build_parshape(p,BodyFontSize/2,0,0,LineHeight,StrutHeight,StrutDepth,StrutHeight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 2}
+ path p ; p := fullsquare rotated 45 scaled 5cm ;
+
+ build_parshape(p,BodyFontSize/2,0,0,LineHeight,StrutHeight,StrutDepth,StrutHeight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 3}
+ numeric w, h ; w := h := 6cm ;
+ path p ; p := (.5w,h) -- (0,h) -- (0,0) -- (w,0) &
+ (w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+
+ build_parshape(p,BodyFontSize/2,0,0,LineHeight,StrutHeight,StrutDepth,StrutHeight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 4}
+ numeric w, h, o, d ;
+
+ def shape = (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+
+ d := BodyFontSize/2;
+
+ w := h := 6cm ; o := d ; path p ; p := shape ;
+ w := h := 6cm ; o := 0 ; path q ; q := shape ;
+
+ build_parshape(p,q,d,d,LineHeight,StrutHeight,StrutDepth,StrutHeight) ;
+
+ draw q withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+
+\defineoverlay[test 1][\useMPgraphic{test 1}]
+\defineoverlay[test 2][\useMPgraphic{test 2}]
+\defineoverlay[test 3][\useMPgraphic{test 3}]
+\defineoverlay[test 4][\useMPgraphic{test 4}]
+
+\startbuffer
+ \startshapetext[test 1,test 2,test 3,test 4]
+ \setupalign[verytolerant,stretch,normal]%
+ \samplefile{douglas} % Douglas R. Hofstadter
+ \stopshapetext
+ \startTEXpage[offset=10pt]
+ \startcombination[2*2]
+ {\framed[offset=overlay,frame=off,background=test 1]{\getshapetext}} {test 1}
+ {\framed[offset=overlay,frame=off,background=test 2]{\getshapetext}} {test 2}
+ {\framed[offset=overlay,frame=off,background=test 3]{\getshapetext}} {test 3}
+ {\framed[offset=overlay,frame=off,background=test 4]{\getshapetext}} {test 4}
+ \stopcombination
+ \stopTEXpage
+\stopbuffer
+
+\getbuffer
+
+\startMPextensions
+ boolean trace_parshape ; trace_parshape := true ;
+\stopMPextensions
+
+\getbuffer
+
+%D Fuzzycount (maybe handy):
+
+\startitemize[fuzzy,nostopper]
+ \startitem This is real fuzzy. \stopitem
+ \startitem But it can be even more fuzzier. \stopitem
+ \startitem And how about this. \stopitem
+\stopitemize
+
+\EnglishRule
+
+\startitemize[continue,broad]
+ \startitem This is real fuzzy. \stopitem
+ \startitem But it can be even more fuzzier. \stopitem
+ \startitem And how about this. \stopitem
+\stopitemize
+
+%D Tight text (manual stuff):
+
+\ruledhbox{\TightText{oeps wat doet dit}{10cm}{1cm}{red}} \blank
+\ruledhbox{\TightText{oeps wat doet dit}{10cm}{} {green}} \blank
+\ruledhbox{\TightText{oeps wat doet dit}{} {1cm}{blue}} \blank
+\ruledhbox{\TightText{oeps wat doet dit}{} {} {}} \blank
+
+%D Old fashioned:
+
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse halfcircle xyscaled 3cm ;
+ draw RotPath ;
+\stopuseMPgraphic
+
+\startTEXpage
+ \followtokens{{\hskip1em}some text{\hskip1em}}
+\stopTEXpage
+
+\startTEXpage
+ \followtokenscentered{{\hskip1em}some text{\hskip1em}}
+\stopTEXpage
+
+\stoptext
diff --git a/tex/context/base/mkxl/mlib-lua.lmt b/tex/context/base/mkxl/mlib-lua.lmt
index cb2718f9b..e8f33a53a 100644
--- a/tex/context/base/mkxl/mlib-lua.lmt
+++ b/tex/context/base/mkxl/mlib-lua.lmt
@@ -9,9 +9,15 @@ if not modules then modules = { } end modules ['mlib-lua'] = {
local type = type
local insert, remove = table.insert, table.remove
+local trace = false trackers.register("metapost.instance",function(v) trace = v end)
+
+local report = logs.reporter("metapost","instance")
+
local codes = mplib.getcodes()
local types = mplib.gettypes()
+-- for k,v in next, mplib do if type(v) == "function" then local f = v mplib[k] = function(...) print(k) return v(...) end end end
+
table.hashed(codes)
table.hashed(types)
@@ -26,6 +32,9 @@ local inject = mp.inject
local currentmpx = nil
local stack = { }
+local function reports(s) report("%a scan %s", tostring(currentmpx),s) end -- temporary, till we're okay
+local function reporti(s) report("%a inject %s",tostring(currentmpx),s) end -- temporary, till we're okay
+
local scan_next = mplib.scan_next
local scan_expression = mplib.scan_expression
local scan_token = mplib.scan_token
@@ -46,21 +55,21 @@ local skip_token = mplib.skip_token
local get_hashentry = mplib.gethashentry
-scan.next = function(k) return scan_next (currentmpx,k) end
-scan.expression = function(k) return scan_expression(currentmpx,k) end
-scan.token = function(k) return scan_token (currentmpx,k) end
-scan.symbol = function(k,e) return scan_symbol (currentmpx,k,e) end
-scan.property = function(k) return scan_property (currentmpx,k) end
-scan.numeric = function() return scan_numeric (currentmpx) end
-scan.integer = function() return scan_integer (currentmpx) end
-scan.boolean = function() return scan_boolean (currentmpx) end
-scan.string = function() return scan_string (currentmpx) end
-scan.pair = function(t) return scan_pair (currentmpx,t) end
-scan.color = function(t) return scan_color (currentmpx,t) end
-scan.cmykcolor = function(t) return scan_cmykcolor (currentmpx,t) end
-scan.transform = function(t) return scan_transform (currentmpx,t) end
-scan.path = function(t) return scan_path (currentmpx,t) end
-scan.pen = function(t) return scan_pen (currentmpx,t) end
+scan.next = function(k) if trace then reporti("next") end return scan_next (currentmpx,k) end
+scan.expression = function(k) if trace then reporti("expression") end return scan_expression(currentmpx,k) end
+scan.token = function(k) if trace then reporti("token") end return scan_token (currentmpx,k) end
+scan.symbol = function(k,e) if trace then reporti("symbol") end return scan_symbol (currentmpx,k,e) end
+scan.property = function(k) if trace then reporti("property") end return scan_property (currentmpx,k) end
+scan.numeric = function() if trace then reporti("numeric") end return scan_numeric (currentmpx) end
+scan.integer = function() if trace then reporti("integer") end return scan_integer (currentmpx) end
+scan.boolean = function() if trace then reporti("boolean") end return scan_boolean (currentmpx) end
+scan.string = function() if trace then reporti("string") end if currentmpx then return scan_string (currentmpx) end end
+scan.pair = function(t) if trace then reporti("pair") end return scan_pair (currentmpx,t) end
+scan.color = function(t) if trace then reporti("color") end return scan_color (currentmpx,t) end
+scan.cmykcolor = function(t) if trace then reporti("cmykcolor") end return scan_cmykcolor (currentmpx,t) end
+scan.transform = function(t) if trace then reporti("transform") end return scan_transform (currentmpx,t) end
+scan.path = function(t) if trace then reporti("path") end return scan_path (currentmpx,t) end
+scan.pen = function(t) if trace then reporti("pen") end return scan_pen (currentmpx,t) end
skip.token = function(t) return skip_token (currentmpx,t) end
@@ -84,16 +93,17 @@ local inject_cmykcolor = mplib.inject_cmykcolor
local inject_transform = mplib.inject_transform
local inject_whatever = mplib.inject_whatever
-------.path = function(t,cycle,curled) return inject_path (currentmpx,t,cycle,curled) end
-inject.numeric = function(n) return inject_numeric (currentmpx,n) end
-inject.pair = function(x,y) return inject_pair (currentmpx,x,y) end
-inject.boolean = function(b) return inject_boolean (currentmpx,b) end
-inject.integer = function(i) return inject_integer (currentmpx,i) end
-inject.string = function(s) return inject_string (currentmpx,s) end
-inject.color = function(r,g,b) return inject_color (currentmpx,r,g,b) end
-inject.cmykcolor = function(c,m,y,k) return inject_cmykcolor(currentmpx,c,m,y,k) end
-inject.transform = function(x,y,xx,xy,yx,yy) return inject_transform(currentmpx,x,y,xx,xy,yx,yy) end
-inject.whatever = function(...) return inject_whatever (currentmpx,...) end
+
+------.path = function(t,cycle,curled) if trace then reporti("path") end return inject_path (currentmpx,t,cycle,curled) end
+inject.numeric = function(n) if trace then reporti("numeric") end return inject_numeric (currentmpx,n) end
+inject.pair = function(x,y) if trace then reporti("pair") end return inject_pair (currentmpx,x,y) end
+inject.boolean = function(b) if trace then reporti("boolean") end return inject_boolean (currentmpx,b) end
+inject.integer = function(i) if trace then reporti("integer") end return inject_integer (currentmpx,i) end
+inject.string = function(s) if trace then reporti("string") end return inject_string (currentmpx,s) end
+inject.color = function(r,g,b) if trace then reporti("color") end return inject_color (currentmpx,r,g,b) end
+inject.cmykcolor = function(c,m,y,k) if trace then reporti("cmykcolor") end return inject_cmykcolor(currentmpx,c,m,y,k) end
+inject.transform = function(x,y,xx,xy,yx,yy) if trace then reporti("transform") end return inject_transform(currentmpx,x,y,xx,xy,yx,yy) end
+inject.whatever = function(...) if trace then reporti("whatever") end return inject_whatever (currentmpx,...) end
inject.triplet = inject.color
inject.quadruplet = inject.cmykcolor
@@ -136,6 +146,7 @@ function inject.path(p,close,connector)
end
end
end
+ if trace then reporti("path") end
return inject_path(currentmpx,p,close,curled)
end
@@ -173,12 +184,19 @@ function mp.autoinject(m)
end
function metapost.pushscriptrunner(mpx)
- insert(stack,mpx)
+ if trace then
+ report("%a => %a",tostring(currentmpx),tostring(mpx))
+ end
+ insert(stack,currentmpx)
currentmpx = mpx
end
function metapost.popscriptrunner()
- currentmpx = remove(stack,mpx)
+ local mpx = remove(stack)
+ if trace then
+ report("%a <= %a",tostring(mpx),tostring(currentmpx))
+ end
+ currentmpx = mpx
end
function metapost.currentmpx()
diff --git a/tex/context/base/mkxl/mlib-mpf.lmt b/tex/context/base/mkxl/mlib-mpf.lmt
index d66491a16..42cee676c 100644
--- a/tex/context/base/mkxl/mlib-mpf.lmt
+++ b/tex/context/base/mkxl/mlib-mpf.lmt
@@ -943,6 +943,12 @@ do
registerscript("setcount", function() setcount(scanstring(),scannumeric()) end)
registerscript("settoks", function() settoks (scanstring(),scanstring()) end)
+ registerscript("setglobalmacro", function() setmacro(scanstring(),scanstring(),"global") end)
+ registerscript("setglobaldimen", function() setdimen("global",scanstring(),scannumeric()/bpfactor) end)
+ registerscript("setglobalcount", function() setcount("global",scanstring(),scannumeric()) end)
+ registerscript("setglobaltoks", function() settoks ("global",scanstring(),scanstring()) end)
+
+
local utfnum = utf.byte
local utflen = utf.len
local utfsub = utf.sub
diff --git a/tex/context/base/mkxl/mlib-pps.lmt b/tex/context/base/mkxl/mlib-pps.lmt
index 31ef130a3..32f23c39d 100644
--- a/tex/context/base/mkxl/mlib-pps.lmt
+++ b/tex/context/base/mkxl/mlib-pps.lmt
@@ -565,26 +565,6 @@ local function checkaskedfig(askedfig) -- return askedfig, wrappit
end
end
-local function extrapass()
- if trace_runs then
- report_metapost("second run of job %s, asked figure %a",top.nofruns,top.askedfig)
- end
- metapost.preparetextextsdata()
- runmetapost {
- mpx = top.mpx,
- askedfig = top.askedfig,
- incontext = true,
- data = {
- top.wrappit and do_begin_fig or "",
- no_trial_run,
- top.initializations,
- do_safeguard,
- top.data,
- top.wrappit and do_end_fig or "",
- },
- }
-end
-
-- This one is called from the \TEX\ end so the specification is different
-- from the specification to metapost,run cum suis! The definitions and
-- extension used to be handled here but are now delegated to the format
diff --git a/tex/context/base/mkxl/mlib-run.lmt b/tex/context/base/mkxl/mlib-run.lmt
index 8ab998bb8..a79ce99ef 100644
--- a/tex/context/base/mkxl/mlib-run.lmt
+++ b/tex/context/base/mkxl/mlib-run.lmt
@@ -535,7 +535,7 @@ function metapost.run(specification)
tra.log:write(banner)
end
stoptiming(metapost)
- metapost.popscriptrunner(mpx)
+ metapost.popscriptrunner()
end
if mpxdone then
metapost.popformat()
diff --git a/tex/context/base/mkxl/mult-sys.mkxl b/tex/context/base/mkxl/mult-sys.mkxl
index 64cedbfad..3e1d32a91 100644
--- a/tex/context/base/mkxl/mult-sys.mkxl
+++ b/tex/context/base/mkxl/mult-sys.mkxl
@@ -571,7 +571,7 @@
%D The setup files for the language, font, color and special subsystems have a common
%D prefix. This means that we have at most three characters for unique filenames.
-\definefileconstant {colo_run} {s-colors-run}
+\definefileconstant {colo_run} {s-colors-show}
\definefileconstant {font_run} {s-fonts-show}
\definefileconstant {page_run} {s-layout-show}
\definefileconstant {symb_run} {s-symbols-show}
diff --git a/tex/context/base/mkxl/node-par.lmt b/tex/context/base/mkxl/node-par.lmt
index af3125d23..9354d769f 100644
--- a/tex/context/base/mkxl/node-par.lmt
+++ b/tex/context/base/mkxl/node-par.lmt
@@ -13,36 +13,76 @@ local sequencers = utilities.sequencers
-- This are called a lot!
-local actions = nodes.tasks.actions("everypar")
+do
+
+ local actions = nodes.tasks.actions("everypar")
+
+ local function everypar(head)
+ starttiming(builders)
+ head = actions(head)
+ stoptiming(builders)
+ return head
+ end
+
+ callbacks.register("insert_par",everypar,"after paragraph start")
-local function everypar(head)
- starttiming(builders)
- head = actions(head)
- stoptiming(builders)
- return head
end
-callbacks.register("insert_par",everypar,"after paragraph start")
+do
-local actions = sequencers.new {
- name = "paragraph",
- arguments = "mode,indented",
- returnvalues = "indented",
- results = "indented",
-}
+ local actions = sequencers.new {
+ name = "paragraph",
+ arguments = "mode,indented,context",
+ returnvalues = "indented",
+ results = "indented",
+ }
-sequencers.appendgroup(actions,"before") -- user
-sequencers.appendgroup(actions,"system") -- private
-sequencers.appendgroup(actions,"after" ) -- user
+ sequencers.appendgroup(actions,"before") -- user
+ sequencers.appendgroup(actions,"system") -- private
+ sequencers.appendgroup(actions,"after" ) -- user
-local function paragraph(mode,indented)
- local runner = actions.runner
- if runner then
- starttiming(builders)
- indented = runner(mode,indented)
- stoptiming(builders)
+ local function paragraph(mode,indented)
+ local runner = actions.runner
+ if runner then
+ starttiming(builders)
+ indented = runner(mode,indented)
+ stoptiming(builders)
+ end
+ return indented
end
- return indented
+
+ callbacks.register("begin_paragraph",paragraph,"before paragraph start")
+
end
-callbacks.register("begin_paragraph",paragraph,"before paragraph start")
+-- This one is a playground for some old metafun gimmicks that I want to improve
+-- while I'm updating the manual to lmtx. but it might also be useful for other
+-- purposes. It fits in the category obscure and probably takes while to stabelize
+-- (if it stays at all).
+
+do
+
+ local actions = sequencers.new {
+ name = "paragraphcontext",
+ arguments = "context",
+ returnvalues = "ignore",
+ results = "ignore",
+ }
+
+ ----------.appendgroup(actions,"before") -- user
+ sequencers.appendgroup(actions,"system") -- private
+ ----------.appendgroup(actions,"after" ) -- user
+
+ local function parcontext(parcontext)
+ local runner = actions.runner
+ if runner then
+ starttiming(builders)
+ local ignore = runner(parcontext)
+ stoptiming(builders)
+ return ignore
+ end
+ end
+
+ callbacks.register("paragraph_context",parcontext,"when the context is dealt with")
+
+end
diff --git a/tex/context/base/mkxl/pack-mrl.mkxl b/tex/context/base/mkxl/pack-mrl.mkxl
index 678afb68a..8bbeeb798 100644
--- a/tex/context/base/mkxl/pack-mrl.mkxl
+++ b/tex/context/base/mkxl/pack-mrl.mkxl
@@ -771,7 +771,7 @@
\begingroup
\def\pack_fillinrules_rule_indeed{\unhbox\nextbox\unskip}% hm, needs checking
\dowithnextbox{\fillinrules[#1]{#2}{\hfill#3}}%
- \hbox\bgroup\let\par\egroup\ignorespaces}
+ \hbox\bgroup\enforced\let\par\egroup\ignorespaces} % bah, i will drop this compatibility hack
%D \macros
%D {fillinline, setupfillinlines}
diff --git a/tex/context/base/mkxl/page-imp.mkxl b/tex/context/base/mkxl/page-imp.mkxl
index 89a2be030..4ee7c159b 100644
--- a/tex/context/base/mkxl/page-imp.mkxl
+++ b/tex/context/base/mkxl/page-imp.mkxl
@@ -76,7 +76,7 @@
\endgroup}
\permanent\protected\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed
- {\setgvalue{\??shipoutmethod#1}##1{#2{##1}}} % and shipped out (don't depend on the exact package)
+ {\gdefcsname\??shipoutmethod#1\endcsname##1{#2{##1}}} % and shipped out (don't depend on the exact package)
\aliased\let\installpagehandler\installshipoutmethod % will go
@@ -257,7 +257,7 @@
\global\advance\paperheight-2\dimexpr\paperoffset/\arrangedpageY\relax}
\permanent\protected\def\doinstallarrangedoption#1#2%
- {\setvalue{\??layoutarrangeoption#1}{#2}}
+ {\gdefcsname\??layoutarrangeoption#1\endcsname{#2}}
\permanent\def\doinstalledarrangedoption#1%
{\ifcsname\??layoutarrangeoption#1\endcsname
@@ -306,6 +306,10 @@
\doinstallarrangedoption\v!background
{\global\settrue\arrangedbackgroundstate}
+\aliased\let\poparrangedpages \relax
+\aliased\let\pusharrangedpage \gobbleoneargument
+\aliased\let\handlearrangedpage\relax
+
\permanent\protected\def\setuparranging[#1]%
{\ifconditional\arrangingdisabledstate \else
%global\setfalse\arrangingdisabledstate
@@ -316,9 +320,10 @@
\global\setfalse\arrangedswapstate
\gdef\arrangedrotationO{0}%
\gdef\arrangedrotationE{180}%
+ % if we use --arrange we have an initial "disable" here
\processcommalist[#1]\doinstalledarrangedoption
- \ifdefined\handlearrangedpage\else
- \global\arrangingpagesfalse
+ \ifrelax\poparrangedpages
+ \global\arrangingpagesfalse % nothing set yet
\fi
\setuppapersize
\ifarrangingpages
@@ -331,24 +336,20 @@
\fi}
\permanent\protected\def\installpagearrangement #1 % will change, no space
- {\setgvalue{\??layoutarranger#1}}
+ {\gdefcsname\??layoutarranger#1\endcsname}
\permanent\def\checkinstalledpagearrangement#1% can be empty: aaa,,bbb
{\begincsname\??layoutarranger#1\endcsname}
-\aliased\let\poparrangedpages \relax
-\aliased\let\pusharrangedpage \relax
-\aliased\let\handlearrangedpage\relax
-
\permanent\protected\def\dosetuparrangement#1#2#3#4#5#6#7#8%
{\global\arrangedpageX #1%
\global\arrangedpageY #2%
\global\arrangedpageT #3%
\global\c_page_marks_nx#4%
\global\c_page_marks_ny#5%
- \enforced\permanent\glet\pusharrangedpage #6%
- \enforced\permanent\glet\poparrangedpages #7%
- \enforced\permanent\glet\handlearrangedpage#8}
+ \enforced\glet\pusharrangedpage #6%
+ \enforced\glet\poparrangedpages #7%
+ \enforced\glet\handlearrangedpage#8}
\installpagearrangement {\v!normal}
{\global\arrangingpagesfalse}
diff --git a/tex/context/base/mkxl/spac-def.mkxl b/tex/context/base/mkxl/spac-def.mkxl
index bba0d47f2..294843cce 100644
--- a/tex/context/base/mkxl/spac-def.mkxl
+++ b/tex/context/base/mkxl/spac-def.mkxl
@@ -45,7 +45,7 @@
% maybe more
\prependtoks
- \let\par\normalpar
+ \enforced\let\par\normalpar
\to \everybeforepagebody % see \fillinline (was endgraf)
% needs checking:
diff --git a/tex/context/base/mkxl/spac-grd.mkxl b/tex/context/base/mkxl/spac-grd.mkxl
index 0f21db726..65739cabe 100644
--- a/tex/context/base/mkxl/spac-grd.mkxl
+++ b/tex/context/base/mkxl/spac-grd.mkxl
@@ -33,19 +33,19 @@
\fi
\endcsname}
-\setvalue{\??lastnodepusher\number\kernnodecode}%
+\defcsname\??lastnodepusher\number\kernnodecode\endcsname
{\enforced\permanent\protected\edef\poplastnode{\kern\the\lastkern\relax}%
\kern-\lastkern}
-\setvalue{\??lastnodepusher\number\gluenodecode}%
+\defcsname\??lastnodepusher\number\gluenodecode\endcsname
{\enforced\permanent\protected\edef\poplastnode{\vskip\the\lastskip\relax}%
\vskip-\lastskip}
-\setvalue{\??lastnodepusher\number\penaltynodecode}%
+\defcsname\??lastnodepusher\number\penaltynodecode\endcsname
{\enforced\permanent\protected\edef\poplastnode{\penalty\the\lastpenalty\relax}%
\nobreak}
-\setvalue{\??lastnodepusher\s!unknown}%
+\defcsname\??lastnodepusher\s!unknown\endcsname
{\enforced\permanent\let\poplastnode\relax}
%D Moved from supp-box:
diff --git a/tex/context/base/mkxl/spac-par.mkxl b/tex/context/base/mkxl/spac-par.mkxl
index 134a60e2a..06aeee4d8 100644
--- a/tex/context/base/mkxl/spac-par.mkxl
+++ b/tex/context/base/mkxl/spac-par.mkxl
@@ -453,4 +453,59 @@
\expandafter\firstofoneargument
\fi}
+%D Something new (experimental and evolving):
+%D
+%D \starttyping
+%D \parshape
+%D 3
+%D options 1 % repeat
+%D 0cm 10cm 2cm 8cm 4cm 6cm
+%D lots of text
+%D \stoptyping
+%D
+%D \starttyping
+%D \parshape 4 5mm 125mm 0mm 120mm 5mm 125mm 0mm 120mm
+%D \pushparagraphtweak {repeat}
+%D verse line 1\crlf
+%D verse line 2\crlf
+%D verse line 3\crlf
+%D verse line 4\par
+%D etc
+%D \popparagraphtweak
+%D \stoptyping
+
+%D But we wrap this in a more abstract interface:
+
+\installcorenamespace {parshapes}
+
+% \installcommandhandler \??shapedparagraph {shapedparagraph} \??shapedparagraph
+
+\aliased\let\stopparagraphshape\relax
+
+\permanent\protected\def\startparagraphshape[#1]#2\stopparagraphshape
+ {\defcsname\??parshapes#1\endcsname{#2}}
+
+\permanent\protected\def\rawparagraphshape#1%
+ {\begincsname\??parshapes#1\endcsname}
+
+\permanent\protected\def\setparagraphshape[#1]%
+ {\ifcsname\??parshapes#1\endcsname
+ \expandafter\clf_setparagraphshape\lastnamedcs done\relax
+ \fi}
+
+% \permanent\protected\tolerant\def\startshapedparagraph[#1]#*[#2]% no grouping
+% {\setparshape[#1]%
+% \pushparagraphtweak{#2}\relax}
+
+\permanent\protected\tolerant\def\startshapedparagraph[#1]% no grouping
+ {\begingroup
+ \getdummyparameters[\c!method=,\c!list=,#1]%
+ \normalexpanded
+ {\endgroup
+ \setparagraphshape[\dummyparameter\c!list]%
+ \pushparagraphtweak{\dummyparameter\c!method}\relax}}
+
+\permanent\protected\def\stopshapedparagraph
+ {\popparagraphtweak}
+
\protect \endinput
diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl
index 6787c7cad..d11611339 100644
--- a/tex/context/base/mkxl/spac-ver.mkxl
+++ b/tex/context/base/mkxl/spac-ver.mkxl
@@ -112,12 +112,12 @@
\aliased\let\setrelativeinterlinespace \relax % used elsewhere
\mutable\let\currentrelativeinterlinespace\empty
-\setvalue{\??interlinespacerelative\v!on }{\oninterlineskip}
-\setvalue{\??interlinespacerelative\v!off }{\offinterlineskip}
-\setvalue{\??interlinespacerelative\v!reset}{\enforced\let\currentrelativeinterlinespace\empty
- \enforced\let\setrelativeinterlinespace\relax
- \setfontparameters}
-\setvalue{\??interlinespacerelative\v!auto }{\enforced\let\setrelativeinterlinespace\spac_linespacing_set_relative_interlinespace}
+\defcsname\??interlinespacerelative\v!on \endcsname{\oninterlineskip}
+\defcsname\??interlinespacerelative\v!off \endcsname{\offinterlineskip}
+\defcsname\??interlinespacerelative\v!reset\endcsname{\enforced\let\currentrelativeinterlinespace\empty
+ \enforced\let\setrelativeinterlinespace\relax
+ \setfontparameters}
+\defcsname\??interlinespacerelative\v!auto \endcsname{\enforced\let\setrelativeinterlinespace\spac_linespacing_set_relative_interlinespace}
\def\spac_linespacing_set_specified_relative_interlinespace#1% fragile?
{\doifelsedimenstring{#1}%
@@ -1244,14 +1244,14 @@
%D Keyword based strutting:
-\letvalue{\??struts\v!yes }\setstrut
-\letvalue{\??struts\v!auto }\setautostrut
-\letvalue{\??struts\v!no }\setnostrut
-\letvalue{\??struts\v!cap }\setcapstrut
-\letvalue{\??struts\v!fit }\setfontstrut
-\letvalue{\??struts\v!line }\setstrut
-\letvalue{\??struts\s!default}\setstrut
-\letvalue{\??struts\empty }\setstrut
+\letcsname\??struts\v!yes \endcsname\setstrut
+\letcsname\??struts\v!auto \endcsname\setautostrut
+\letcsname\??struts\v!no \endcsname\setnostrut
+\letcsname\??struts\v!cap \endcsname\setcapstrut
+\letcsname\??struts\v!fit \endcsname\setfontstrut
+\letcsname\??struts\v!line \endcsname\setstrut
+\letcsname\??struts\s!default\endcsname\setstrut
+\letcsname\??struts\empty \endcsname\setstrut
%D Handy:
@@ -2333,12 +2333,12 @@
{\stopbaselinecorrection
\egroup}
-\letvalue{\??fixedalternatives \v!high}\bbox
-\letvalue{\??fixedalternatives \v!low}\tbox
-\letvalue{\??fixedalternatives \v!middle}\vcenter
-\letvalue{\??fixedalternatives \v!lohi}\vcenter
-\letvalue{\??fixedalternatives\s!unknown}\tbox
-\letvalue{\??fixedalternatives\s!default}\tbox
+\letcsname\??fixedalternatives \v!high\endcsname\bbox
+\letcsname\??fixedalternatives \v!low\endcsname\tbox
+\letcsname\??fixedalternatives \v!middle\endcsname\vcenter
+\letcsname\??fixedalternatives \v!lohi\endcsname\vcenter
+\letcsname\??fixedalternatives\s!unknown\endcsname\tbox
+\letcsname\??fixedalternatives\s!default\endcsname\tbox
\protected\def\typo_fixed_finish#1%
{\expandnamespacevalue\??fixedalternatives{#1}\s!default{\box\nextbox}}
diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl
index 0efbaaaa7..50304d104 100644
--- a/tex/context/base/mkxl/syst-ini.mkxl
+++ b/tex/context/base/mkxl/syst-ini.mkxl
@@ -1131,9 +1131,9 @@
%D For now here: will get a proper solution
-\pushoverloadmode
-\mutable\let\par\par
-\popoverloadmode
+% \pushoverloadmode
+% \mutable\let\par\par
+% \popoverloadmode
%D Also here:
diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl
index 9eede7720..88cd791e4 100644
--- a/tex/context/base/mkxl/tabl-tbl.mkxl
+++ b/tex/context/base/mkxl/tabl-tbl.mkxl
@@ -760,11 +760,11 @@
\installcorenamespace{tabulatecolorspec}
-\setvalue{\??tabulatecolorspec C}#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\zerocount}
-\setvalue{\??tabulatecolorspec L}#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusone }
-\setvalue{\??tabulatecolorspec M}#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plustwo }
-\setvalue{\??tabulatecolorspec R}#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusthree}
-\setvalue{\??tabulatecolorspec T}#1{\xdef\m_tabl_tabulate_text_color{#1}}
+\defcsname\??tabulatecolorspec C\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\zerocount}
+\defcsname\??tabulatecolorspec L\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusone }
+\defcsname\??tabulatecolorspec M\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plustwo }
+\defcsname\??tabulatecolorspec R\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusthree}
+\defcsname\??tabulatecolorspec T\endcsname#1{\xdef\m_tabl_tabulate_text_color{#1}}
\def\tabl_tabulate_set_color_span#1#2%
{\csname\??tabulatecolorspec#1\endcsname{#2}%
@@ -1163,19 +1163,40 @@
\let\currenttabulationparent\empty
\tabl_start_regular}
+% \tolerant\protected\def\tabl_start_regular[#1]#*[#2]% [format] | [settings] | [format] [settings] | [settings] [format]
+% {\let\currenttabulation\currenttabulationparent
+% \iftok{#1}\emptytoks
+% \ifhastok={#2}\relax
+% \setupcurrenttabulation[#2]%
+% \fi
+% \orelse\ifhastok={#1}\relax
+% \iftok{#2}\emptytoks\else
+% \settabulationparameter\c!format{#2}%
+% \fi
+% \setupcurrenttabulation[#1]%
+% \else
+% \settabulationparameter\c!format{#1}%
+% \ifhastok={#2}\relax
+% \setupcurrenttabulation[#2]%
+% \fi
+% \fi
+% \tabl_tabulate_start_building}
+
\tolerant\protected\def\tabl_start_regular[#1]#*[#2]% [format] | [settings] | [format] [settings] | [settings] [format]
{\let\currenttabulation\currenttabulationparent
\iftok{#1}\emptytoks
\ifhastok={#2}\relax
\setupcurrenttabulation[#2]%
\fi
- \orelse\ifhastok={#1}
- \ifhastok{#2}\relax
+ \orelse\ifhastok={#1}\relax
+ \iftok{#2}\emptytoks\else
\settabulationparameter\c!format{#2}%
\fi
\setupcurrenttabulation[#1]%
\else
- \settabulationparameter\c!format{#1}%
+ \iftok{#1}\emptytoks\else
+ \settabulationparameter\c!format{#1}%
+ \fi
\ifhastok={#2}\relax
\setupcurrenttabulation[#2]%
\fi
@@ -1194,10 +1215,10 @@
\enforced\letvalue{\e!start\v!tabulate}\tabl_tabulate_start_ignore % only the main one
\to \everytabulate
-\setvalue{\??tabulatesplit\v!yes }{\settrue\c_tabl_tabulate_split}
-\setvalue{\??tabulatesplit\v!repeat}{\settrue\c_tabl_tabulate_split}
-\setvalue{\??tabulatesplit\v!no }{\setfalse\c_tabl_tabulate_split}
-\setvalue{\??tabulatesplit\v!auto }{\ifinsidefloat\ifinsidesplitfloat\else\setfalse\c_tabl_tabulate_split\fi\fi}
+\defcsname\??tabulatesplit\v!yes \endcsname{\settrue\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!repeat\endcsname{\settrue\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!no \endcsname{\setfalse\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!auto \endcsname{\ifinsidefloat\ifinsidesplitfloat\else\setfalse\c_tabl_tabulate_split\fi\fi}
% todo: spacing around tabulate when bodyfont is set
@@ -1548,13 +1569,13 @@
{\enforced\let#1\tabl_tabulate_column_inject_auto
\enforced\let\\\tabl_tabulate_column_inject_auto} % brrr, will go
-\setvalue{\??tabulateseparator\v!blank }{\s_tabl_tabulate_separator\bigskipamount}
-\setvalue{\??tabulateseparator\v!depth }{\s_tabl_tabulate_separator\strutdp}
-\setvalue{\??tabulateseparator\v!small }{\def\m_tabl_tabulate_separator_factor{.25}}
-\setvalue{\??tabulateseparator\v!medium}{\def\m_tabl_tabulate_separator_factor{.5}}
-\setvalue{\??tabulateseparator\v!big }{}
-\setvalue{\??tabulateseparator\v!none }{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
-\setvalue{\??tabulateseparator\v!grid }{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
+\defcsname\??tabulateseparator\v!blank \endcsname{\s_tabl_tabulate_separator\bigskipamount}
+\defcsname\??tabulateseparator\v!depth \endcsname{\s_tabl_tabulate_separator\strutdp}
+\defcsname\??tabulateseparator\v!small \endcsname{\def\m_tabl_tabulate_separator_factor{.25}}
+\defcsname\??tabulateseparator\v!medium\endcsname{\def\m_tabl_tabulate_separator_factor{.5}}
+\defcsname\??tabulateseparator\v!big \endcsname{}
+\defcsname\??tabulateseparator\v!none \endcsname{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
+\defcsname\??tabulateseparator\v!grid \endcsname{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
\def\tabl_tabulate_column_rule_separator_step#1%
{\ifcsname\??tabulateseparator#1\endcsname
@@ -1758,13 +1779,13 @@
%D Beware, we cannot use \type {\protected} on \type {\HL} cum suis, since \TEX's
%D hard coded noalign lookahead fails on it! I mistakenly added this for a while.
-\setvalue{\??tabulatealigning\v!normal}{0}
-\setvalue{\??tabulatealigning\v!right }{1}
-\setvalue{\??tabulatealigning\v!left }{2}
-\setvalue{\??tabulatealigning\v!middle}{3}
+\defcsname\??tabulatealigning\v!normal\endcsname{0}
+\defcsname\??tabulatealigning\v!right \endcsname{1}
+\defcsname\??tabulatealigning\v!left \endcsname{2}
+\defcsname\??tabulatealigning\v!middle\endcsname{3}
-\setvalue{\??tabulateheader\v!repeat}{\plusone}
-\setvalue{\??tabulateheader\v!text }{\plustwo}
+\defcsname\??tabulateheader\v!repeat\endcsname{\plusone}
+\defcsname\??tabulateheader\v!text \endcsname{\plustwo}
\protected\def\tabl_tabulate_bskip_first {\setbox\b_tabl_tabulate\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
\protected\def\tabl_tabulate_eskip_first {\par\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
@@ -2584,13 +2605,13 @@
\pushoverloadmode
-\permanent\protected\setuvalue{starttabulate}%
+\permanent\protected\defcsname starttabulate\endcsname
{\bgroup % whole thing
\settrue\c_tabl_generic
\let\currenttabulationparent\empty
\tabl_start_regular}
-\permanent\letvalue{stoptabulate}\relax % testcase cvs-002.tex
+\permanent\letcsname stoptabulate\endcsname\relax % testcase cvs-002.tex
\popoverloadmode
diff --git a/tex/context/base/mkxl/typo-par.lmt b/tex/context/base/mkxl/typo-par.lmt
new file mode 100644
index 000000000..c7204ecd2
--- /dev/null
+++ b/tex/context/base/mkxl/typo-par.lmt
@@ -0,0 +1,177 @@
+if not modules then modules = { } end modules ['typo-par'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Just some experimental stuff .. trying to improve some ancient metafun manual
+-- hackery that has been on the angenda for too long already. Names might names
+-- anyway.
+
+local insert, remove = table.insert, table.remove
+
+local texget = tex.get
+local texset = tex.set
+local shiftparshape = tex.shiftparshape
+
+local sequencers = utilities.sequencers
+local appendaction = sequencers.appendaction
+local enableaction = sequencers.enableaction
+local disableaction = sequencers.disableaction
+
+local stack = { }
+local top = nil
+local enabled = false
+
+interfaces.implement {
+ name = "pushparagraphtweak",
+ public = true,
+ protected = true,
+ arguments = "string",
+ actions = function(t)
+ insert(stack,top)
+ if not top then
+ enableaction("paragraphcontext","builders.checkparcontext")
+ enabled = true
+ end
+ top = t
+ end
+}
+interfaces.implement {
+ name = "popparagraphtweak",
+ public = true,
+ protected = true,
+ actions = function()
+ top = remove(stack)
+ if not top then
+ disableaction("paragraphcontext","builders.checkparcontext")
+ enabled = false
+ end
+ end
+}
+
+function builders.checkparcontext(where)
+ if top and where == "normal" then
+ if top == "cycle" then
+ local s = texget("parshape",true)
+ if s then
+ local p = texget("prevgraf")
+ while p > s do
+ p = p - s
+ end
+ shiftparshape(p,true)
+ end
+ return true
+ elseif top == "shift" then
+ shiftparshape(texget("prevgraf"))
+ return true
+ end
+ end
+end
+
+appendaction("paragraphcontext","system","builders.checkparcontext")
+
+-- Another experiment: continuing parshapes with alternative definitions:
+--
+-- left d | right d | left d right d | both d | left d hsize d |
+-- copy n | reset | repeat | done
+
+do
+
+ local scanners = tokens.scanners
+ local scanword = scanners.word
+ local scandimen = scanners.dimen
+ local scancardinal = scanners.cardinal
+
+ interfaces.implement {
+ name = "setparagraphshape",
+ protected = true,
+ actions = function()
+ local t = { }
+ local n = 0
+ local h = texget("hsize")
+ while true do
+ local key = scanword()
+ ::AGAIN::
+ if key == "left" then
+ local l = scandimen()
+ key = scanword()
+ if key == "right" then
+ n = n + 1 ; t[n] = { l, h - l - scandimen() }
+ elseif key == "hsize" then
+ n = n + 1 ; t[n] = { l, scandimen() }
+ else
+ n = n + 1 ; t[n] = { l, h }
+ goto AGAIN
+ end
+ elseif key == "right" then
+ n = n + 1 ; t[n] = { 0, h - scandimen() }
+ elseif key == "both" then
+ local b = scandimen()
+ n = n + 1 ; t[n] = { b, h - b - b }
+ elseif key == "copy" then
+ local c = scancardinal()
+ for i=1,c do
+ local m = n + 1
+ t[m] = t[n]
+ n = m
+ end
+ elseif key == "done" then
+ -- in case the user ended with "done"
+ scanword()
+ break
+ elseif key == "repeat" then
+ t["repeat"] = true
+ elseif key == "reset" then
+ n = n + 1 ; t[n] = { 0, h }
+ break
+ else
+ logs.report("system","bad key %a in paragraphshape",key)
+ break
+ end
+ end
+ texset("parshape",t)
+ end,
+ }
+
+ local NC = context.NC
+ local NR = context.NR
+ local VL = context.VL
+
+ interfaces.implement {
+ name = "showparagraphshape",
+ protected = true,
+ public = true,
+ actions = function()
+ local p = texget("parshape")
+ if p then
+ -- only english interface (for now)
+ context.inleftmargin(
+ {
+ align = "flushright",
+ strut = "no",
+ width = "0pt",
+ -- voffset = "-\\lineheight"
+ }, function()
+ context.starttabulate {
+ before = "",
+ after = "",
+ unit = "2pt",
+ rulethickness = ".1pt",
+ format = "|rb{\\smallinfofont}|lb{\\smallinfofont}|"
+ }
+ for i=1,#p do
+ NC() context("%P",p[i][1])
+ VL() context("%P",p[i][2])
+ NC() NR()
+ end
+ context.stoptabulate()
+ end
+ )
+ end
+ end
+ }
+
+end
diff --git a/tex/context/base/mkxl/typo-par.mkxl b/tex/context/base/mkxl/typo-par.mkxl
index de40c6568..22450e76e 100644
--- a/tex/context/base/mkxl/typo-par.mkxl
+++ b/tex/context/base/mkxl/typo-par.mkxl
@@ -26,5 +26,35 @@
%registerctxluafile{node-ltp}{optimize}
\registerctxluafile{node-ltp}{}
\registerctxluafile{trac-par}{}
+\registerctxluafile{typo-par}{}
+
+%D Just a reminder:
+%D
+%D \starttyping
+%D \def\whatever#1{#1mm \dimexpr\hsize-#1mm\relax}
+%D
+%D \parshape
+%D 14
+%D options 1 % repeat
+%D \whatever{0} \whatever {2}\whatever {4}\whatever{6}\whatever{8}\whatever{10}\whatever{12}\whatever{14}
+%D \whatever{12}\whatever{10}\whatever{8}\whatever{6}\whatever {4}\whatever {2}
+%D \pushparagraphtweak {repeat}
+%D \dorecurse{10}{\samplefile{tufte} \samplefile{tufte} \par}
+%D \popparagraphtweak
+%D \page
+%D
+%D \dorecurse{2}{
+%D \parshape 4 5mm 125mm 0mm 120mm 5mm 125mm 0mm 120mm
+%D \pushparagraphtweak {repeat}
+%D \dorecurse{10}{
+%D verse line 1\crlf
+%D verse line 2\crlf
+%D verse line 3\crlf
+%D verse line 4\par
+%D }
+%D \popparagraphtweak
+%D \page
+%D }
+%D \stoptyping
\protect \endinput
diff --git a/tex/context/modules/mkxl/s-colors-show.mkxl b/tex/context/modules/mkxl/s-colors-show.mkxl
index 7467acd4c..aa0e3227e 100644
--- a/tex/context/modules/mkxl/s-colors-show.mkxl
+++ b/tex/context/modules/mkxl/s-colors-show.mkxl
@@ -41,7 +41,7 @@
%D Palets
-permanent\protected\tolerant\gdef\showpalet[#1]#*[#2]%
+\permanent\protected\tolerant\gdef\showpalet[#1]#*[#2]%
{\doifelsecolorpalet{#1}
{\doifelseinset\v!vertical{#2}\colo_palets_show_vertical\colo_palets_show_horizontal{#1}{#2}}%
{}}
@@ -152,7 +152,7 @@ permanent\protected\tolerant\gdef\showpalet[#1]#*[#2]%
%D Groups
-permanent\protected\tolerant\gdef\showcolorgroup[#1]#*[#2]%
+\permanent\protected\tolerant\gdef\showcolorgroup[#1]#*[#2]%
{\doifcolor{#1:1}
{\doifelseinset\v!vertical{#2}\colo_groups_show_vertical\colo_groups_show_horizontal{#1}{#2}}}
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 7952d615c..2880d77c0 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 : 2021-02-23 17:41
+-- merge date : 2021-02-27 19:27
do -- begin closure to overcome local limits and interference
@@ -3158,25 +3158,59 @@ local function points(n)
n=n*ptf
if n%1==0 then
return format("%ipt",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+ end
+end
+local function nupoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
if n==0 then
- return "0pt"
+ return "0bp"
end
n=tonumber(n)
if not n or n==0 then
- return "0pt"
+ return "0bp"
end
n=n*bpf
if n%1==0 then
return format("%ibp",n)
+ else
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+ end
+end
+local function nubasepoints(n)
+ if n==0 then
+ return "0"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%i",n)
+ else
+ return format("%.5f",n)
end
- return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
+number.nupoints=nupoints
number.basepoints=basepoints
+number.nubasepoints=nubasepoints
local rubish=spaceortab^0*newline
local anyrubish=spaceortab+newline
local stripped=(spaceortab^1/"")*newline
@@ -3454,7 +3488,9 @@ local environment={
concat=table.concat,
signed=number.signed,
points=number.points,
+ nupoints=number.nupoints,
basepoints=number.basepoints,
+ nubasepoints=number.nubasepoints,
utfchar=utf.char,
utfbyte=utf.byte,
lpegmatch=lpeg.match,
@@ -3649,10 +3685,18 @@ local format_p=function()
n=n+1
return format("points(a%s)",n)
end
+local format_P=function()
+ n=n+1
+ return format("nupoints(a%s)",n)
+end
local format_b=function()
n=n+1
return format("basepoints(a%s)",n)
end
+local format_B=function()
+ n=n+1
+ return format("nubasepoints(a%s)",n)
+end
local format_t=function(f)
n=n+1
if f and f~="" then
@@ -3805,7 +3849,7 @@ local builder=Cs { "start",
+V("n")
+V("N")
+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("P")+V("b")+V("B")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
+V("A")
@@ -3843,7 +3887,9 @@ local builder=Cs { "start",
["u"]=(prefix_any*P("u"))/format_u,
["U"]=(prefix_any*P("U"))/format_U,
["p"]=(prefix_any*P("p"))/format_p,
+ ["P"]=(prefix_any*P("P"))/format_P,
["b"]=(prefix_any*P("b"))/format_b,
+ ["B"]=(prefix_any*P("B"))/format_B,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
["l"]=(prefix_any*P("l"))/format_l,