From 4f7f67101a808c6b6c89d64ad5ee1f1701d8f632 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sat, 27 Feb 2021 20:17:05 +0100 Subject: 2021-02-27 19:30:00 --- .../lexers/data/scite-context-data-metafun.lua | 2 +- .../context/scite-context-data-metafun.properties | 23 +- .../context/data/scite-context-data-metafun.lua | 2 +- .../context/syntaxes/context-syntax-mps.json | 2 +- .../general/manuals/lowlevel-paragraphs.pdf | Bin 0 -> 140547 bytes .../general/manuals/lowlevel/lowlevel-boxes.tex | 10 +- .../manuals/lowlevel/lowlevel-paragraphs.tex | 423 +++++++++++++++++++++ .../general/manuals/metafun/metafun-basics.tex | 66 +++- .../general/manuals/metafun/metafun-debugging.tex | 163 +++++++- .../general/manuals/metafun/metafun-examples.tex | 253 ++++++++++++ .../general/manuals/metafun/metafun-lua.tex | 276 ++++++++++++++ .../general/manuals/metafun/metafun-macros.tex | 13 +- metapost/context/base/mpiv/mp-luas.mpiv | 5 + metapost/context/base/mpxl/mp-luas.mpxl | 10 +- metapost/context/base/mpxl/mp-text.mpxl | 157 ++++++++ scripts/context/lua/mtxrun.lua | 62 ++- scripts/context/stubs/mswin/mtxrun.lua | 62 ++- scripts/context/stubs/unix/mtxrun | 62 ++- scripts/context/stubs/win64/mtxrun.lua | 62 ++- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/mlib-mpf.lua | 10 + tex/context/base/mkiv/mtx-context-select.tex | 2 - tex/context/base/mkiv/mult-fun.lua | 1 + tex/context/base/mkiv/status-files.pdf | Bin 25351 -> 25335 bytes tex/context/base/mkiv/status-lua.pdf | Bin 256039 -> 256139 bytes tex/context/base/mkiv/util-str.lua | 70 +++- tex/context/base/mkxl/bibl-tra.mkxl | 9 +- tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/meta-imp-txt.lmt | 86 +++++ tex/context/base/mkxl/meta-imp-txt.mkxl | 339 +++++++++++++++++ tex/context/base/mkxl/mlib-lua.lmt | 72 ++-- tex/context/base/mkxl/mlib-mpf.lmt | 6 + tex/context/base/mkxl/mlib-pps.lmt | 20 - tex/context/base/mkxl/mlib-run.lmt | 2 +- tex/context/base/mkxl/mult-sys.mkxl | 2 +- tex/context/base/mkxl/node-par.lmt | 88 +++-- tex/context/base/mkxl/pack-mrl.mkxl | 2 +- tex/context/base/mkxl/page-imp.mkxl | 25 +- tex/context/base/mkxl/spac-def.mkxl | 2 +- tex/context/base/mkxl/spac-grd.mkxl | 8 +- tex/context/base/mkxl/spac-par.mkxl | 55 +++ tex/context/base/mkxl/spac-ver.mkxl | 40 +- tex/context/base/mkxl/syst-ini.mkxl | 6 +- tex/context/base/mkxl/tabl-tbl.mkxl | 75 ++-- tex/context/base/mkxl/typo-par.lmt | 177 +++++++++ tex/context/base/mkxl/typo-par.mkxl | 30 ++ tex/context/modules/mkxl/s-colors-show.mkxl | 4 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 58 ++- 52 files changed, 2622 insertions(+), 232 deletions(-) create mode 100644 doc/context/documents/general/manuals/lowlevel-paragraphs.pdf create mode 100644 doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex create mode 100644 metapost/context/base/mpxl/mp-text.mpxl create mode 100644 tex/context/base/mkxl/meta-imp-txt.lmt create mode 100644 tex/context/base/mkxl/meta-imp-txt.mkxl create mode 100644 tex/context/base/mkxl/typo-par.lmt 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 Binary files /dev/null and b/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf 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 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, -- cgit v1.2.3