summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-metafun.lua2
-rw-r--r--context/data/scite/context/scite-context-data-metafun.properties13
-rw-r--r--context/data/textadept/context/data/scite-context-data-metafun.lua2
-rw-r--r--context/data/vscode/extensions/context/syntaxes/context-syntax-mps.json2
-rw-r--r--doc/context/documents/general/manuals/luametatex.pdfbin1383078 -> 1380089 bytes
-rw-r--r--doc/context/sources/general/manuals/followingup/followingup-fonts.tex248
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-modifications.tex2
-rw-r--r--metapost/context/base/mpxl/mp-lmtx.mpxl5
-rw-r--r--metapost/context/base/mpxl/mp-luas.mpxl5
-rw-r--r--metapost/context/base/mpxl/mp-math.mpxl40
-rw-r--r--metapost/context/fonts/mpiv/punkfont-characters.mp19
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-imp-math.lua28
-rw-r--r--tex/context/base/mkiv/font-imp-tracing.lua104
-rw-r--r--tex/context/base/mkiv/font-pre.mkiv1
-rw-r--r--tex/context/base/mkiv/good-mth.lua167
-rw-r--r--tex/context/base/mkiv/math-act.lua113
-rw-r--r--tex/context/base/mkiv/mult-fun.lua2
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26131 -> 26114 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin254409 -> 254915 bytes
-rw-r--r--tex/context/base/mkiv/strc-mar.lua2
-rw-r--r--tex/context/base/mkiv/task-ini.lua1
-rw-r--r--tex/context/base/mkxl/anch-pos.lmt7
-rw-r--r--tex/context/base/mkxl/attr-alt.lmt111
-rw-r--r--tex/context/base/mkxl/attr-alt.mkxl55
-rw-r--r--tex/context/base/mkxl/attr-eff.mkxl4
-rw-r--r--tex/context/base/mkxl/attr-ini.mkxl1
-rw-r--r--tex/context/base/mkxl/back-ext.mkxl (renamed from tex/context/base/mkxl/back-trf.mkxl)14
-rw-r--r--tex/context/base/mkxl/back-ini.lmt30
-rw-r--r--tex/context/base/mkxl/back-out.lmt255
-rw-r--r--tex/context/base/mkxl/back-out.mkxl22
-rw-r--r--tex/context/base/mkxl/back-pdf.mkxl1
-rw-r--r--tex/context/base/mkxl/back-trf.lmt164
-rw-r--r--tex/context/base/mkxl/colo-nod.lmt6
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl10
-rw-r--r--tex/context/base/mkxl/driv-shp.lmt656
-rw-r--r--tex/context/base/mkxl/font-chk.lmt1
-rw-r--r--tex/context/base/mkxl/font-con.lmt36
-rw-r--r--tex/context/base/mkxl/font-fbk.lmt9
-rw-r--r--tex/context/base/mkxl/font-imp-math.lmt31
-rw-r--r--tex/context/base/mkxl/font-imp-tracing.lmt286
-rw-r--r--tex/context/base/mkxl/font-lib.mklx6
-rw-r--r--tex/context/base/mkxl/font-ogr.lmt69
-rw-r--r--tex/context/base/mkxl/font-pre.mkxl4
-rw-r--r--tex/context/base/mkxl/font-vfc.lmt108
-rw-r--r--tex/context/base/mkxl/good-mth.lmt464
-rw-r--r--tex/context/base/mkxl/layo-ini.lmt115
-rw-r--r--tex/context/base/mkxl/layo-ini.mkxl2
-rw-r--r--tex/context/base/mkxl/lpdf-col.lmt170
-rw-r--r--tex/context/base/mkxl/lpdf-ini.lmt29
-rw-r--r--tex/context/base/mkxl/lpdf-lmt.lmt231
-rw-r--r--tex/context/base/mkxl/lpdf-mis.lmt79
-rw-r--r--tex/context/base/mkxl/lpdf-ren.lmt12
-rw-r--r--tex/context/base/mkxl/lpdf-rul.lmt8
-rw-r--r--tex/context/base/mkxl/lpdf-tag.lmt16
-rw-r--r--tex/context/base/mkxl/lpdf-vfc.lmt42
-rw-r--r--tex/context/base/mkxl/math-act.lmt480
-rw-r--r--tex/context/base/mkxl/math-ali.mkxl2
-rw-r--r--tex/context/base/mkxl/math-ini.mkxl2
-rw-r--r--tex/context/base/mkxl/math-noa.lmt9
-rw-r--r--tex/context/base/mkxl/meta-imp-punk.mkxl272
-rw-r--r--tex/context/base/mkxl/mlib-mpf.lmt7
-rw-r--r--tex/context/base/mkxl/node-ext.lmt650
-rw-r--r--tex/context/base/mkxl/node-fin.lmt76
-rw-r--r--tex/context/base/mkxl/node-ini.lmt46
-rw-r--r--tex/context/base/mkxl/node-ini.mkxl4
-rw-r--r--tex/context/base/mkxl/node-res.lmt41
-rw-r--r--tex/context/base/mkxl/node-syn.lmt782
-rw-r--r--tex/context/base/mkxl/node-tra.lmt2
-rw-r--r--tex/context/base/mkxl/page-lin.lmt2
-rw-r--r--tex/context/base/mkxl/scrn-pag.lmt56
-rw-r--r--tex/context/base/mkxl/scrn-pag.mklx2
-rw-r--r--tex/context/base/mkxl/spac-hor.mkxl35
-rw-r--r--tex/context/base/mkxl/strc-reg.mkxl14
-rw-r--r--tex/context/base/mkxl/trac-vis.lmt48
-rw-r--r--tex/context/base/mkxl/typo-cap.lmt23
-rw-r--r--tex/context/fonts/mkiv/bonum-math.lfg22
-rw-r--r--tex/context/fonts/mkiv/dejavu-math.lfg15
-rw-r--r--tex/context/fonts/mkiv/minion-math.lfg10
-rw-r--r--tex/context/fonts/mkiv/pagella-math.lfg24
-rw-r--r--tex/context/fonts/mkiv/schola-math.lfg16
-rw-r--r--tex/context/fonts/mkiv/termes-math.lfg22
-rw-r--r--tex/context/fonts/mkiv/type-imp-punk.mkxl54
-rw-r--r--tex/context/fonts/mkiv/type-imp-texgyre.mkiv16
-rw-r--r--tex/context/fonts/mkiv/xits-math.lfg1
-rw-r--r--tex/context/modules/mkiv/m-punk.mkiv5
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
91 files changed, 4756 insertions, 1804 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
index d02ed5332..edbf39a57 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", "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" },
+ ["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" },
["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 ac2a048df..79f8b5087 100644
--- a/context/data/scite/context/scite-context-data-metafun.properties
+++ b/context/data/scite/context/scite-context-data-metafun.properties
@@ -72,12 +72,13 @@ positionpath positioncurve positionxy positionpxy positionwhd \
positionpage positionregion positionbox positionanchor positioninregion \
positionatanchor wdpart htpart dppart texvar \
texstr inpath pointof leftof rightof \
-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
+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
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 d02ed5332..edbf39a57 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", "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" },
+ ["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" },
["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 9000bd62f..29bb24058 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|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|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|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|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/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index 635e56000..f5ece94d6 100644
--- a/doc/context/documents/general/manuals/luametatex.pdf
+++ b/doc/context/documents/general/manuals/luametatex.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/followingup/followingup-fonts.tex b/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
index 2f7320b12..6bc10e929 100644
--- a/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
+++ b/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
@@ -23,7 +23,24 @@ Fonts come in sizes, and for instance Latin Modern has quite a few variants wher
the shapes are adapted to the size. This means that when you need a 9pt regular
shape alongside a 12pt one, two fonts have to be loaded. This is quite visible in
math where we have three related sizes: text, script and scriptscript, grouped in
-so called families.
+so called families. When we scale the digit~2 to the same height you will notice
+that the text, script and scriptscript sizes look different (the last three are
+unscaled):
+
+\startlinecorrection
+\dontleavehmode\scale[frame=on,height=5ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,width=4em]{\colored[r=.6,a=1,t=.5]{$\textstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[g=.6,a=1,t=.5]{$\scriptstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[b=.6,a=1,t=.5]{$\scriptscriptstyle 2$}}\quad\quad
+\dontleavehmode{$\textstyle 2$}\quad
+\dontleavehmode{$\scriptstyle 2$}\quad
+\dontleavehmode{$\scriptscriptstyle 2$}\quad
+\stoplinecorrection
Plenty has been written (in various documents that come with \CONTEXT) about how
this all works together and how it impacts the design of the system, so here I
@@ -34,62 +51,82 @@ just give a short summary of what a font system has to deal with.
In a bodyfont setup different sizes (9pt, 10pt, 12pt) can have their own
specific set of fonts. This can result in quite some definitions that relate
to the style, like regular, bold, italic, bolditalic, slanted and
- boldslanted, etc. When possible loading the fonts is delayed.
+ boldslanted, etc. When possible loading the fonts is delayed. But in
+ \CONTEXT\ often the number of actually loaded fonts is not that large.
\stopitem
\startitem
Some font designs have different shapes per bodyfont size. A minor
- complication is that when one is missing some heuristic best match choice
- might be needed.
+ complication is that when one is missing some heuristic best|-|match choice
+ might be needed. Okay, in practice only Latin Modern falls into this
+ category. Maybe \OPENTYPE\ variable fonts can be seen this way, but, although
+ we supported that right from the start, I haven't noticed much interest in
+ the \TEX\ community.
\stopitem
\startitem
Within a bodyfont size we distinguish size variants. We can go smaller (x and
xx), for instance when we use sub- and superscripts in text, or we can go
- larger, for instance in titling (a, b, c, d, \unknown). Fortunately most of
+ larger, for instance in titles (a, b, c, d, \unknown). Fortunately most of
the loading of these can be delayed too.
\stopitem
\startitem
When instances are not available, scaling can be used, as happens for
instance with 11pt in Computer Modern. Actually, this is why in \CONTEXT\ we
default to 12pt, because the scaled versions didn't look as nice as the
- others.
+ others (keep in mind that we started in the age of bitmaps).
\stopitem
\startitem
Special features, like smallcaps or oldstyle numerals, can demand their own
definitions. More loading and automatic definitions can be triggered by sizes
- needed in for instance scripts and titling.
+ needed in for instance scripts and titles.
\stopitem
\startitem
A document can have a mixed setup, that is: use different font designs in one
document, so some kind of namespace subsystem is needed.
\stopitem
\startitem
- In traditional eight bit engine the dependency of hyphenation on the encoding
- of a font can result in the necessity to load a font multiple times in
- different encodings, something that depends on the language mix used.
+ In an eight bit font world, we not only have text fonts but also collections
+ of symbols, and even in math there are additional symbol collections. In
+ \OPENTYPE\ symbols end up in text fonts, but there we have tons of emoji's
+ and color fonts. All has to be dealt with in an integrated way. And we're
+ not even talking of virtual fonts, (runtime) \METAPOST\ generated fonts, and
+ so on.
+\stopitem
+\startitem
+ In traditional eight bit engines the dependency of hyphenation on the
+ encoding of a font can result in the necessity to load a font multiple times
+ in different encodings, something that depends on the language mix used.
+ Interesting is that coming up with an European encoding (covering most Latin
+ languages) was not that hard, especially when one keeps in mind that many
+ eight bit encodings waste slots on seldom used symbols, but by that time
+ \OPENTYPE\ and and \UNICODE\ input started to dominate.
\stopitem
\startitem
In the more modern \OPENTYPE\ fonts combinations of features can demand
- additional instances (one can thing of language|/|script combinations,
+ additional instances (one can think of language|/|script combinations,
substitutions in base mode, special effects like boldening, color fonts,
etc.).
\stopitem
\startitem
- Math is complicated by the fact that alphabets come from different fonts
- (sometimes a font has several alphabets which means that some mapping can be
- needed). Operating on the size, shape, encoding and style axes puts some
- demands on the font system. Add to this (often) partial (due to lack of
- fonts) bold support and it gets even more complicated.
+ Math is complicated by the fact that in traditional \TEX\ alphabets come from
+ different fonts which is why we have many so called families; sometimes a
+ font has several alphabets which means that some mapping can be needed.
+ Operating on the size, shape, encoding and style axes puts some demands on
+ the font system. Add to this (often) partial (due to lack of fonts) bold
+ support and it gets even more complicated. In \OPENTYPE\ all the alphabets
+ come from one font.
\stopitem
\startitem
There is additional math auto|-|definition and loading code for the sizes
- used in text scripts and titling.
+ used in text scripts and titles.
\stopitem
\stopitemize
All this has resulted in a pretty complex subsystem. Although going \OPENTYPE\
(and emulated \OPENTYPE\ with \TYPEONE\ fonts as we do in \MKIV) removes some
complications, like encodings, it does also add complexity because of the many
-possible font features, either or not dependent on script and language.
+possible font features, either or not dependent on script and language. Text as
+well as math got simpler at the \TEX\ end (but that is compensated by quite a bit
+\LUA\ code that deals with new features).
Also, in order to let a font subsystem not impact performance to much, let alone
extensive memory usage, the \CONTEXT\ font subsystem is rather optimized. The
@@ -102,26 +139,27 @@ always been rather fast.
\startsection[title={Reality}]
In \MKIV\ and therefore also in \LMTX\ more font magic happens. The initial node
-lists that makes up a box or paragraph can get manipulated in several ways and
-often fonts are involved. The mentioned font features can be defines static (as
-part of the definition) or dynamic (resolved on the spot at the cost of some
-overhead). Characters can be remapped, fonts can be replaced. The math subsystem
-in \MKIV\ was different right from the start: we use a limited number of families
-(regular, bold, l2r and r2l), and stay abstract till the moment we need to deal
-with the specific alphabets. But still, in \MKIV, we have the families with three
-fonts.
+lists that make up a box or paragraph can get manipulated in several ways and
+often fonts are involved. The font features (smallcaps, oldstyle, alternates,
+etc.) can be defined static (as part of the definition) or dynamic (resolved on
+the spot at the cost of some overhead). Characters can be remapped, fonts can be
+replaced. The math subsystem in \MKIV\ was different right from the start: we use
+a limited number of families (regular, bold, l2r and r2l), and stay abstract till
+the moment we need to deal with the specific alphabets. But still, in \MKIV, we
+have the families with three fonts.
In the \LUAMETATEX\ manual we show some math magic and we do so for different
-fonts. As a side effect, we set up half a dozen bodyfont collections. Even with
-delayed and shared font loading, we end up with 158 instances but quite a bit of
-them are math fonts, at least six per bodyfont size: regular and bold (boldened)
-text, script and scriptscript. Of course most are just copies with different
-scaling that reuse already loaded resources.
+fonts. As a side effect, we set up half a dozen bodyfont collections: Lucida,
+Pagella, Latin Modern, Dejavu, the math standard Cambria, etc. Even with delayed
+and shared font loading, we end up with 158 instances but quite a bit of them are
+math fonts, at least six per bodyfont size: regular and bold (boldened) text,
+script and scriptscript. Of course most are just copies with different scaling
+that reuse already loaded resources. In the final\PDF\ we have 21 subset fonts.
If we look at the math fonts that we use today, there is however quite some
overlap. It starts with a text font. From that script and scriptscript variants
are derived, but often these variants use many text size related shapes too. Some
-shapes get alternatives (from the \type {ssty} feature), and the whole clone get
+shapes get alternatives (from the \type {ssty} feature), and the whole clone gets
scaled. But, much of the logic of for instance extensibles is the same.
A similar situation happens with for instance large \CJK\ fonts: there are hardly
@@ -130,19 +168,25 @@ dimensions, and these fonts can be real huge!
Actually, when we talk about features, in many cases in \CONTEXT\ you don't
define them as part of the font. For instance small caps can best be triggered by
-using a dynamic feature: applied to a specific stretch of text. When the font
-handler does its work there are actually four cases: no features get applied,
-something that for instance happens with most monospaced fonts, base mode is
-used, which means that the \TEX\ machinery takes care of constructing ligatures
-and injecting kerns, and node mode, where \LUA\ handles the features. The fourth
-case is a special case of node mode where a different features set is applied.
-\footnote {We also have so called plug mode where an external rendered can do the
-work but that one is only around for some experiments during Idris' font
-development.} At the cost of some extra overhead (for each node mode run) dynamic
-features are quite powerful and save quite some memory and definitions. The
-overhead comes from much more testing regarding the font we deal with because
-suddenly the same font can demand different treatments, depending on what dynamic
-features is active.
+using a dynamic feature: applied to a specific stretch of text. In fact, often
+features like superiors of fractions only work well on characters that fit the
+bill and produce weird side effects otherwise (a matter of design completeness).
+When the font handler does its work there are actually four cases: no features
+get applied, something that for instance happens with most mono spaced fonts,
+base mode is used, which means that the \TEX\ machinery takes care of
+constructing ligatures and injecting kerns, and node mode, where \LUA\ handles
+the features. The fourth case is a special case of node mode where a different
+feature set is applied. \footnote {We also have so called plug mode where an
+external renderer can do the work but that one is only around for some
+experiments during Idris Hamid's font development.} At the cost of some extra
+overhead (for each node mode run) dynamic features are quite powerful and save
+quite some memory and definitions. \footnote {The generic font handler that is
+derived from the \CONTEXT\ one doesn't implement this so it runs a little
+faster.} The overhead comes from much more testing regarding the font we deal
+with because suddenly the same font can demand different treatments, depending on
+what dynamic features are active. \footnote {Originally this model was introduced
+for a dynamic paragraph optimization subsystem for Arabic but no one really uses
+it because there there are no suitable fonts.}
Although the font handling is responsible for much of the time spent in \LUA, it is
still reasonable given what has to be done. Actually, because we have an extensible
@@ -183,8 +227,8 @@ e{\glyphxscale 2500 ffi}cient
So, in order to deal with this kind of scaling, we now operate not only on the
font (id) and dynamic feature axes, but also on the scales of which we have three
-variants: glyph scale, glyph xscale and glyph y scale). There is actually also a
-state dimension but we leave that for now. Think of flagging glyphs as initial or
+variants: glyph scale, glyph xscale and glyph yscale). There is actually also a
+state dimension but we leave that for now; think of flagging glyphs as initial or
final. This brings the number of axis to six. It is important to stress that in
these examples the same font instance is used!
@@ -197,22 +241,22 @@ go together but for now I see no real gain in that.
\startsection[title={Math}]
-Given what is written in the previous sections, a logical question is if we can
-apply scaling to math and the answer is \quotation {yes, we can}. But we actually
-go a bit further and that is partly due to some other properties of the engine.
+Given what is written in the previous sections, a logical question would be
+\quotation {Can we apply scaling to math?} and the answer is \quotation {Yes, we
+can!}. But we actually go a bit further and that is partly due to some other
+properties of the engine.
From \PDFTEX\ the \LUATEX\ engines inherited character protrusion and glyph
expansions, aka hz. However, where in \PDFTEX\ copies of the font are made that
carry the expanded dimensions, in \LUATEX\ at some point this was replaced by an
expansion field in the glyph and kern nodes. So, instead of changing the font id
of expanded glyphs, the same id is used but with the applied expansion factor set
-in the glyph. A side effect was that in places where dimensions are needed, calls
-to functions that calculate the expanded widths on request (as these can change
-during linebreak calculations) in combination with accessing font dimensions
-directly, we now always use accessor functions. This level of abstraction is even
-more present in \LUAMETATEX. This means that we have an uniform interface to
-fonts and as a side effect scaling is to be dealt with in only a few places in
-the code.
+in the glyph. A side effect was that in places where dimensions are needed, we
+call functions that calculate the expanded widths on request (as these can
+change during linebreak calculations) in combination with accessing font
+dimensions directly. This level of abstraction is even more present in
+\LUAMETATEX. This means that we have an uniform interface to fonts and as a side
+effect scaling is to be dealt with in only a few places in the code.
Now, in math we have a few more complications. First of all, we have three sizes
to consider and we also have lots of parameters that depend on the size. But, as
@@ -236,9 +280,9 @@ the math engine needs a specific character at a given size (text, script,
scriptscript) we just follow that chain.
In an \OPENTYPE\ math font the script and scriptscript sizes are specified as
-percentages of the text size. So, when the dimensions of a glyph are needed, we
-just scale on the fly. Again this adds some overhead but I'm pretty sure that no
-user will notice this.
+percentages of the text size. When the dimensions of a glyph are needed, we just
+scale on the fly. Again this adds some overhead but I'm pretty sure that no user
+will notice this.
So, to summarize: if we need a character at scriptscript size, we access the text
size glyph, check for a pointer to a script size, go there, and again check for a
@@ -246,8 +290,11 @@ smaller size. We just use what fits the bill. And, when we need dimensions we
just scale. In order to scale we need the relative size, so we need to set that
up when we load the font. Because in \CONTEXT\ we also can assemble a virtual
\OPENTYPE\ font from \TYPEONE\ fonts, it was actually that (old) compatibility
-feature that took most time to adapt, not so much because it is complicates but
-because in \LMTX\ we have to bypass some advanced loading mechanisms.
+feature, the one that implements \TYPEONE\ bases \OPENTYPE\ math, that took most
+time to adapt, not so much because it is complicates but because in \LMTX\ we
+have to bypass some advanced loading mechanisms. Because we can scale in two
+dimensions the many (font related) math parameters also need to be dealt with
+accordingly.
The end result is that for math we now only need to define two fonts per bodyfont
setup: regular and bold at the natural scale (normally 10pt) and we share these
@@ -283,12 +330,12 @@ manual we get these stats:
\stoptyping
So, we win on all fronts when we use this glyph scale mechanism. The magic
-primitive that deals with this is \type {\glyphscale} which accepts a number,
-where \type {1200} and \type {1.2} both mean scaling to 20\percent\ more than
-normal. But one can best not use this primitive directly.
+primitive that deals with this is \type {\glyphscale} primitive that accepts a
+number, where \type {1200} and \type {1.2} both mean scaling to 20\percent\ more
+than normal. But one can best not use this primitive directly.
A specific font can be defined using the \type {\definefont} command. In \LMTX\ a
-regular scaler can be followed by two scale factors. The nest example
+regular scaler can be followed by two scale factors. The next example
demonstrates this:
\startbuffer
@@ -311,11 +358,10 @@ only shows the two scales but also introduces the offset.
\getbuffer
-Here is another one:
+In compact mode this is one font. Here is another example:
\startbuffer
-\definetweakedfont[squeezed] [xscale=0.9]
-\definetweakedfont[squeezed] [xscale=0.9]
+\definetweakedfont[squeezed][xscale=0.9]
\startlines
$a = b^2 + \sqrt{c}$
@@ -330,13 +376,13 @@ $a = b^2 + \sqrt{c}$
Watch this:
\startbuffer
-\startcombination[4*1]
+\startcombination[3*1]
{\bTABLE
\bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
\bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
\eTABLE}
{local}
- {\bTABLE[style=squeezed]
+ {\bTABLE[style=\squeezed]
\bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
\bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
\eTABLE}
@@ -404,20 +450,28 @@ gives:
\stoplinecorrection
Glyphs can have offsets and these are used for implementing \OPENTYPE\ features.
-However, they are also available at the \TEX\ end. Take this
+However, they are also available at the \TEX\ end. Take this example where we use
+the new \type {\glyph} primitive (a variant of \type {\char} that takes
+keywords):
\startbuffer
\ruledhbox{
- \ruledhbox{\glyph yoffset 1ex options 0 123}
+ \ruledhbox{\glyph yoffset 1ex options 0 123} % left curly brace
\ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 123}
- \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800 \glyphyscale\glyphxscale oeps}oeps}
+ \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800
+ \glyphyscale\glyphxscale oeps}oeps}
}
\stopbuffer
-This example demonstrates that the \type {\glyph} primitive takes keywords: \type
-{xoffset}, \type {yoffset}, \type {xscale}, \type {yscale}, \type {options},
-\type {font} and \type {id} where the last two take a font identifier or font id
-(an positive number).
+\typebuffer \getbuffer
+
+This example demonstrates that the \type {\glyph} primitive takes quite some
+keywords: \type {xoffset}, \type {yoffset}, \type {xscale}, \type {yscale}, \type
+{left}, \type {right}, \type {raise}, \type {options}, \type {font} and \type {id}
+where the last two take a font identifier or font id (an positive number). For
+this article it's enough to know that the option indicates that glyph dimension
+should include the offset. In a moment we will see an alternative that doesn't
+need that.
\startbuffer
\samplefile{jojomayer}
@@ -441,7 +495,7 @@ To quote Jojo Mayer:
\stopnarrower
Keep in mind that this can interfere badly with font feature processing which also
-used offsets. It might work out okay, or not.
+used offsets. It might often work out okay vertically, but less well horizontally.
The scales, as mentioned, works with pseudo scales but that is sometimes a bit
cumbersome. This is why a special \type {\numericscale} primitive has been
@@ -477,8 +531,8 @@ the slanted version could use some more left shifting of the E.
\typebuffer[definition,example]
-This gives is the \TEX\ logos (but of course we normally use the real ones
-instead).
+This gives the \TEX\ logos but of course we normally use the more official
+definitions instead.
\startnarrower
\darkred \getbuffer[definition,example]
@@ -490,7 +544,7 @@ suboptimal. Here is a better alternative:
\startbuffer[definition]
\def\UnKernedTeX
- {T\glyph left .2ex raise -.4ex `E\glyph left .4ex `X\relax}
+ {T\glyph left .2ex raise -.4ex `E\glyph left .2ex `X\relax}
\stopbuffer
\typebuffer[definition]
@@ -501,7 +555,7 @@ The result is the same:
\darkgreen \getbuffer[definition,example]
\stopnarrower
-But anyway: don't over|-|do it. We could deal with such cases for decades without
+But anyway: don't over|-|do it. We have dealt with such cases for decades without
these fancy new features. The next example show margins in action:
\startlinecorrection
@@ -565,23 +619,25 @@ dimensions of a glyph.
Discussing the implementation in the engine makes no sense here, also because
details might change. However, it is good to know that quite some properties
-travel with the glyph nodes, for instance the scales and offsets. The dimensions
-(width, height and depth) are not stored in the glyph node but calculated from
-the font, scales and optionally the offsets and expansion factor. One problem is
-that the more clever (and nice) solutions we cook up, the more it might impact
-performance. So, I will delay some experiments till I have a more powerful
-machine.
+travel with the glyph nodes, for instance the scales, margins, offsets, language,
+script and state properties, control over kerning, ligaturing, expansion and
+protrusion, etc. The dimensions (width, height and depth) are not stored in the
+glyph node but calculated from the font, scales and optionally the offsets and
+expansion factor. One problem is that the more clever (and nice) solutions we
+cook up, the more it might impact performance. So, I will delay some experiments
+till I have a more powerful machine.
One reason for {\em not} storing the dimensions in a glyph node is that we often
copy those nodes or change character fields in the font handler and we definitely
don't want the wrong dimensions there. At that moment, offsets and margin fields
-don't reflect features yet, so copying them is no big deal. However, dimensions
-are rather character bound so every time a character is set, we also would have
-to set the dimensions. Even worse, when we can set them, the question arises if
-they actually were already set explicitly. So, this is a can of worms we're not
-going to open: the basic width, height and depth of the glyph as specified in the
-font is used and combines with actual dimensions (likely already scaled according
-the glyph scales) in offset and margin fields.
+don't reflect features yet, so copying them is no big deal because at that moment
+these are still zero. However, dimensions are rather character bound so every
+time a character is set, we also would have to set the dimensions. Even worse,
+when we can set them, the question arises if they actually were already set
+explicitly. So, this is a can of worms we're not going to open: the basic width,
+height and depth of the glyph as specified in the font is used and combined with
+actual dimensions (likely already scaled according the glyph scales) in offset
+and margin fields.
Now, I have to admit that especially playing with using margins to glyphs instead
of font kerns is more of an experiment to see what the consequences are than a
diff --git a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
index 747945f55..bf4233165 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
@@ -615,6 +615,8 @@ primitives (for as far their functionality is still around) you now can do this:
\protected\def\pdfmapline {\pdfextension mapline }
\protected\def\pdftrailer {\pdfextension trailer }
\protected\def\pdfglyphtounicode {\pdfextension glyphtounicode }
+\protected\def\pdfrunninglinkoff {\pdfextension linkstate 1 }
+\protected\def\pdfrunninglinkon {\pdfextension linkstate 0 }
\stoptyping
The introspective primitives can be defined as:
diff --git a/metapost/context/base/mpxl/mp-lmtx.mpxl b/metapost/context/base/mpxl/mp-lmtx.mpxl
index 28fdb1417..88a0450d6 100644
--- a/metapost/context/base/mpxl/mp-lmtx.mpxl
+++ b/metapost/context/base/mpxl/mp-lmtx.mpxl
@@ -2219,10 +2219,7 @@ def lmt_registerglyphs = applyparameters "mpsglyphs" "lmt_do_registerglyphs" end
def lmt_registerglyph = applyparameters "mpsglyph" "lmt_do_registerglyph" enddef ;
newscriptindex mfid_registerglyphs ; mfid_registerglyphs := scriptindex "registerglyphs" ; def lmt_do_registerglyphs = runscript mfid_registerglyphs enddef ;
-newscriptindex mfid_registerglyph ; mfid_registerglyph := scriptindex "registerglyph " ; def lmt_do_registerglyph = runscript mfid_registerglyph enddef ;
-
-% vardef lmt_do_registerglyphs = lua.mp.lmt_register_glyphs() ; enddef ;
-% vardef lmt_do_registerglyph = lua.mp.lmt_register_glyph () ; enddef ;
+newscriptindex mfid_registerglyph ; mfid_registerglyph := scriptindex "registerglyph" ; def lmt_do_registerglyph = runscript mfid_registerglyph enddef ;
% Again an experiment (todo: the faster method):
diff --git a/metapost/context/base/mpxl/mp-luas.mpxl b/metapost/context/base/mpxl/mp-luas.mpxl
index c13db4d59..9ea130d35 100644
--- a/metapost/context/base/mpxl/mp-luas.mpxl
+++ b/metapost/context/base/mpxl/mp-luas.mpxl
@@ -215,16 +215,19 @@ permanent inpath, pointof, leftof, rightof ;
extra_endfig := extra_endfig & " runscript mfid_path_reset ; " ;
+newscriptindex mfid_utfnum ; mfid_utfnum := scriptindex "utfnum" ;
newscriptindex mfid_utflen ; mfid_utflen := scriptindex "utflen" ;
newscriptindex mfid_utfsub ; mfid_utfsub := scriptindex "utfsub" ;
+% def utfnum = runscript mfid_utfnum enddef ;
% def utflen = runscript mfid_utflen enddef ;
% def utfsub = runscript mfid_utfsub enddef ;
+vardef utfnum(expr s) = runscript mfid_utfnum s enddef ; % str
vardef utflen(expr s) = runscript mfid_utflen s enddef ; % str
vardef utfsub(text t) = runscript mfid_utfsub t enddef ; % str, first, (optional) last
-permanent utflen, utfsub ;
+permanent utfnum, utflen, utfsub ;
newscriptindex mfid_getparameters ; mfid_getparameters := scriptindex "getparameters" ;
newscriptindex mfid_presetparameters ; mfid_presetparameters := scriptindex "presetparameters" ;
diff --git a/metapost/context/base/mpxl/mp-math.mpxl b/metapost/context/base/mpxl/mp-math.mpxl
index c2723b0f6..cfe9e55e6 100644
--- a/metapost/context/base/mpxl/mp-math.mpxl
+++ b/metapost/context/base/mpxl/mp-math.mpxl
@@ -79,27 +79,27 @@ newscriptindex mfid_m_yz ; mfid_m_yz := scriptindex "m_y0"
newscriptindex mfid_m_y ; mfid_m_y := scriptindex "m_y1" ; def m_y = runscript mfid_m_y enddef ; % y1
newscriptindex mfid_m_yn ; mfid_m_yn := scriptindex "m_yn" ; def m_yn = runscript mfid_m_yn enddef ;
-newscriptindex mfid_c_sin ; mfid_c_asin := scriptindex "c_sin" ; def c_sin = runscript mfid_c_sin enddef ;
-newscriptindex mfid_c_cos ; mfid_c_acos := scriptindex "c_cos" ; def c_cos = runscript mfid_c_cos enddef ;
-newscriptindex mfid_c_tan ; mfid_c_acos := scriptindex "c_tan" ; def c_tan = runscript mfid_c_tan enddef ;
-newscriptindex mfid_c_sinh ; mfid_c_acos := scriptindex "c_sinh" ; def c_sinh = runscript mfid_c_sinh enddef ;
-newscriptindex mfid_c_cosh ; mfid_c_acos := scriptindex "c_cosh" ; def c_cosh = runscript mfid_c_cosh enddef ;
-newscriptindex mfid_c_tanh ; mfid_c_acos := scriptindex "c_tanh" ; def c_tanh = runscript mfid_c_tanh enddef ;
-
-newscriptindex mfid_c_asin ; mfid_c_acos := scriptindex "c_asin" ; def c_asin = runscript mfid_c_asin enddef ;
+newscriptindex mfid_c_sin ; mfid_c_sin := scriptindex "c_sin" ; def c_sin = runscript mfid_c_sin enddef ;
+newscriptindex mfid_c_cos ; mfid_c_cos := scriptindex "c_cos" ; def c_cos = runscript mfid_c_cos enddef ;
+newscriptindex mfid_c_tan ; mfid_c_tan := scriptindex "c_tan" ; def c_tan = runscript mfid_c_tan enddef ;
+newscriptindex mfid_c_sinh ; mfid_c_sinh := scriptindex "c_sinh" ; def c_sinh = runscript mfid_c_sinh enddef ;
+newscriptindex mfid_c_cosh ; mfid_c_cosh := scriptindex "c_cosh" ; def c_cosh = runscript mfid_c_cosh enddef ;
+newscriptindex mfid_c_tanh ; mfid_c_tanh := scriptindex "c_tanh" ; def c_tanh = runscript mfid_c_tanh enddef ;
+
+newscriptindex mfid_c_asin ; mfid_c_asin := scriptindex "c_asin" ; def c_asin = runscript mfid_c_asin enddef ;
newscriptindex mfid_c_acos ; mfid_c_acos := scriptindex "c_acos" ; def c_acos = runscript mfid_c_acos enddef ;
-newscriptindex mfid_c_atan ; mfid_c_acos := scriptindex "c_atan" ; def c_atan = runscript mfid_c_atan enddef ;
-newscriptindex mfid_c_asinh ; mfid_c_acos := scriptindex "c_asinh" ; def c_asinh = runscript mfid_c_asinh enddef ;
-newscriptindex mfid_c_acosh ; mfid_c_acos := scriptindex "c_acosh" ; def c_acosh = runscript mfid_c_acosh enddef ;
-newscriptindex mfid_c_atanh ; mfid_c_acos := scriptindex "c_atanh" ; def c_atanh = runscript mfid_c_atanh enddef ;
-
-newscriptindex mfid_c_sqrt ; mfid_c_acos := scriptindex "c_sqrt" ; def c_sqrt = runscript mfid_c_sqrt enddef ;
-newscriptindex mfid_c_abs ; mfid_c_acos := scriptindex "c_abs" ; def c_abs = runscript mfid_c_abs enddef ;
-newscriptindex mfid_c_arg ; mfid_c_acos := scriptindex "c_arg" ; def c_arg = runscript mfid_c_arg enddef ;
-newscriptindex mfid_c_conj ; mfid_c_acos := scriptindex "c_conj" ; def c_conj = runscript mfid_c_conj enddef ;
-newscriptindex mfid_c_exp ; mfid_c_acos := scriptindex "c_exp" ; def c_exp = runscript mfid_c_exp enddef ;
-newscriptindex mfid_c_log ; mfid_c_acos := scriptindex "c_log" ; def c_log = runscript mfid_c_log enddef ;
-newscriptindex mfid_c_proj ; mfid_c_acos := scriptindex "c_proj" ; def c_proj = runscript mfid_c_proj enddef ;
+newscriptindex mfid_c_atan ; mfid_c_atan := scriptindex "c_atan" ; def c_atan = runscript mfid_c_atan enddef ;
+newscriptindex mfid_c_asinh ; mfid_c_asinh := scriptindex "c_asinh" ; def c_asinh = runscript mfid_c_asinh enddef ;
+newscriptindex mfid_c_acosh ; mfid_c_acosh := scriptindex "c_acosh" ; def c_acosh = runscript mfid_c_acosh enddef ;
+newscriptindex mfid_c_atanh ; mfid_c_atanh := scriptindex "c_atanh" ; def c_atanh = runscript mfid_c_atanh enddef ;
+
+newscriptindex mfid_c_sqrt ; mfid_c_sqrt := scriptindex "c_sqrt" ; def c_sqrt = runscript mfid_c_sqrt enddef ;
+newscriptindex mfid_c_abs ; mfid_c_abs := scriptindex "c_abs" ; def c_abs = runscript mfid_c_abs enddef ;
+newscriptindex mfid_c_arg ; mfid_c_arg := scriptindex "c_arg" ; def c_arg = runscript mfid_c_arg enddef ;
+newscriptindex mfid_c_conj ; mfid_c_conj := scriptindex "c_conj" ; def c_conj = runscript mfid_c_conj enddef ;
+newscriptindex mfid_c_exp ; mfid_c_exp := scriptindex "c_exp" ; def c_exp = runscript mfid_c_exp enddef ;
+newscriptindex mfid_c_log ; mfid_c_log := scriptindex "c_log" ; def c_log = runscript mfid_c_log enddef ;
+newscriptindex mfid_c_proj ; mfid_c_proj := scriptindex "c_proj" ; def c_proj = runscript mfid_c_proj enddef ;
newscriptindex mfid_c_erf ; mfid_c_erf := scriptindex "c_erf" ; def c_erf = runscript mfid_c_erf enddef ;
newscriptindex mfid_c_erfc ; mfid_c_erfc := scriptindex "c_erfc" ; def c_erfc = runscript mfid_c_erfc enddef ;
diff --git a/metapost/context/fonts/mpiv/punkfont-characters.mp b/metapost/context/fonts/mpiv/punkfont-characters.mp
index da0015b02..5ba7a8a21 100644
--- a/metapost/context/fonts/mpiv/punkfont-characters.mp
+++ b/metapost/context/fonts/mpiv/punkfont-characters.mp
@@ -592,9 +592,19 @@ pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems
pd z5; draw z5--z6; % crossbar
endchar;
-beginpunkchar("i",5,1,2);
-z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h);
-pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem
+% beginpunkchar("i",5,1,2);
+% z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h);
+% pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem
+% endchar;
+
+% beginpunkchar("i",9,1,2);
+% z1=pp(.5w,0); z2=(.5w,.1h); z3=(.5w,2/3h); z4=(.5w,h);
+% pd z1; pd z4; draw flex(z1,z2,z3,z4) withcolor red; % stem
+% endchar;
+
+beginpunkchar("i",9,1,2);
+z1=pp(.5w,0); z4=(.5w,h);
+pd z1; pd z4; draw z1--z4; % stem
endchar;
beginpunkchar("j",9,1,2);
@@ -642,7 +652,8 @@ z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h);
pd z5; pd z6; draw z5--z7--z6; % tail
endchar;
-beginpunkchar("r",16,1,2);
+% beginpunkchar("r",16,1,2);
+beginpunkchar("r",13,1,2);
z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0);
pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal
endchar;
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index d06fbe463..6c1dca8a2 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.01.11 16:28}
+\newcontextversion{2021.01.17 21:39}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index c36274955..dbe4e4249 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.01.11 16:28}
+\edef\contextversion{2021.01.17 21:39}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 49c850c9b..d8dfa0fa2 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.01.11 16:28}
+\newcontextversion{2021.01.17 21:39}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 93744dfda..8e697e850 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.01.11 16:28}
+\edef\contextversion{2021.01.17 21:39}
%D Kind of special:
diff --git a/tex/context/base/mkiv/font-imp-math.lua b/tex/context/base/mkiv/font-imp-math.lua
index ed82fcc48..d2294e93c 100644
--- a/tex/context/base/mkiv/font-imp-math.lua
+++ b/tex/context/base/mkiv/font-imp-math.lua
@@ -80,6 +80,34 @@ registerotffeature {
}
}
+function fonts.helpers.mathscriptslots(tfmdata,textcode)
+ local rawdata = tfmdata.shared.rawdata
+ local rawresources = rawdata and rawdata.resources
+ local rawfeatures = rawresources and rawresources.features
+ local basesubstitutions = rawfeatures and rawfeatures.gsub
+ local sequences = basesubstitutions and tfmdata.resources.sequences
+ if sequences then
+ local characters = tfmdata.characters
+ if characters[textcode] then
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local sfeatures = sequence.features
+ if sfeatures and sfeatures.ssty then
+ local steps = sequence.steps
+ for i=1,#steps do
+ local coverage = steps[i].coverage
+ if coverage then
+ local okay = coverage[textcode]
+ if okay then
+ return okay
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
local function initialize(tfmdata,key,value)
if value then
local rawdata = tfmdata.shared.rawdata
diff --git a/tex/context/base/mkiv/font-imp-tracing.lua b/tex/context/base/mkiv/font-imp-tracing.lua
index 1acf14558..255b4cdf0 100644
--- a/tex/context/base/mkiv/font-imp-tracing.lua
+++ b/tex/context/base/mkiv/font-imp-tracing.lua
@@ -139,107 +139,3 @@ local specification = {
registerotffeature(specification)
registerafmfeature(specification)
-
-local f_m = formatters["%F %F m"]
-local f_l = formatters["%F %F l"]
-local f_b = formatters["[] 0 d 0 J %.6F w"]
-local f_e = formatters["s"]
-
-local function ladder(list,docolor,nocolor,lst,offset,sign,default)
- local l = lst[1]
- local x1 = bp * (offset + l.kern) * sign
- local y1 = bp * l.height
- local t = { f_b(r,r/2), f_m(x1,y1) }
- local n = 2
- local m = #lst
- if default > 0 then
- default = default * bp + r
- else
- default = default * bp - r
- end
- if m == 1 then
- n = n + 1 t[n] = f_l(x1,default)
- else
- for i=1,m do
- local l = lst[i]
- local x2 = bp * (offset + l.kern) * sign
- local y2 = bp * l.height
- if i > 1 and y2 == 0 then
- y2 = default
- end
- n = n + 1 t[n] = f_l(x2,y1)
- n = n + 1 t[n] = f_l(x2,y2)
- x1, y1 = x2, y2
- end
- end
- n = n + 1 t[n] = f_e()
- list[#list+1] = docolor
- list[#list+1] = { "pdf", "origin", concat(t," ") }
- list[#list+1] = nocolor
-end
-
-local function initialize(tfmdata,key,value)
- if value then
- if not backcolors then
- local vfspecials = backends.pdf.tables.vfspecials
- startcolor = vfspecials.startcolor
- stopcolor = vfspecials.stopcolor
- end
- local characters = tfmdata.characters
- local brcolor = startcolor("darkred")
- local trcolor = startcolor("darkgreen")
- local blcolor = startcolor("darkblue")
- local tlcolor = startcolor("darkyellow")
- local black = stopcolor
- for unicode, character in next, characters do
- local mathkern = character.mathkern
- if mathkern then
- -- more efficient would be co collect more in one pdf
- -- directive but this is hardly used so not worth the
- -- effort
- local width = character.width or 0
- local height = character.height or 0
- local depth = character.depth or 0
- local list = { }
- local br = mathkern.bottom_right
- local tr = mathkern.top_right
- local bl = mathkern.bottom_left
- local tl = mathkern.top_left
- if br then
- ladder(list,brcolor,black,br,width,1,height)
- end
- if tr then
- ladder(list,trcolor,black,tr,width,1,-depth)
- end
- if bl then
- ladder(list,blcolor,black,bl,0,-1,height)
- end
- if tl then
- ladder(list,tlcolor,black,tl,0,-1,-depth)
- end
- if #list > 0 then
- local commands = character.commands
- if commands then
- character.commands = appendcommandtable(commands,list)
- else
- list[#list+1] = charcommand[unicode]
- character.commands = list
- end
- end
- end
- end
- end
-end
-
-local specification = {
- name = "staircase",
- description = "show staircase kerns",
- position=1,
- manipulators = {
- base = initialize,
- node = initialize,
- }
-}
-
-registerotffeature(specification)
-registerafmfeature(specification)
diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv
index c32690375..445dedd25 100644
--- a/tex/context/base/mkiv/font-pre.mkiv
+++ b/tex/context/base/mkiv/font-pre.mkiv
@@ -405,6 +405,7 @@
mathalternates=yes,
mathitalics=yes, % we pass them
mathdimensions=all,
+ % mathkerns=yes,
% mathgaps=yes,
language=dflt,
script=math]
diff --git a/tex/context/base/mkiv/good-mth.lua b/tex/context/base/mkiv/good-mth.lua
index b85e680cc..3473cc205 100644
--- a/tex/context/base/mkiv/good-mth.lua
+++ b/tex/context/base/mkiv/good-mth.lua
@@ -6,8 +6,9 @@ if not modules then modules = { } end modules ['good-mth'] = {
license = "see context related readme files"
}
-local type, next = type, next
+local type, next, tonumber, unpack = type, next, tonumber, unpack
local ceil = math.ceil
+local match = string.match
local fonts = fonts
@@ -20,6 +21,10 @@ local fontgoodies = fonts.goodies or { }
local fontcharacters = fonts.hashes.characters
+local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
+
+local report_math = logs.reporter("mathematics","initializing")
+
local nuts = nodes.nuts
local setlink = nuts.setlink
@@ -33,11 +38,149 @@ local new_vlist = nodepool.vlist
local insert_node_after = nuts.insert_after
+local helpers = fonts.helpers
+local upcommand = helpers.commands.up
+local rightcommand = helpers.commands.right
+local charcommand = helpers.commands.char
+local prependcommands = helpers.prependcommands
+
-- experiment, we have to load the definitions immediately as they precede
-- the definition so they need to be initialized in the typescript
+local function withscriptcode(tfmdata,unicode,data,action)
+ if type(unicode) == "string" then
+ local p, u = match(unicode,"^(.-):(.-)$")
+ if u then
+ u = tonumber(u)
+ if u then
+ local slots = fonts.helpers.mathscriptslots(tfmdata,u)
+ if slots then
+ if p == "*" then
+ action(u,data)
+ for i=1,#slots do
+ action(slots[i],data)
+ end
+ else
+ p = tonumber(p)
+ if p then
+ action(slots[p],data)
+ end
+ end
+ end
+ end
+ end
+ else
+ action(unicode,data)
+ end
+end
+
local function finalize(tfmdata,feature,value)
- mathematics.overloaddimensions(tfmdata,tfmdata,value)
+-- if tfmdata.mathparameters then -- funny, cambria text has this
+ local goodies = tfmdata.goodies
+ if goodies then
+ local virtualized = mathematics.virtualized
+ for i=1,#goodies do
+ local goodie = goodies[i]
+ local mathematics = goodie.mathematics
+ local dimensions = mathematics and mathematics.dimensions
+ if dimensions then
+ if trace_defining then
+ report_math("overloading dimensions in %a @ %p",tfmdata.properties.fullname,tfmdata.parameters.size)
+ end
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local parameters = tfmdata.parameters
+ local factor = parameters.factor
+ local hfactor = parameters.hfactor
+ local vfactor = parameters.vfactor
+ local function overloadone(unicode,data)
+ local character = characters[unicode]
+ if not character then
+ local c = virtualized[unicode]
+ if c then
+ character = characters[c]
+ end
+ end
+ if character then
+ local width = data.width
+ local height = data.height
+ local depth = data.depth
+ if trace_defining and (width or height or depth) then
+ report_math("overloading dimensions of %C, width %p, height %p, depth %p",
+ unicode,width or 0,height or 0,depth or 0)
+ end
+ if width then character.width = width * hfactor end
+ if height then character.height = height * vfactor end
+ if depth then character.depth = depth * vfactor end
+ --
+ local xoffset = data.xoffset
+ local yoffset = data.yoffset
+ if xoffset == "llx" then
+ local d = descriptions[unicode]
+ if d then
+ xoffset = - d.boundingbox[1] * hfactor
+ character.width = character.width + xoffset
+ xoffset = rightcommand[xoffset]
+ else
+ xoffset = nil
+ end
+ elseif xoffset and xoffset ~= 0 then
+ xoffset = rightcommand[xoffset * hfactor]
+ else
+ xoffset = nil
+ end
+ if yoffset and yoffset ~= 0 then
+ yoffset = upcommand[yoffset * vfactor]
+ else
+ yoffset = nil
+ end
+ if xoffset or yoffset then
+ local commands = characters.commands
+ if commands then
+ prependcommands(commands,yoffset,xoffset)
+ else
+ local slot = charcommand[unicode]
+ if xoffset and yoffset then
+ character.commands = { xoffset, yoffset, slot }
+ elseif xoffset then
+ character.commands = { xoffset, slot }
+ else
+ character.commands = { yoffset, slot }
+ end
+ end
+ end
+ elseif trace_defining then
+ report_math("no overloading dimensions of %C, not in font",unicode)
+ end
+ end
+ local function overload(dimensions)
+ for unicode, data in next, dimensions do
+ withscriptcode(tfmdata,unicode,data,overloadone)
+ end
+ end
+ if value == nil then
+ value = { "default" }
+ end
+ if value == "all" or value == true then
+ for name, value in next, dimensions do
+ overload(value)
+ end
+ else
+ if type(value) == "string" then
+ value = utilities.parsers.settings_to_array(value)
+ end
+ if type(value) == "table" then
+ for i=1,#value do
+ local d = dimensions[value[i]]
+ if d then
+ overload(d)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
end
registerotffeature {
@@ -77,10 +220,11 @@ end
fontgoodies.register("mathematics", initialize)
-local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end)
+-- local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end)
local function initialize(tfmdata)
- if enabled and tfmdata.mathparameters then -- funny, cambria text has this
+-- if enabled and tfmdata.mathparameters then -- funny, cambria text has this
+ if tfmdata.mathparameters then -- funny, cambria text has this
local goodies = tfmdata.goodies
if goodies then
local characters = tfmdata.characters
@@ -91,12 +235,15 @@ local function initialize(tfmdata)
if mathgoodies then
local kerns = mathgoodies.kerns
if kerns then
- for unicode, specification in next, kerns do
+ local function kernone(unicode,data)
local chardata = characters[unicode]
- if chardata and (not chardata.mathkerns or specification.force) then
- chardata.mathkerns = specification
+ if chardata and (not chardata.mathkerns or data.force) then
+ chardata.mathkerns = data
end
end
+ for unicode, data in next, kerns do
+ withscriptcode(tfmdata,unicode,data,kernone)
+ end
return
end
end
@@ -109,9 +256,9 @@ local function initialize(tfmdata)
end
registerotffeature {
- name = "mathkerns",
- description = "math kerns",
- default = true,
+ name = "mathkerns",
+ description = "math kerns",
+ -- default = true,
initializers = {
base = initialize,
node = initialize,
diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua
index 4f38b4195..a5cfa82de 100644
--- a/tex/context/base/mkiv/math-act.lua
+++ b/tex/context/base/mkiv/math-act.lua
@@ -230,115 +230,6 @@ sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaft
local virtualized = mathematics.virtualized
-function mathematics.overloaddimensions(target,original,set)
- local goodies = target.goodies
- if goodies then
- for i=1,#goodies do
- local goodie = goodies[i]
- local mathematics = goodie.mathematics
- local dimensions = mathematics and mathematics.dimensions
- if dimensions then
- if trace_defining then
- report_math("overloading dimensions in %a @ %p",target.properties.fullname,target.parameters.size)
- end
- local characters = target.characters
- local descriptions = target.descriptions
- local parameters = target.parameters
- local factor = parameters.factor
- local hfactor = parameters.hfactor
- local vfactor = parameters.vfactor
-if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then
- target.type = "virtual"
- target.properties.virtualized = true
-end
- local function overload(dimensions)
- for unicode, data in next, dimensions do
- local character = characters[unicode]
- if not character then
- local c = virtualized[unicode]
- if c then
- character = characters[c]
- end
- end
- if character then
- --
- local width = data.width
- local height = data.height
- local depth = data.depth
- if trace_defining and (width or height or depth) then
- report_math("overloading dimensions of %C, width %p, height %p, depth %p",
- unicode,width or 0,height or 0,depth or 0)
- end
- if width then character.width = width * hfactor end
- if height then character.height = height * vfactor end
- if depth then character.depth = depth * vfactor end
- --
- local xoffset = data.xoffset
- local yoffset = data.yoffset
- if xoffset == "llx" then
- local d = descriptions[unicode]
- if d then
- xoffset = - d.boundingbox[1] * hfactor
- character.width = character.width + xoffset
- xoffset = rightcommand[xoffset]
- else
- xoffset = nil
- end
- elseif xoffset and xoffset ~= 0 then
- xoffset = rightcommand[xoffset * hfactor]
- else
- xoffset = nil
- end
- if yoffset and yoffset ~= 0 then
- yoffset = upcommand[yoffset * vfactor]
- else
- yoffset = nil
- end
- if xoffset or yoffset then
- local commands = characters.commands
- if commands then
- prependcommands(commands,yoffset,xoffset)
- else
- local slot = charcommand[unicode]
- if xoffset and yoffset then
- character.commands = { xoffset, yoffset, slot }
- elseif xoffset then
- character.commands = { xoffset, slot }
- else
- character.commands = { yoffset, slot }
- end
- end
- end
- elseif trace_defining then
- report_math("no overloading dimensions of %C, not in font",unicode)
- end
- end
- end
- if set == nil then
- set = { "default" }
- end
- if set == "all" or set == true then
- for name, set in next, dimensions do
- overload(set)
- end
- else
- if type(set) == "string" then
- set = utilities.parsers.settings_to_array(set)
- end
- if type(set) == "table" then
- for i=1,#set do
- local d = dimensions[set[i]]
- if d then
- overload(d)
- end
- end
- end
- end
- end
- end
- end
-end
-
-- no, it's a feature now (see good-mth):
--
-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
@@ -711,10 +602,10 @@ function mathematics.finishfallbacks(target,specification,fallbacks)
fonts = { }
target.fonts = fonts
end
-if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then
+ --
target.type = "virtual"
target.properties.virtualized = true
-end
+ --
if #fonts == 0 then
fonts[1] = { id = 0, size = size } -- self, will be resolved later
end
diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua
index 4d99e8320..4e4a901c0 100644
--- a/tex/context/base/mkiv/mult-fun.lua
+++ b/tex/context/base/mkiv/mult-fun.lua
@@ -187,7 +187,7 @@ return {
--
"inpath", "pointof", "leftof", "rightof",
--
- "utflen", "utfsub",
+ "utfnum", "utflen", "utfsub",
--
"newhash", "disposehash", "inhash", "tohash",
--
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index d55bfa411..605d8e1f1 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 78ade839c..3c5c26cb3 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-mar.lua b/tex/context/base/mkiv/strc-mar.lua
index b5fd2667b..f7953c416 100644
--- a/tex/context/base/mkiv/strc-mar.lua
+++ b/tex/context/base/mkiv/strc-mar.lua
@@ -122,7 +122,7 @@ end
local function sweep(head,first,last)
for n, id, subtype in nextnode, head do
-- we need to handle empty heads so we test for latelua
- if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then
+ if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then -- brrr
local a = getattr(n,a_marks)
if not a then
-- next
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index c06e32df3..3e78fb2f9 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -95,6 +95,7 @@ appendaction("shipouts", "finishers", "attributes.transparencies.handler",
appendaction("shipouts", "finishers", "attributes.colorintents.handler", nil, "nut", "disabled" )
appendaction("shipouts", "finishers", "attributes.negatives.handler", nil, "nut", "disabled" )
appendaction("shipouts", "finishers", "attributes.effects.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.alternates.handler", nil, "nut", "disabled" )
appendaction("shipouts", "finishers", "attributes.viewerlayers.handler", nil, "nut", "disabled" )
appendaction("shipouts", "wrapup", "nodes.handlers.export", nil, "nut", "disabled" ) -- always last
diff --git a/tex/context/base/mkxl/anch-pos.lmt b/tex/context/base/mkxl/anch-pos.lmt
index e804dbdf6..67d1657f2 100644
--- a/tex/context/base/mkxl/anch-pos.lmt
+++ b/tex/context/base/mkxl/anch-pos.lmt
@@ -1628,6 +1628,9 @@ end)
local newsavepos = nodes.pool.savepos
+jobpositions.lastx = 0
+jobpositions.lasty = 0
+
implement { name = "savepos", actions = function() context(newsavepos()) end }
-implement { name = "lastxpos", actions = function() context(gethpos()) end }
-implement { name = "lastypos", actions = function() context(getvpos()) end }
+implement { name = "lastxpos", actions = function() context(jobpositions.lastx) end }
+implement { name = "lastypos", actions = function() context(jobpositions.lasty) end }
diff --git a/tex/context/base/mkxl/attr-alt.lmt b/tex/context/base/mkxl/attr-alt.lmt
new file mode 100644
index 000000000..9d8592074
--- /dev/null
+++ b/tex/context/base/mkxl/attr-alt.lmt
@@ -0,0 +1,111 @@
+if not modules then modules = { } end modules ['attr-eff'] = {
+ version = 1.001,
+ comment = "companion to attr-eff.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local attributes, nodes, backends, utilities = attributes, nodes, backends, utilities
+local tex = tex
+
+local states = attributes.states
+local enableaction = nodes.tasks.enableaction
+local nodeinjections = backends.nodeinjections
+local texsetattribute = tex.setattribute
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
+local interfaces = interfaces
+local implement = interfaces.implement
+
+attributes.alternates = attributes.alternates or { }
+local alternates = attributes.alternates
+
+local a_alternate = attributes.private('alternate')
+
+alternates.data = allocate()
+alternates.values = alternates.values or { }
+alternates.registered = alternates.registered or { }
+alternates.attribute = a_alternate
+
+local data = alternates.data
+local registered = alternates.registered
+local values = alternates.values
+
+storage.register("attributes/alternates/registered", registered, "attributes.alternates.registered")
+storage.register("attributes/alternates/values", values, "attributes.alternates.values")
+
+local function extender(alternates,key)
+ if key == "none" then
+ local d = nodeinjections.stopalternate()
+ alternates.none = d
+ return d
+ end
+end
+
+local function reviver(data,n)
+ local d = values[n] and nodeinjections.startalternate(values[n]) or nodeinjections.stopalternate()
+ data[n] = d
+ return d
+end
+
+setmetatableindex(alternates, extender)
+setmetatableindex(alternates.data, reviver)
+
+alternates.handler = nodes.installattributehandler {
+ name = "alternate",
+ namespace = alternates,
+ initializer = states.initialize,
+ finalizer = states.finalize,
+ processor = states.simple,
+}
+
+local function register(specification)
+ local text = specification.text or "unknown"
+ local n = registered[text]
+ if not n then
+ n = #values + 1
+ values[n] = text
+ registered[text] = n
+ end
+ return n
+end
+
+local enabled = false
+
+local function enable()
+ if not enabled then
+ enableaction("shipouts","attributes.alternates.handler")
+ enabled = true
+ end
+end
+
+alternates.register = register
+alternates.enable = enable
+
+-- interface
+
+implement {
+ name = "setalternate",
+ actions = function(specification)
+ if not enabled then
+ enable()
+ end
+ texsetattribute(a_alternate,register(specification))
+ end,
+ arguments = {
+ {
+ { "text", "string" },
+ }
+ }
+}
+
+implement {
+ name = "resetalternate",
+ actions = function()
+ if enabled then
+ texsetattribute(a_alternate)
+ end
+ end
+}
diff --git a/tex/context/base/mkxl/attr-alt.mkxl b/tex/context/base/mkxl/attr-alt.mkxl
new file mode 100644
index 000000000..3881d929e
--- /dev/null
+++ b/tex/context/base/mkxl/attr-alt.mkxl
@@ -0,0 +1,55 @@
+%D \module
+%D [ file=attr-alt,
+%D version=2007.06.06,
+%D title=\CONTEXT\ Attribute Macros,
+%D subtitle=Alternates,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Attribute Macros / Alternates}
+
+\registerctxluafile{attr-alt}{autosuffix}
+
+%D The main reason for providing this is that we need to make sure we have no
+%D dangling end markers when we cross a page. Public viewers don't seem to support
+%D actual text at all and acrobat has some funny selection issues.
+%D
+%D \starttyping
+%D test
+%D \startalternate[text={A}]
+%D \dorecurse{10}{A }
+%D \startalternate[text={B}]
+%D \dorecurse{10}{B }
+%D \stopalternate
+%D \dorecurse{10}{A }
+%D \stopalternate
+%D test \par
+%D \stoptyping
+%D
+%D \starttyping
+%D test \startalternate[text={e=mc^2}]!$e=mc^2$\stopalternate\par
+%D test \alternate{e=mc^2}{copy:}\nbsp$e=mc^2$\par
+%D \stoptyping
+
+\unprotect
+
+\permanent\protected\def\startalternate[#1]% maybe better/also: [text={...}]
+ {\begingroup
+ \getdummyparameters[\c!text=,#1]%
+ \clf_setalternate text {\dummyparameter\c!text}\relax}
+
+\permanent\protected\def\stopalternate
+ {\endgroup}
+
+\permanent\protected\def\alternate#1%
+ {\groupedcommand{\clf_setalternate text {#1}\relax}{}}
+
+\permanent\protected\def\setalternate #1{\clf_setalternate text {#1}\relax}
+\permanent\protected\def\resetalternate {\clf_resetalternate}
+
+\protect \endinput
diff --git a/tex/context/base/mkxl/attr-eff.mkxl b/tex/context/base/mkxl/attr-eff.mkxl
index 04a0c55ce..42aadf9a2 100644
--- a/tex/context/base/mkxl/attr-eff.mkxl
+++ b/tex/context/base/mkxl/attr-eff.mkxl
@@ -30,8 +30,8 @@
\appendtoks
\edef\p_method{\effectparameter\c!method}%
\ifx\p_method\v!command
- \setuxvalue{\e!start\currenteffect}{\starteffect[#1]}%
- \setuxvalue{\e!stop \currenteffect}{\stopeffect}%
+ \frozen\protected\xdefcsname\e!start\currenteffect\endcsname{\starteffect[#1]}%
+ \frozen\protected\xdefcsname\e!stop \currenteffect\endcsname{\stopeffect}%
\fi
\to \everydefineeffect
diff --git a/tex/context/base/mkxl/attr-ini.mkxl b/tex/context/base/mkxl/attr-ini.mkxl
index de22cd6e2..8cef1ec56 100644
--- a/tex/context/base/mkxl/attr-ini.mkxl
+++ b/tex/context/base/mkxl/attr-ini.mkxl
@@ -130,6 +130,7 @@
\definesystemattribute [ruled] [public]
\definesystemattribute [shifted] [public]
\definesystemattribute [checkedbreak] [public]
+\definesystemattribute [alternate] [public]
\definesystemattribute [vboxtohboxseparator] [public]
\permanent\protected\let\showattributes\clf_showattributes % maybe at lua end
diff --git a/tex/context/base/mkxl/back-trf.mkxl b/tex/context/base/mkxl/back-ext.mkxl
index fcf69ade4..bba33335d 100644
--- a/tex/context/base/mkxl/back-trf.mkxl
+++ b/tex/context/base/mkxl/back-ext.mkxl
@@ -1,8 +1,8 @@
%D \module
-%D [ file=back-trf,
-%D version=2019.02.08, % 2009.04.15,
+%D [ file=back-ext,
+%D version=2019.02.08, % and later, merged file
%D title=\CONTEXT\ Backend Macros,
-%D subtitle=Transformations,
+%D subtitle=Output,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
@@ -11,9 +11,15 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% \registerctxluafile{back-ext}{autosuffix}
+
\unprotect
-\registerctxluafile{back-trf}{autosuffix}
+% \let\normalopenout \openout
+% \let\normalwrite \write
+% \let\normalcloseout\closeout
+% \let\normallatelua \latelua
+% \let\normalspecial \special
% rotation
diff --git a/tex/context/base/mkxl/back-ini.lmt b/tex/context/base/mkxl/back-ini.lmt
index ee40c384d..922705742 100644
--- a/tex/context/base/mkxl/back-ini.lmt
+++ b/tex/context/base/mkxl/back-ini.lmt
@@ -95,17 +95,6 @@ statistics.register("used backend", function()
end
end)
-local comment = { "comment", "" }
-
-tables.vfspecials = allocate {
- red = comment,
- green = comment,
- blue = comment,
- black = comment,
- startslant = comment,
- stopslant = comment,
-}
-
-- can best be here
interfaces.implement {
@@ -131,25 +120,6 @@ end)
backends.included = included
--- Also here:
-
-local paper_width = 0
-local paper_height = 0
-
-function codeinjections.setpagedimensions(paperwidth,paperheight)
- if paperwidth then
- paper_width = paperwidth
- end
- if paperheight then
- paper_height = paperheight
- end
- return paper_width, paper_height
-end
-
-function codeinjections.getpagedimensions()
- return paper_width, paper_height
-end
-
-- could also be codeinjections
function backends.getcallbackstate()
diff --git a/tex/context/base/mkxl/back-out.lmt b/tex/context/base/mkxl/back-out.lmt
deleted file mode 100644
index fbcb220dc..000000000
--- a/tex/context/base/mkxl/back-out.lmt
+++ /dev/null
@@ -1,255 +0,0 @@
-if not modules then modules = { } end modules ['back-out'] = {
- version = 1.001,
- comment = "companion to back-ini.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local type = type
-local loadstring = loadstring
-
-local context = context
-
--- tokens.scanners.....
-
-local get = token.get_index
-local scanners = tokens.scanners
-local scaninteger = scanners.integer
-local scanstring = scanners.string
-local scankeyword = scanners.keyword
-local scantokenlist = scanners.tokenlist
-
-local serialize = token.serialize
-
-local logwriter = logs.writer
-local openfile = io.open
-local flushio = io.flush
-
-local nuts = nodes.nuts
-local tonode = nuts.tonode
-local copynode = nuts.copy
-local nodepool = nuts.pool
-
-local getdata = nuts.getdata
-
-local whatsit_code = nodes.nodecodes.whatsit
-
-local whatsitcodes = nodes.whatsitcodes
-
-local literalvalues = nodes.literalvalues
-local originliteral_code = literalvalues.origin
-local pageliteral_code = literalvalues.page
-local directliteral_code = literalvalues.direct
-local rawliteral_code = literalvalues.raw
-
-local immediate_code = tex.flagcodes.immediate
-
-local nodeproperties = nodes.properties.data
-
-local channels = { }
-
-local register = nodepool.register
-local newnut = nuts.new
-
-local opennode = register(newnut(whatsit_code,whatsitcodes.open))
-local writenode = register(newnut(whatsit_code,whatsitcodes.write))
-local closenode = register(newnut(whatsit_code,whatsitcodes.close))
-local lateluanode = register(newnut(whatsit_code,whatsitcodes.latelua))
-local literalnode = register(newnut(whatsit_code,whatsitcodes.literal))
-local savenode = register(newnut(whatsit_code,whatsitcodes.save))
-local restorenode = register(newnut(whatsit_code,whatsitcodes.restore))
-local setmatrixnode = register(newnut(whatsit_code,whatsitcodes.setmatrix))
-
-local open_command, write_command, close_command
-
-backends = backends or { }
-
-local function immediately(prefix)
- return prefix and (prefix & immediate_code) ~= 0
-end
-
-local function openout(prefix)
- local channel = scaninteger()
- scankeyword("=") -- hack
- local filename = scanstring()
- if not immediately(prefix) then
- local n = copynode(opennode)
- nodeproperties[n] = { channel = channel, filename = filename } -- action = "open"
- return context(tonode(n))
- elseif not channels[channel] then
- local handle = openfile(filename,"wb") or false
- if handle then
- channels[channel] = handle
- else
- -- error
- end
- end
-end
-
-function backends.openout(n)
- local p = nodeproperties[n]
- if p then
- local handle = openfile(p.filename,"wb") or false
- if handle then
- channels[p.channel] = handle
- else
- -- error
- end
- end
-end
-
-local function write(prefix)
- local channel = scaninteger()
- if not immediately(prefix) then
- local t = scantokenlist()
- local n = copynode(writenode)
- nodeproperties[n] = { channel = channel, data = t } -- action = "write"
- return context(tonode(n))
- else
- local content = scanstring()
- local handle = channels[channel]
- if handle then
- handle:write(content,"\n")
- else
- logwriter(content,"\n")
- end
- end
-end
-
-function backends.writeout(n)
- local p = nodeproperties[n]
- if p then
- local handle = channels[p.channel]
- local content = serialize(p.data)
- if handle then
- handle:write(content,"\n")
- else
- logwriter(content,"\n")
- end
- end
-end
-
-local function closeout(prefix)
- local channel = scaninteger()
- if not immediately(prefix) then
- local n = copynode(closenode)
- nodeproperties[n] = { channel = channel } -- action = "close"
- return context(tonode(n))
- else
- local handle = channels[channel]
- if handle then
- handle:close()
- channels[channel] = false
- flushio()
- else
- -- error
- end
- end
-end
-
-function backends.closeout(n)
- local p = nodeproperties[n]
- if p then
- local channel = p.channel
- local handle = channels[channel]
- if handle then
- handle:close()
- channels[channel] = false
- flushio()
- else
- -- error
- end
- end
-end
-
-local noflatelua = 0
-
-local function latelua()
- local node = copynode(lateluanode)
- local name = "latelua"
- if scankeyword("name") then
- name = scanstring()
- end
- local data = scantokenlist()
- nodeproperties[node] = { name = name, data = data }
- return context(tonode(node))
-end
-
-function backends.latelua(current,pos_h,pos_v) -- todo: pass pos_h and pos_v (more efficient in lmtx)
- local p = nodeproperties[current]
- if p then
- data = p.data
- else
- data = getdata(current)
- end
- noflatelua = noflatelua + 1
- local kind = type(data)
- if kind == "table" then
- data.action(data.specification or data)
- elseif kind == "function" then
- data()
- else
- if kind ~= "string" then
- data = serialize(data)
- end
- if #data ~= "" then
- local code = loadstring(data)
- if code then
- code()
- end
- end
- end
-end
-
-function backends.getcallbackstate()
- return { count = noflatelua }
-end
-
-function nodepool.originliteral(str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = originliteral_code } return t end
-function nodepool.pageliteral (str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = pageliteral_code } return t end
-function nodepool.directliteral(str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = directliteral_code } return t end
-function nodepool.rawliteral (str) local t = copynode(literalnode) nodeproperties[t] = { data = str, mode = rawliteral_code } return t end
-
-local pdfliterals = {
- [originliteral_code] = originliteral_code, [literalvalues[originliteral_code]] = originliteral_code,
- [pageliteral_code] = pageliteral_code, [literalvalues[pageliteral_code]] = pageliteral_code,
- [directliteral_code] = directliteral_code, [literalvalues[directliteral_code]] = directliteral_code,
- [rawliteral_code] = rawliteral_code, [literalvalues[rawliteral_code]] = rawliteral_code,
-}
-
-function nodepool.literal(mode,str)
- local t = copynode(literalnode)
- if str then
- nodeproperties[t] = { data = str, mode = pdfliterals[mode] or pageliteral_code }
- else
- nodeproperties[t] = { data = mode, mode = pageliteral_code }
- end
- return t
-end
-
---- these 3 will move to node-res as they are generic
-
-function nodepool.save()
- return copynode(savenode)
-end
-
-function nodepool.restore()
- return copynode(restorenode)
-end
-
-function nodepool.setmatrix(rx,sx,sy,ry,tx,ty)
- local t = copynode(setmatrixnode)
- nodeproperties[t] = { matrix = { rx, sx, sy, ry, tx, ty } }
- return t
-end
-
-interfaces.implement { name = "openout", actions = openout, public = true, usage = "value" }
-interfaces.implement { name = "write", actions = write, public = true, usage = "value" }
-interfaces.implement { name = "closeout", actions = closeout, public = true, usage = "value" }
-interfaces.implement { name = "latelua", actions = latelua, public = true, protected = true }
-interfaces.implement { name = "special", actions = scanstring, public = true, protected = true }
-
-open_command = get(token.create("openout"))
-write_command = get(token.create("write"))
-close_command = get(token.create("closeout"))
diff --git a/tex/context/base/mkxl/back-out.mkxl b/tex/context/base/mkxl/back-out.mkxl
deleted file mode 100644
index 5cf79b2ea..000000000
--- a/tex/context/base/mkxl/back-out.mkxl
+++ /dev/null
@@ -1,22 +0,0 @@
-%D \module
-%D [ file=back-out,
-%D version=2019.02.08,
-%D title=\CONTEXT\ Backend Macros,
-%D subtitle=Output,
-%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.
-
-\registerctxluafile{back-out}{autosuffix}
-
-% \let\normalopenout \openout
-% \let\normalwrite \write
-% \let\normalcloseout\closeout
-% \let\normallatelua \latelua
-% \let\normalspecial \special
-
-\endinput
diff --git a/tex/context/base/mkxl/back-pdf.mkxl b/tex/context/base/mkxl/back-pdf.mkxl
index 66db06ef1..d59c29bc0 100644
--- a/tex/context/base/mkxl/back-pdf.mkxl
+++ b/tex/context/base/mkxl/back-pdf.mkxl
@@ -20,7 +20,6 @@
\registerctxluafile{lpdf-ini}{autosuffix,optimize}
\registerctxluafile{lpdf-lmt}{autosuffix,optimize}
\registerctxluafile{lpdf-col}{autosuffix}
-\registerctxluafile{lpdf-vfc}{autosuffix}
\registerctxluafile{lpdf-xmp}{autosuffix}
\registerctxluafile{lpdf-ano}{autosuffix}
\registerctxluafile{lpdf-res}{autosuffix}
diff --git a/tex/context/base/mkxl/back-trf.lmt b/tex/context/base/mkxl/back-trf.lmt
deleted file mode 100644
index e3ec0bda3..000000000
--- a/tex/context/base/mkxl/back-trf.lmt
+++ /dev/null
@@ -1,164 +0,0 @@
-if not modules then modules = { } end modules ['back-trf'] = {
- version = 1.001,
- comment = "companion to back-ini.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local sind, cosd, abs = math.sind, math.cosd, math.abs
-local insert, remove = table.insert, table.remove
-local unpack = unpack
-
-local context = context
-
-local formatters = string.formatters
-
-local scanners = tokens.scanners
-local scankeyword = scanners.keyword
-local scaninteger = scanners.integer
-local scannumber = scanners.number
-local scanstring = scanners.string
-
-local implement = interfaces.implement
-
-local nodepool = nodes.pool
-local savenode = nodepool.save
-local restorenode = nodepool.restore
-local setmatrixnode = nodepool.setmatrix
-local literalnode = nodepool.literal -- has to become some nodeinjection
-
-local stack = { }
-local restore = true -- false
-
-updaters.register("backend.update",function()
- savenode = nodepool.save -- not needed
- restorenode = nodepool.restore -- not needed
- setmatrixnode = nodepool.setmatrix -- not needed
- literalnode = nodepool.literal -- has to become some nodeinjection
-end)
-
-local function stopsomething()
- local top = remove(stack)
- if top == false then
- -- not wrapped
- elseif top == true then
- context(restorenode())
- elseif top then
- context(setmatrixnode(unpack(top))) -- not really needed anymore
- context(restorenode())
- else
- -- nesting error
- end
-end
-
-local function startrotation()
- local a = scannumber()
- if a == 0 then
- insert(stack,false)
- else
- local s, c = sind(a), cosd(a)
- if abs(s) < 0.000001 then
- s = 0 -- otherwise funny -0.00000
- end
- if abs(c) < 0.000001 then
- c = 0 -- otherwise funny -0.00000
- end
- context(savenode())
- context(setmatrixnode(c,s,-s,c))
- insert(stack,restore and { c, -s, s, c } or true)
- end
-end
-
-implement { name = "startrotation", actions = startrotation }
-implement { name = "stoprotation", actions = stopsomething }
-
-local function startscaling() -- at the tex end we use sx and sy instead of rx and ry
- local rx, ry = 1, 1
- while true do
- if scankeyword("rx") then
- rx = scannumber()
- elseif scankeyword("ry") then
- ry = scannumber()
- -- elseif scankeyword("revert") then
- -- local top = stack[#stack]
- -- if top then
- -- rx = top[1]
- -- ry = top[4]
- -- else
- -- rx = 1
- -- ry = 1
- -- end
- else
- break
- end
- end
- if rx == 1 and ry == 1 then
- insert(stack,false)
- else
- if rx == 0 then
- rx = 0.0001
- end
- if ry == 0 then
- ry = 0.0001
- end
- context(savenode())
- context(setmatrixnode(rx,0,0,ry))
- insert(stack,restore and { 1/rx, 0, 0, 1/ry } or true)
- end
-end
-
-implement { name = "startscaling", actions = startscaling }
-implement { name = "stopscaling", actions = stopsomething }
-
-local function startmatrix() -- rx sx sy ry -- tx, ty
- local rx, sx, sy, ry = 1, 0, 0, 1
- while true do
- if scankeyword("rx") then rx = scannumber()
- elseif scankeyword("ry") then ry = scannumber()
- elseif scankeyword("sx") then sx = scannumber()
- elseif scankeyword("sy") then sy = scannumber()
- else break end
- end
- if rx == 1 and sx == 0 and sy == 0 and ry == 1 then
- insert(stack,false)
- else
- context(savenode())
- context(setmatrixnode(rx,sx,sy,ry))
- insert(stack,store and { -rx, -sx, -sy, -ry } or true)
- end
-end
-
-implement { name = "startmatrix", actions = startmatrix }
-implement { name = "stopmatrix", actions = stopsomething }
-
-local function startmirroring()
- context(setmatrixnode(-1,0,0,1))
-end
-
-implement { name = "startmirroring", actions = startmirroring }
-implement { name = "stopmirroring", actions = startmirroring } -- not: stopsomething
-
--- this could also run on top of pack-rul ... todo
-
--- local function startclipping()
--- -- context(savenode())
--- context(literalnode("origin",formatters["q 0 w %s W n"](scanstring())))
--- end
---
--- local function stopclipping()
--- -- context(restorenode())
--- context(literalnode("Q"))
--- end
-
-local function startclipping()
- context(savenode())
- context(literalnode("origin",formatters["0 w %s W n"](scanstring())))
-end
-
-local function stopclipping()
- context(restorenode())
-end
-
-implement { name = "startclipping", actions = startclipping }
-implement { name = "stopclipping", actions = stopclipping }
diff --git a/tex/context/base/mkxl/colo-nod.lmt b/tex/context/base/mkxl/colo-nod.lmt
index d65f5978c..67487fee5 100644
--- a/tex/context/base/mkxl/colo-nod.lmt
+++ b/tex/context/base/mkxl/colo-nod.lmt
@@ -12,9 +12,9 @@ local setattrs = nuts.setattrs
local privateattributes = attributes.private
+local a_colormodel = privateattributes('colormodel')
local a_color = privateattributes('color')
local a_transparency = privateattributes('transparency')
-local a_colormodel = privateattributes('colormodel')
local colors = { }
nuts.colors = colors
@@ -26,9 +26,9 @@ function colors.set(n,ma,ca,ta) -- we could also do layers here
ma = 1
end
if ta then
- setattrs(n,a_colorspace,ma,a_color,ca,a_transparency,ta)
+ setattrs(n,a_colormodel,ma,a_color,ca,a_transparency,ta)
else
- setattrs(n,a_colorspace,ma,a_color,ca)
+ setattrs(n,a_colormodel,ma,a_color,ca)
end
end
elseif ta then
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 31dbd327a..8f1882ce5 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.01.11 16:28}
+\newcontextversion{2021.01.17 21:39}
%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 751712225..54b1bb730 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.01.11 16:28}
+\immutable\edef\contextversion{2021.01.17 21:39}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
@@ -159,7 +159,7 @@
\loadmkxlfile{node-ini}
-\loadmkxlfile{cldf-bas} % basics / depends on nodes
+% \loadmkxlfile{cldf-bas} % basics / depends on nodes
\loadmkxlfile{node-fin}
\loadmkxlfile{node-mig}
@@ -169,13 +169,15 @@
\loadmkxlfile{back-ini}
\loadmkxlfile{back-res}
-\loadmkxlfile{back-trf}
-\loadmkxlfile{back-out}
+\loadmkxlfile{back-ext}
+
+\loadmkxlfile{cldf-bas} % basics / depends on nodes
\loadmkxlfile{attr-col}
\loadmkxlfile{attr-lay}
\loadmkxlfile{attr-neg}
\loadmkxlfile{attr-eff}
+\loadmkxlfile{attr-alt}
\loadmkxlfile{attr-mkr}
\loadmkxlfile{trac-tex}
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index 9747ba82d..cfa61e30e 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -99,21 +99,7 @@ local gleaders_code = gluecodes.gleaders
local spaceskip_code = gluecodes.spaceskip
-local saveposwhatsit_code = whatsitcodes.savepos
-local userdefinedwhatsit_code = whatsitcodes.userdefined
-local openwhatsit_code = whatsitcodes.open
-local writewhatsit_code = whatsitcodes.write
-local closewhatsit_code = whatsitcodes.close
-local lateluawhatsit_code = whatsitcodes.latelua
-local literalwhatsit_code = whatsitcodes.literal
-local setmatrixwhatsit_code = whatsitcodes.setmatrix
-local savewhatsit_code = whatsitcodes.save
-local restorewhatsit_code = whatsitcodes.restore
-
-local getpagedimensions getpagedimensions = function()
- getpagedimensions = backends.codeinjections.getpagedimensions
- return getpagedimensions()
-end
+local getpagedimensions = layouts.getpagedimensions
local drivers = drivers
local instances = drivers.instances
@@ -154,11 +140,6 @@ local flushcharacter
local flushfontchar
local flushrule
local flushliteral
-local flushsetmatrix
-local flushsave
-local flushrestore
-local flushspecial
------ flushimage
-- make local
@@ -169,307 +150,323 @@ function drivers.getvpos() return round(pos_v) end
-- characters
-local flush_character
-
-local stack = setmetatableindex("table")
-local level = 0
-local nesting = 0
-local main = 0
-
--- experiment (smaller page stream but might be fragile)
+local flush_character do
-local tospace = false directives.register("backends.spaces", function(v) tospace = v end)
+ local stack = setmetatableindex("table")
+ local level = 0
+ local nesting = 0
+ local main = 0
--- todo: cache streams
+ -- experiment (smaller page stream but might be fragile)
-local default = 16384 * number.dimenfactors.bp -- 65536 // 4
+ local tospace = false directives.register("backends.spaces", function(v) tospace = v end)
-local startcolor = function() end
-local stopcolor = function() end
+ -- todo: cache streams
-updaters.register("backend.update",function()
- startcolor = fonts.vfcommands.startcolor
- stopcolor = fonts.vfcommands.stopcolor
-end)
+ local default = 16384 * number.dimenfactors.bp -- 65536 // 4
-local function flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy)
+ local vfinjectors = fonts.helpers.vfinjectors
- if nesting > 100 then
- return
- elseif nesting == 0 then
- main = font
- end
+ local function flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy)
- nesting = nesting + 1
+ if nesting > 100 then
+ return
+ elseif nesting == 0 then
+ main = font
+ end
- local saved_h = pos_h
- local saved_v = pos_v
- local saved_r = pos_r
- pos_r = lefttoright_code
+ nesting = nesting + 1
- local data = fontdata[font]
- local fnt = font
- local fonts = data.fonts
- local siz = (data.parameters.factor or 1)/65536
+ local saved_h = pos_h
+ local saved_v = pos_v
+ local saved_r = pos_r
+ pos_r = lefttoright_code
--- siz = siz * data.parameters.size / 1000
+ local data = fontdata[font]
+ local fnt = font
+ local fonts = data.fonts
+ local siz = (data.parameters.factor or 1)/65536
- local function flushchar(font,char,fnt,chr,f,e)
- if fnt then
- local nest = char ~= chr or font ~= fnt
- if fnt == 0 then
- fnt = main
+ local function flushchar(font,char,fnt,chr,f,e)
+ if fnt then
+ local nest = char ~= chr or font ~= fnt
+ if fnt == 0 then
+ fnt = main
+ end
+ return flush_character(current,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e)
+ else
+ return 0
end
--- return flush_character(false,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e)
- return flush_character(current,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e)
- else
- return 0
end
- end
- -- we assume resolved fonts: id mandate but maybe also size
-
- for i=1,#vfcommands do
- local packet = vfcommands[i]
- local command = packet[1]
- if command == "char" then
- local chr = packet[2]
- local f = packet[3]
- local e = packet[4]
- pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
- elseif command == "slot" then
- local index = packet[2]
- local chr = packet[3]
- local f = packet[4]
- local e = packet[5]
- if index == 0 then
- pos_h = pos_h + flushchar(font,char,font,chr,f,e)
- else
- local okay = fonts and fonts[index]
- if okay then
- local fnt = okay.id
- if fnt then
- pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
- end
- else
- -- safeguard, we assume the font itself (often index 1)
- pos_h = pos_h + flushchar(font,char,font,chr,f,e)
- end
- end
- elseif command == "use" then
- local index = packet[2]
- if index then
- local fnt
+ -- we assume resolved fonts: id mandate but maybe also size
+
+ -- we could map left, right, up, down -> offset
+ -- we could map char, font, slot to -> slot
+
+ for i=1,#vfcommands do
+ local packet = vfcommands[i]
+ local command = packet[1]
+ if command == "char" then
+ local chr = packet[2]
+ local f = packet[3]
+ local e = packet[4]
+ pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
+ elseif command == "slot" then
+ local index = packet[2]
+ local chr = packet[3]
+ local f = packet[4]
+ local e = packet[5]
if index == 0 then
- fnt = font
+ pos_h = pos_h + flushchar(font,char,font,chr,f,e)
else
local okay = fonts and fonts[index]
if okay then
- fnt = okay.id
+ local fnt = okay.id
+ if fnt then
+ pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
+ end
+ else
+ -- safeguard, we assume the font itself (often index 1)
+ pos_h = pos_h + flushchar(font,char,font,chr,f,e)
end
end
- if fnt then
- -- not efficient but ok for now as experiment
- local d = characters[fnt]
- if d then
- for i=3,#packet do
- local chr = packet[i]
- local dat = d[chr]
- if dat then
- flushfontchar(fnt,chr,dat)
+ elseif command == "use" then
+ local index = packet[2]
+ if index then
+ local fnt
+ if index == 0 then
+ fnt = font
+ else
+ local okay = fonts and fonts[index]
+ if okay then
+ fnt = okay.id
+ end
+ end
+ if fnt then
+ -- not efficient but ok for now as experiment
+ local d = characters[fnt]
+ if d then
+ for i=3,#packet do
+ local chr = packet[i]
+ local dat = d[chr]
+ if dat then
+ flushfontchar(fnt,chr,dat)
+ end
end
end
end
end
- end
- elseif command == "right" then
- local h = packet[2] -- already scaled
- if factor ~= 0 and h ~= 0 then
- h = h + h * factor / 1000 -- expansion
- end
- h = h * sx
- pos_h = pos_h + h
- elseif command == "down" then
- local v = packet[2] -- already scaled
- v = v * sy
- pos_v = pos_v - v
- elseif command == "push" then
- level = level + 1
- local s = stack[level]
- s[1] = pos_h
- s[2] = pos_v
- elseif command == "pop" then
- if level > 0 then
- local s = stack[level]
- pos_h = s[1]
- pos_v = s[2]
- level = level - 1
- end
- elseif command == "rule" then
- local size_v = packet[2]
- local size_h = packet[3]
- if size_h > 0 and size_v > 0 then
- if factor ~= 0 then
- size_h = size_h + size_h * factor / 1000
+ elseif command == "right" then
+ local h = packet[2] -- already scaled
+ if h ~= 0 then
+ if factor ~= 0 then
+ h = h + h * factor / 1000 -- expansion
+ end
+ pos_h = pos_h + h * sx
end
- if size_h > 0 then
- size_h = size_h * sx
- size_v = size_v * sy
- flushsimplerule(pos_h,pos_v,pos_r,size_h,size_v)
- pos_h = pos_h + size_h
+ elseif command == "left" then
+ local h = packet[2] -- already scaled
+ if h ~= 0 then
+ if factor ~= 0 then
+ h = h + h * factor / 1000 -- expansion
+ end
+ pos_h = pos_h - h * sx
end
- end
- elseif command == "frame" then
- -- d:width d:height d:depth d:rulethickness b:outline b:advance b:baseline s:color
- local width = packet[2]
- if width > 0 then
- local height = packet[3] or 0
- local depth = packet[4] or 0
- local total = height + depth
- if total > 0 then
+ elseif command == "down" then
+ local v = packet[2] -- already scaled
+ if v and v ~= 0 then
+ pos_v = pos_v - v * sy
+ end
+ elseif command == "up" then
+ local v = packet[2] -- already scaled
+ if v and v ~= 0 then
+ pos_v = pos_v + v * sy
+ end
+ elseif command == "offset" then
+ local h = packet[2] or 0
+ local v = packet[3] or 0
+ if h ~= 0 then
if factor ~= 0 then
- width = width + width * factor / 1000
+ h = h + h * factor / 1000 -- expansion
end
- if width > 0 then
- local line = packet[5] or default
- local outline = not packet[6]
- local advance = not packet[7]
- local baseline = outline and packet[8]
- local color = packet[9]
- if color then
- startcolor(color)
- end
- width = width * sx
- height = height * sy
- depth = depth * sy
- flushspecialrule(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline)
- if color then
- stopcolor()
+ pos_h = pos_h + h * sx
+ end
+ if v and v ~= 0 then
+ pos_v = pos_v + v * sy
+ end
+ elseif command == "push" then
+ level = level + 1
+ local s = stack[level]
+ s[1] = pos_h
+ s[2] = pos_v
+ elseif command == "pop" then
+ if level > 0 then
+ local s = stack[level]
+ pos_h = s[1]
+ pos_v = s[2]
+ level = level - 1
+ end
+ elseif command == "rule" then
+ local size_v = packet[2]
+ local size_h = packet[3]
+ if size_h > 0 and size_v > 0 then
+ if factor ~= 0 then
+ size_h = size_h + size_h * factor / 1000
+ end
+ if size_h > 0 then
+ size_h = size_h * sx
+ size_v = size_v * sy
+ flushsimplerule(pos_h,pos_v,pos_r,size_h,size_v)
+ pos_h = pos_h + size_h
+ end
+ end
+ elseif command == "frame" then
+ -- d:width d:height d:depth d:rulethickness b:outline b:advance b:baseline s:color
+ local width = packet[2]
+ if width > 0 then
+ local height = packet[3] or 0
+ local depth = packet[4] or 0
+ local total = height + depth
+ if total > 0 then
+ if factor ~= 0 then
+ width = width + width * factor / 1000
end
- if advance then
- pos_h = pos_h + width
+ if width > 0 then
+ local line = packet[5] or default
+ local outline = not packet[6]
+ local advance = not packet[7]
+ local baseline = outline and packet[8]
+ local color = packet[9] -- no longer needed probably
+ if color then
+ vfinjectors.startcolor(pos_h,pos_v,color) -- takes packet or string
+ end
+ width = width * sx
+ height = height * sy
+ depth = depth * sy
+ flushspecialrule(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline)
+ if color then
+ vfinjectors.stopcolor()
+ end
+ if advance then
+ pos_h = pos_h + width
+ end
end
end
end
+ elseif command == "font" then
+ local index = packet[2]
+ local okay = fonts and fonts[index]
+ if okay then
+ fnt = okay.id or fnt -- or maybe just return
+ end
+ elseif command == "lua" then
+ local code = packet[2]
+ local kind = type(code)
+ if kind ~= "function" then
+ code = loadstring(code)
+ kind = type(code)
+ end
+ if kind == "function" then
+ code(font,char,pos_h,pos_v,sx,sy)
+ end
+ elseif command == "node" then -- obsolete
+ local h = packet[2]
+ hlist_out(h,getlist(h))
+ else
+ local injector = vfinjectors[command]
+ if injector then
+ injector(pos_h,pos_v,packet)
+ end
end
- elseif command == "font" then
- local index = packet[2]
- local okay = fonts and fonts[index]
- if okay then
- fnt = okay.id or fnt -- or maybe just return
- end
- elseif command == "lua" then
- local code = packet[2]
- local kind = type(code)
- if kind ~= "function" then
- code = loadstring(code)
- kind = type(code)
- end
- if kind == "function" then
- code(font,char,pos_h,pos_v,sx,sy)
- end
- elseif command == "node" then
- -- us this really useful?
- local h = packet[2]
- hlist_out(h,getlist(h))
- elseif command == "pdf" then
- -- this will disappear and become a plug
- flushliteral(false,pos_h,pos_v,packet[2],packet[3])
- -- elseif command == "image" then
- -- -- doesn't work because intercepted by engine so we use a different
- -- -- mechanism (for now)
- -- local image = packet[2]
- -- -- to do
- -- elseif command == "pdfmode" then
- -- -- doesn't happen
- -- elseif command == "special" then
- -- -- not supported
- -- elseif command == "nop" then
- -- -- nothing to do|
- -- elseif command == "scale" then
- -- -- not supported
+ -- image : not needed, maybe some day
+ -- pdfmode : not used
+ -- special : makes no sense
+ -- nop : the official ignore
+ -- scale : not supported
end
- end
- pos_h = saved_h
- pos_v = saved_v
- pos_r = saved_r
+ pos_h = saved_h
+ pos_v = saved_v
+ pos_r = saved_r
- nesting = nesting - 1
-end
+ nesting = nesting - 1
+ end
-local onetimemessage -- could be defined later (todo: make plug for this)
+ local onetimemessage -- could be defined later (todo: make plug for this)
-local getxyscales = nuts.getxyscales
+ local getxyscales = nuts.getxyscales
-flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r,f,e)
+ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r,f,e)
- if font ~= lastfont then
- lastfont = font
- fontcharacters = characters[font]
- updatefontstate(font)
- end
+ if font ~= lastfont then
+ lastfont = font
+ fontcharacters = characters[font]
+ updatefontstate(font)
+ end
- local data = fontcharacters[char]
- if not data then
- if char > 0 then
- if not onetimemessage then
- onetimemessage = fonts.loggers.onetimemessage
+ local data = fontcharacters[char]
+ if not data then
+ if char > 0 then
+ if not onetimemessage then
+ onetimemessage = fonts.loggers.onetimemessage
+ end
+ onetimemessage(font,char,"missing")
end
- onetimemessage(font,char,"missing")
- end
- return 0, 0, 0
- end
- if vfcommands then
- vfcommands = data.commands
- end
- local width, height, depth, naturalwidth, sx, sy
- if current then
- naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width
- sx, sy = getxyscales(current) -- maybe: getwhdfs
- if factor == 0 then
- width = naturalwidth
- else
- -- width = (1.0 + factor/1000000.0) * naturalwidth
- width = naturalwidth + naturalwidth * factor/1000000.0
- -- width = naturalwidth + naturalwidth * 0.000001 * factor
+ return 0, 0, 0
end
- else
- width = data.width or 0
- height = data.height or 0
- depth = data.depth or 0
- naturalwidth = width
- if not factor then
- factor = 0
+ if vfcommands then
+ vfcommands = data.commands
end
- sx = 1
- sy = 1
- end
- if pos_r == righttoleft_code then
- pos_h = pos_h - width -- here ?
- end
- if vfcommands then
- flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy) -- also f ?
- else
- -- kind of messy that we do orientation here and offsets elsewhere
- local orientation = data.orientation
- if orientation and (orientation == 1 or orientation == 3) then
- local x = data.xoffset
- local y = data.yoffset
- if x then
- pos_h = pos_h + x
+ local width, height, depth, naturalwidth, sx, sy
+ if current then
+ naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width
+ sx, sy = getxyscales(current) -- maybe: getwhdfs
+ if factor == 0 then
+ width = naturalwidth
+ else
+ -- width = (1.0 + factor/1000000.0) * naturalwidth
+ width = naturalwidth + naturalwidth * factor/1000000.0
+ -- width = naturalwidth + naturalwidth * 0.000001 * factor
end
- if y then
- pos_v = pos_v + y
+ else
+ width = data.width or 0
+ height = data.height or 0
+ depth = data.depth or 0
+ naturalwidth = width
+ if not factor then
+ factor = 0
end
- pushorientation(orientation,pos_h,pos_v)
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
- poporientation(orientation,pos_h,pos_v)
+ sx = 1
+ sy = 1
+ end
+ if pos_r == righttoleft_code then
+ pos_h = pos_h - width -- here ?
+ end
+ if vfcommands then
+ flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy) -- also f ?
else
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
+ -- kind of messy that we do orientation here and offsets elsewhere .. this might change
+ local orientation = data.orientation
+ if orientation and (orientation == 1 or orientation == 3) then
+ local x = data.xoffset
+ local y = data.yoffset
+ if x then
+ pos_h = pos_h + x
+ end
+ if y then
+ pos_v = pos_v + y
+ end
+ pushorientation(orientation,pos_h,pos_v)
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
+ poporientation(orientation,pos_h,pos_v)
+ else
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
+ end
end
+ return width, height, depth
end
- return width, height, depth
+
end
-- end of characters
@@ -536,6 +533,13 @@ local function flushcloseout(current)
end
end
+local function flushsavepos(current,pos_h,pos_v)
+ jobpositions.lastx = pos_h
+ jobpositions.lasty = pos_v
+end
+
+local flushwhatsit
+
local hlist_out, vlist_out do
local function applyanchor(orientation,x,y,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset)
@@ -905,26 +909,7 @@ local hlist_out, vlist_out do
goto synced
end
elseif id == whatsit_code then
- if subtype == literalwhatsit_code then
- flushliteral(current,pos_h,pos_v)
- elseif subtype == lateluawhatsit_code then
- flushlatelua(current,pos_h,pos_v)
- elseif subtype == setmatrixwhatsit_code then
- flushsetmatrix(current,pos_h,pos_v)
- elseif subtype == savewhatsit_code then
- flushsave(current,pos_h,pos_v)
- elseif subtype == restorewhatsit_code then
- flushrestore(current,pos_h,pos_v)
- elseif subtype == saveposwhatsit_code then
- last_position_x = pos_h
- last_position_y = pos_v
- elseif subtype == writewhatsit_code then
- flushwriteout(current)
- elseif subtype == closewhatsit_code then
- flushcloseout(current)
- elseif subtype == openwhatsit_code then
- flushopenout(current)
- end
+ flushwhatsit[subtype](current,pos_h,pos_v)
elseif id == disc_code then
local replace, tail = getreplace(current)
-- actually, we no longer have these select discs in the packaged list ... it's about
@@ -1164,26 +1149,7 @@ local hlist_out, vlist_out do
end
cur_v = cur_v + total
elseif id == whatsit_code then
- if subtype == literalwhatsit_code then
- flushliteral(current,pos_h,pos_v)
- elseif subtype == lateluawhatsit_code then
- flushlatelua(current,pos_h,pos_v)
- elseif subtype == setmatrixwhatsit_code then
- flushsetmatrix(current,pos_h,pos_v)
- elseif subtype == savewhatsit_code then
- flushsave(current,pos_h,pos_v)
- elseif subtype == restorewhatsit_code then
- flushrestore(current,pos_h,pos_v)
- elseif subtype == saveposwhatsit_code then
- last_position_x = pos_h
- last_position_y = pos_v
- elseif subtype == writewhatsit_code then
- flushwriteout(current)
- elseif subtype == closewhatsit_code then
- flushcloseout(current)
- elseif subtype == openwhatsit_code then
- flushopenout(current)
- end
+ flushwhatsit[subtype](current,pos_h,pos_v)
else
-- penalty
goto synced
@@ -1223,22 +1189,47 @@ function drivers.converters.lmtx(driver,box,smode,objnum,specification)
initialize = actions.initialize
finalize = actions.finalize
- updatefontstate = flushers.updatefontstate
-
- pushorientation = flushers.pushorientation
- poporientation = flushers.poporientation
+ -- we need to do this once ...
+
+ if not updatefontstate then
+
+ updatefontstate = flushers.updatefontstate
+
+ pushorientation = flushers.pushorientation
+ poporientation = flushers.poporientation
+
+ flushcharacter = flushers.character
+ flushfontchar = flushers.fontchar
+ flushrule = flushers.rule
+ flushsimplerule = flushers.simplerule
+ flushspecialrule = flushers.specialrule
+ flushliteral = flushers.literal
+
+ flushwhatsit = setmetatableindex ( {
+ [whatsitcodes.literal] = flushliteral,
+ [whatsitcodes.latelua] = flushlatelua,
+ [whatsitcodes.userdefined] = function() end, -- special purpose, handled in callbacks
+ [whatsitcodes.savepos] = flushsavepos, -- only used by generic packages
+ [whatsitcodes.save] = flushers.save,
+ [whatsitcodes.restore] = flushers.restore,
+ [whatsitcodes.setmatrix] = flushers.setmatrix,
+ [whatsitcodes.open] = flushopenout, -- generic
+ [whatsitcodes.close] = flushcloseout, -- generic
+ [whatsitcodes.write] = flushwriteout, -- generic
+ [whatsitcodes.startmatrix] = flushers.startmatrix,
+ [whatsitcodes.stopmatrix] = flushers.stopmatrix,
+ [whatsitcodes.startscaling] = flushers.startscaling,
+ [whatsitcodes.stopscaling] = flushers.stopscaling,
+ [whatsitcodes.startrotation] = flushers.startrotation,
+ [whatsitcodes.stoprotation] = flushers.stoprotation,
+ [whatsitcodes.startmirroring] = flushers.startmirroring,
+ [whatsitcodes.stopmirroring] = flushers.stopmirroring,
+ [whatsitcodes.startclipping] = flushers.startclipping,
+ [whatsitcodes.stopclipping] = flushers.stopclipping,
+ [whatsitcodes.setstate] = flushers.setstate,
+ }, function(t, k) report("weird whatsit %a",k) return function() end end)
- flushcharacter = flushers.character
- flushfontchar = flushers.fontchar
- flushrule = flushers.rule
- flushsimplerule = flushers.simplerule
- flushspecialrule = flushers.specialrule
- flushspecial = flushers.special
- flushliteral = flushers.literal
- flushsetmatrix = flushers.setmatrix
- flushsave = flushers.save
- flushrestore = flushers.restore
- -- flushimage = flushers.image
+ end
reset_dir_stack()
reset_state()
@@ -1279,12 +1270,6 @@ function drivers.converters.lmtx(driver,box,smode,objnum,specification)
local pagewidth, pageheight = getpagedimensions()
- -- local h_offset_par = texget("hoffset")
- -- local v_offset_par = texget("voffset")
-
- -- page_h_origin = trueinch
- -- page_v_origin = trueinch
-
pos_r = lefttoright_code
if pagewidth > 0 then
@@ -1307,17 +1292,14 @@ function drivers.converters.lmtx(driver,box,smode,objnum,specification)
page_size_v = total
end
- local refpoint_h = 0 -- + page_h_origin + h_offset_par
- local refpoint_v = page_size_v -- - page_v_origin - v_offset_par
+ local refpoint_h = 0
+ local refpoint_v = page_size_v
pos_h = refpoint_h
pos_v = refpoint_v - height
- -- synced
else
- -- page_h_origin = 0
- -- page_v_origin = 0
page_size_h = width
page_size_v = total
pos_r = getdirection(box)
diff --git a/tex/context/base/mkxl/font-chk.lmt b/tex/context/base/mkxl/font-chk.lmt
index 7141be2c7..8e73d1b3c 100644
--- a/tex/context/base/mkxl/font-chk.lmt
+++ b/tex/context/base/mkxl/font-chk.lmt
@@ -64,7 +64,6 @@ local implement = interfaces.implement
local glyph_code = nodes.nodecodes.glyph
-local new_special = nodes.pool.special -- todo: literal
local hpack_node = node.hpack
local nuts = nodes.nuts
diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt
index 88e17290a..60e3f0233 100644
--- a/tex/context/base/mkxl/font-con.lmt
+++ b/tex/context/base/mkxl/font-con.lmt
@@ -51,6 +51,8 @@ constructors.designsizes = designsizes
local loadedfonts = allocate()
constructors.loadedfonts = loadedfonts
+----- scalecommands = fonts.helpers.scalecommands
+
--[[ldx--
<p>We need to normalize the scale factor (in scaled points). This has to
do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
@@ -260,6 +262,8 @@ function constructors.scale(tfmdata,specification)
end
target.specification = specification
--
+ local scalecommands = fonts.helpers.scalecommands -- defined later
+ --
local scaledpoints = specification.size
local relativeid = specification.relativeid
--
@@ -774,37 +778,7 @@ function constructors.scale(tfmdata,specification)
end
local vc = character.commands
if vc then
- -- we assume non scaled commands here
- -- tricky .. we need to scale pseudo math glyphs too
- -- which is why we deal with rules too
- local ok = false
- for i=1,#vc do
- local key = vc[i][1]
- if key == "right" or key == "down" or key == "rule" then
- ok = true
- break
- end
- end
- if ok then
- local tt = { }
- for i=1,#vc do
- local ivc = vc[i]
- local key = ivc[1]
- if key == "right" then
- tt[i] = { key, ivc[2]*hdelta }
- elseif key == "down" then
- tt[i] = { key, ivc[2]*vdelta }
- elseif key == "rule" then
- tt[i] = { key, ivc[2]*vdelta, ivc[3]*hdelta }
- else -- not comment
- tt[i] = ivc -- shared since in cache and untouched
- end
- end
- chr.commands = tt
- else
- chr.commands = vc
- end
- -- chr.index = nil
+ chr.commands = scalecommands(vc,hdelta,vdelta)
end
targetcharacters[unicode] = chr
end
diff --git a/tex/context/base/mkxl/font-fbk.lmt b/tex/context/base/mkxl/font-fbk.lmt
index 651bca331..47d284c84 100644
--- a/tex/context/base/mkxl/font-fbk.lmt
+++ b/tex/context/base/mkxl/font-fbk.lmt
@@ -63,13 +63,12 @@ local function composecharacters(tfmdata)
local deltaxheight = scale * (Xdesc.boundingbox[4] - xdesc.boundingbox[4])
local extraxheight = fraction * deltaxheight -- maybe use compose value
local italicfactor = parameters.italicfactor or 0
- local vfspecials = backends.tables.vfspecials --brr
local red, green, blue, black
if trace_visualize then
- red = vfspecials.startcolor("red")
- green = vfspecials.startcolor("green")
- blue = vfspecials.startcolor("blue")
- black = vfspecials.stopcolor
+ red = { "startcolor", "red" }
+ green = { "startcolor", "green" }
+ blue = { "startcolor", "blue" }
+ black = { "stopcolor" }
end
local compose = fonts.goodies.getcompositions(tfmdata)
if compose and trace_visualize then
diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt
index 079c867e2..277190f24 100644
--- a/tex/context/base/mkxl/font-imp-math.lmt
+++ b/tex/context/base/mkxl/font-imp-math.lmt
@@ -70,6 +70,35 @@ registerotffeature {
-- A quick and dirty and low level implementation but okay for testing:
+function fonts.helpers.mathscriptslots(tfmdata,textcode)
+ local rawdata = tfmdata.shared.rawdata
+ local rawresources = rawdata and rawdata.resources
+ local rawfeatures = rawresources and rawresources.features
+ local basesubstitutions = rawfeatures and rawfeatures.gsub
+ local sequences = basesubstitutions and tfmdata.resources.sequences
+ if sequences then
+ local characters = tfmdata.characters
+ if characters[textcode] then
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local sfeatures = sequence.features
+ if sfeatures and sfeatures.ssty then
+ local steps = sequence.steps
+ for i=1,#steps do
+ local coverage = steps[i].coverage
+ if coverage then
+ local okay = coverage[textcode]
+ if okay then
+ return okay
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
local function manipulate(tfmdata,key,value)
if texconditionals["c_font_compact"] then
local rawdata = tfmdata.shared.rawdata
@@ -81,7 +110,7 @@ local function manipulate(tfmdata,key,value)
if sequences then
local characters = tfmdata.characters
for s=1,#sequences do
- local sequence = sequences[s]
+ local sequence = sequences[s]
local sfeatures = sequence.features
if sfeatures and sfeatures.ssty then
local steps = sequence.steps
diff --git a/tex/context/base/mkxl/font-imp-tracing.lmt b/tex/context/base/mkxl/font-imp-tracing.lmt
new file mode 100644
index 000000000..59603c9dd
--- /dev/null
+++ b/tex/context/base/mkxl/font-imp-tracing.lmt
@@ -0,0 +1,286 @@
+if not modules then modules = { } end modules ['font-imp-tracing'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv and hand-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local abs = math.abs
+
+local next, type = next, type
+local concat = table.concat
+local formatters = string.formatters
+
+local fonts = fonts
+
+local handlers = fonts.handlers
+local registerotffeature = handlers.otf.features.register
+local registerafmfeature = handlers.afm.features.register
+
+local settings_to_array = utilities.parsers.settings_to_array
+local setmetatableindex = table.setmetatableindex
+
+local helpers = fonts.helpers
+local appendcommandtable = helpers.appendcommandtable
+local prependcommands = helpers.prependcommands
+local charcommand = helpers.commands.char
+
+local variables = interfaces.variables
+
+local v_background = variables.background
+local v_frame = variables.frame
+local v_empty = variables.empty
+local v_none = variables.none
+
+local function initialize(tfmdata,key,value)
+ if value then
+ local vfspecials = fonts.helpers.vfspecials
+ local vfcommands = fonts.helpers.commands
+ local backgrounds = vfspecials.backgrounds
+ local outlines = vfspecials.outlines
+ local characters = tfmdata.characters
+ local rulecache = backgrounds
+ local showchar = true
+ local color = "palegray"
+ if type(value) == "string" then
+ value = settings_to_array(value)
+ for i=1,#value do
+ local v = value[i]
+ if v == v_frame then
+ rulecache = outlines
+ elseif v == v_background then
+ rulecache = backgrounds
+ elseif v == v_empty then
+ showchar = false
+ elseif v == v_none then
+ color = nil
+ else
+ color = v
+ end
+ end
+ end
+ local gray = color and { "startcolor", color } or nil
+ local black = gray and { "stopcolor" } or nil
+ for unicode, character in next, characters do
+ local width = character.width or 0
+ local height = character.height or 0
+ local depth = character.depth or 0
+ local rule = rulecache[height][depth][width]
+ if showchar then
+ local commands = character.commands
+ if commands then
+ if gray then
+ character.commands = prependcommands (
+ commands, gray, rule, black
+ )
+ else
+ character.commands = prependcommands (
+ commands, rule
+ )
+ end
+ else
+ local char = charcommand[unicode]
+ if gray then
+ character.commands = {
+ gray, rule, black, char
+ }
+ else
+ character.commands = {
+ rule, char
+ }
+ end
+ end
+ else
+ if gray then
+ character.commands = {
+ gray, rule, black
+ }
+ else
+ character.commands = {
+ rule
+ }
+ end
+ end
+ end
+ end
+end
+
+local specification = {
+ name = "boundingbox",
+ description = "show boundingbox",
+ manipulators = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local function initialize(tfmdata,key,value)
+ if value then
+ local rawdata = tfmdata.shared.rawdata
+ local rawresources = rawdata and rawdata.resources
+ local mathconstants = rawresources.mathconstants
+ if mathconstants then
+ local vfspecials = fonts.helpers.vfspecials
+ local vfcommands = fonts.helpers.commands
+ local backgrounds = vfspecials.backgrounds
+ local outlines = vfspecials.outlines
+ local characters = tfmdata.characters
+ local rulecache = backgrounds
+ local push = vfcommands.push
+ local pop = vfcommands.pop
+ local black = { "stopcolor" }
+ local itcolor = { "startcolor", "trace:0" } -- s / dd (transparent)
+ local brcolor = { "startcolor", "trace:1" } -- r / dr
+ local trcolor = { "startcolor", "trace:2" } -- g / dg
+ local blcolor = { "startcolor", "trace:3" } -- b / db
+ local tlcolor = { "startcolor", "trace:4" } -- y / dy
+ for unicode, character in next, characters do
+ local mathkern = character.mathkern
+ local italic = character.vert_italic or character.italic
+ if mathkern or (italic and italic ~= 0) then
+ local width = character.width or 0
+ local height = character.height or 0
+ local depth = character.depth or 0
+ local list = { }
+ local count = 0
+ if italic and italic ~= 0 then
+ count = count + 1 list[count] = itcolor
+ count = count + 1 list[count] = push
+ count = count + 1 list[count] = { "offset", width + (italic < 0 and -italic or 0), 0 }
+ count = count + 1 list[count] = rulecache[height][depth][abs(-italic)]
+ count = count + 1 list[count] = pop
+ count = count + 1 list[count] = black
+ end
+ if mathkern then
+ local br = mathkern.bottom_right
+ local tr = mathkern.top_right
+ local bl = mathkern.bottom_left
+ local tl = mathkern.top_left
+ if br then
+ local done = false
+ for i=1,#br do
+ local l = br[i]
+ local h = l.height or 0
+ local k = l.kern or 0
+ if k ~= 0 then
+ if h == 0 then
+ h = height + depth -- todo max
+ end
+ if not done then
+ count = count + 1 list[count] = brcolor
+ done = true
+ end
+ count = count + 1 list[count] = push
+ count = count + 1 list[count] = { "offset", width + (k < 0 and k or 0), - depth }
+ count = count + 1 list[count] = rulecache[h][0][abs(k)]
+ count = count + 1 list[count] = pop
+ end
+ end
+ if done then
+ count = count + 1 list[count] = black
+ end
+ end
+ if tr then
+ local done = false
+ for i=1,#tr do
+ local l = tr[i]
+ local h = l.height or 0
+ local k = l.kern or 0
+ if k ~= 0 then
+ if h == 0 then
+ h = height + depth -- todo max
+ end
+ if not done then
+ count = count + 1 list[count] = trcolor
+ done = true
+ end
+ count = count + 1 list[count] = push
+ count = count + 1 list[count] = { "offset", width + (k < 0 and k or 0), height - h }
+ count = count + 1 list[count] = rulecache[h][0][abs(k)]
+ count = count + 1 list[count] = pop
+ end
+ end
+ if done then
+ count = count + 1 list[count] = black
+ end
+ end
+ if bl then
+ local done = false
+ for i=1,#bl do
+ local l = bl[i]
+ local h = l.height or 0
+ local k = l.kern or 0
+ if k ~= 0 then
+ if h == 0 then
+ h = height + depth -- todo max
+ end
+ if not done then
+ count = count + 1 list[count] = blcolor
+ done = true
+ end
+ count = count + 1 list[count] = push
+ count = count + 1 list[count] = { "offset", (k < 0 and k or 0), -depth }
+ count = count + 1 list[count] = rulecache[h][0][abs(k)]
+ count = count + 1 list[count] = pop
+ end
+ end
+ if done then
+ count = count + 1 list[count] = black
+ end
+ end
+ if tl then
+ local done = false
+ for i=1,#tl do
+ local l = tl[i]
+ local h = l.height or 0
+ local k = l.kern or 0
+ if k ~= 0 then
+ if h == 0 then
+ h = height + depth -- todo max
+ end
+ if not done then
+ count = count + 1 list[count] = tlcolor
+ done = true
+ end
+ count = count + 1 list[count] = push
+ count = count + 1 list[count] = { "offset", (k < 0 and k or 0), height - h }
+ count = count + 1 list[count] = rulecache[h][0][abs(k)]
+ count = count + 1 list[count] = pop
+ end
+ end
+ if done then
+ count = count + 1 list[count] = black
+ end
+ end
+ end
+ if count > 0 then
+ local commands = character.commands
+ if commands then
+ character.commands = appendcommandtable(commands,list)
+ else
+ list[#list+1] = charcommand[unicode]
+ character.commands = list
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local specification = {
+ name = "staircase",
+ description = "show staircase kerns",
+-- position = 1,
+ manipulators = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx
index 00bddc2c3..e90973d75 100644
--- a/tex/context/base/mkxl/font-lib.mklx
+++ b/tex/context/base/mkxl/font-lib.mklx
@@ -17,7 +17,7 @@
\registerctxluafile{font-ini}{autosuffix}
\registerctxluafile{font-log}{}
-\registerctxluafile{font-con}{autosuffix}
+\registerctxluafile{font-con}{autosuffix} % kind of early
%registerctxluafile{font-cft}{}
\registerctxluafile{font-enc}{}
\registerctxluafile{font-fmp}{autosuffix}
@@ -88,7 +88,7 @@
\registerctxluafile{good-ini}{}
\registerctxluafile{good-gen}{}
\registerctxluafile{good-ctx}{}
-\registerctxluafile{good-mth}{}
+\registerctxluafile{good-mth}{autosuffix}
\registerctxluafile{font-def}{autosuffix}
\registerctxluafile{font-ctx}{autosuffix} % after def as it overloads
@@ -116,7 +116,7 @@
% not yet, lmtx feature
}
-\registerctxluafile{font-imp-tracing}{} % comes last!
+\registerctxluafile{font-imp-tracing}{autosuffix} % comes last!
\registerctxluafile{font-fbk}{autosuffix}
diff --git a/tex/context/base/mkxl/font-ogr.lmt b/tex/context/base/mkxl/font-ogr.lmt
index df6449ded..a3f8acb3c 100644
--- a/tex/context/base/mkxl/font-ogr.lmt
+++ b/tex/context/base/mkxl/font-ogr.lmt
@@ -242,6 +242,8 @@ do -- this will move to its own module
return false
end
+ -- list of tonumber keywords
+
local function initializemps(tfmdata,kind,value)
if value then
local specification = settings_to_hash_strict(value)
@@ -256,9 +258,20 @@ do -- this will move to its own module
local categories = settings_to_array(category)
local usedshapes = nil
local index = 0
- local spread = tonumber(specification.spread or 0)
+ local spread = tonumber(specification.spread or 0) -- hm
local hascolor = hascolorspec(specification)
- specification.spread = spread -- now a number
+
+ specification.spread = spread -- now a number, maybe also for slant, weight etc
+
+ local preroll = specification.preroll
+ if preroll then
+ metapost.simple(instance,"begingroup;",true,true)
+ metapost.setparameterset("mpsfont",specification)
+ metapost.simple("simplefun",preroll)
+ metapost.setparameterset("mpsfont")
+ metapost.simple(instance,"endgroup;",true,true)
+ end
+
for i=1,#categories do
local category = categories[i]
local mpsshapes = shapes[category]
@@ -291,25 +304,39 @@ do -- this will move to its own module
}
-- todo: deal with extensibles and more properties
for unicode, shape in sortedhash(mpsshapes.glyphs) do
- -- local oldc = characters[unicode]
- -- if oldc then
- index = index + 1 -- todo: somehow we end up with 2 as first entry after 0
- local wd = shape.width or defaultwidth
- local ht = shape.height or defaultheight
- local dp = shape.depth or defaultdepth
- local newc = {
- index = index, -- into usedshapes
- width = scale * (wd + spread),
- height = scale * ht,
- depth = scale * dp,
- unicode = unicode,
- }
- --
- characters [unicode] = newc
- descriptions[unicode] = newc
- --
- usedshapes[unicode] = shape.code or defaultcode
- -- end
+ index = index + 1 -- todo: somehow we end up with 2 as first entry after 0
+ local wd = shape.width or defaultwidth
+ local ht = shape.height or defaultheight
+ local dp = shape.depth or defaultdepth
+ local uc = shape.tounicode
+ if uc then
+ uc = round(uc) -- brrr can be 123.0
+ end
+ local newc = {
+ index = index, -- into usedshapes
+ width = scale * (wd + spread),
+ height = scale * ht,
+ depth = scale * dp,
+ unicode = uc or unicode,
+ }
+ --
+ characters [unicode] = newc
+ descriptions[unicode] = newc
+ usedshapes [unicode] = shape.code or defaultcode
+ --
+ -- This is a way to get/use randomized shapes (see punk example).
+ --
+ if uc and uc ~= unicode then
+ local c = characters[uc]
+ if c then
+ local v = c.variants
+ if v then
+ v[#v + 1] = unicode
+ else
+ c.variants = { unicode }
+ end
+ end
+ end
end
end
end
diff --git a/tex/context/base/mkxl/font-pre.mkxl b/tex/context/base/mkxl/font-pre.mkxl
index fafe20a60..884a6c913 100644
--- a/tex/context/base/mkxl/font-pre.mkxl
+++ b/tex/context/base/mkxl/font-pre.mkxl
@@ -405,7 +405,9 @@
mathalternates=yes,
mathitalics=yes, % we pass them
mathdimensions=all,
-compactmath=yes,
+ % mathkerns=yes,
+ % staircase=yes,
+ compactmath=yes,
% mathgaps=yes,
language=dflt,
script=math]
diff --git a/tex/context/base/mkxl/font-vfc.lmt b/tex/context/base/mkxl/font-vfc.lmt
index e39eca683..9330bdea0 100644
--- a/tex/context/base/mkxl/font-vfc.lmt
+++ b/tex/context/base/mkxl/font-vfc.lmt
@@ -71,13 +71,111 @@ function helpers.appendcommandtable(commands,t)
end
helpers.commands = utilities.storage.allocate {
- char = setmetatableindex(function(t,k) local v = { "slot", 0, k } t[k] = v return v end),
- right = setmetatableindex(function(t,k) local v = { "right", k } t[k] = v return v end),
- left = setmetatableindex(function(t,k) local v = { "right", -k } t[k] = v return v end), -- todo: left
- down = setmetatableindex(function(t,k) local v = { "down", k } t[k] = v return v end),
- up = setmetatableindex(function(t,k) local v = { "down", -k } t[k] = v return v end), -- todo: up
+ char = setmetatableindex(function(t,k) local v = { "slot", 0, k } t[k] = v return v end),
+ right = setmetatableindex(function(t,k) local v = { "right", k } t[k] = v return v end),
+ left = setmetatableindex(function(t,k) local v = { "left", k } t[k] = v return v end),
+ down = setmetatableindex(function(t,k) local v = { "down", k } t[k] = v return v end),
+ up = setmetatableindex(function(t,k) local v = { "up", k } t[k] = v return v end),
push = push,
pop = pop,
dummy = dummy,
}
+helpers.vfinjectors = {
+ -- backend specific: startcolor, stopcolor etc
+}
+
+-- maybe round()
+
+local defaultline = 16384
+
+helpers.vfspecials = {
+
+ backgrounds = setmetatableindex(function(t,h)
+ local v = setmetatableindex(function(t,d)
+ local v = setmetatableindex(function(t,w)
+ local v = { "frame", w, h, d, defaultline, true, true }
+ t[w] = v
+ return v
+ end)
+ t[d] = v
+ return v
+ end)
+ t[h] = v
+ return v
+ end),
+
+ outlines = setmetatableindex(function(t,h)
+ local v = setmetatableindex(function(t,d)
+ local v = setmetatableindex(function(t,w)
+ local v = { "frame", w, h, d, defaultline, false, true }
+ t[w] = v
+ return v
+ end)
+ t[d] = v
+ return v
+ end)
+ t[h] = v
+ return v
+ end),
+
+}
+
+-- In the past we only copied when we had something that got scaled but the problem
+-- is that we then run into issues when we extend a commands in the parent. This
+-- needs checking. When we go to glyph scaling, this can go away.
+--
+-- The alternative is to work with unscaled values and always do scaling at the
+-- TeX end. So, then we need accessors instead of tables and we also need to check
+-- all the context code: where do we access values?
+--
+-- On the other hand, in glyph scale mode we hardly do any scaling so we seldom
+-- call the next one.
+--
+-- What if we use named fields: then we can scale by field name.
+
+local scaled = {
+ right = true,
+ down = true,
+ left = true,
+ right = true,
+ offset = true,
+ rule = true,
+ char = false,
+ font = false,
+ slot = false,
+ use = false,
+ push = false,
+ pop = false,
+ lua = false,
+ -- obsolete
+ node = false,
+ -- additional ones are never scaled (color etc)
+}
+
+function helpers.scalecommands(list,hdelta,vdelta)
+ local n = #list
+ for i=1,n do
+ local key = list[i][1]
+ if scaled[list[i][1]] then
+ local result = { }
+ for i=1,n do
+ local cmd = list[i]
+ local key = ivc[1]
+ if key == "right" or key == "left" then
+ result[i] = { key, cmd[2]*hdelta }
+ elseif key == "down" or key == "up" then
+ result[i] = { key, cmd[2]*vdelta }
+ elseif key == "offset" or key == "rule" then
+ result[i] = { key, cmd[2]*hdelta, cmd[3]*vdelta }
+ -- elseif key == "frame" then
+ -- result[i] = cmd -- already scaled, for now
+ else
+ result[i] = cmd -- shared since in cache and untouched
+ end
+ end
+ return result
+ end
+ end
+ return list
+end
diff --git a/tex/context/base/mkxl/good-mth.lmt b/tex/context/base/mkxl/good-mth.lmt
new file mode 100644
index 000000000..87b6787df
--- /dev/null
+++ b/tex/context/base/mkxl/good-mth.lmt
@@ -0,0 +1,464 @@
+if not modules then modules = { } end modules ['good-mth'] = {
+ version = 1.000,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tonumber, unpack = type, next, tonumber, unpack
+local ceil = math.ceil
+local match = string.match
+
+local fonts = fonts
+
+local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+local report_goodies = logs.reporter("fonts","goodies")
+
+local registerotffeature = fonts.handlers.otf.features.register
+
+local fontgoodies = fonts.goodies or { }
+
+local fontcharacters = fonts.hashes.characters
+
+local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
+
+local report_math = logs.reporter("mathematics","initializing")
+
+local nuts = nodes.nuts
+
+local setlink = nuts.setlink
+
+local nodepool = nuts.pool
+
+local new_kern = nodepool.kern
+local new_glyph = nodepool.glyph
+local new_hlist = nodepool.hlist
+local new_vlist = nodepool.vlist
+
+local insert_node_after = nuts.insert_after
+
+local helpers = fonts.helpers
+local upcommand = helpers.commands.up
+local rightcommand = helpers.commands.right
+local charcommand = helpers.commands.char
+local prependcommands = helpers.prependcommands
+
+-- experiment, we have to load the definitions immediately as they precede
+-- the definition so they need to be initialized in the typescript
+
+local function withscriptcode(tfmdata,unicode,data,action)
+ if type(unicode) == "string" then
+ local p, u = match(unicode,"^(.-):(.-)$")
+ if u then
+ u = tonumber(u)
+ if u then
+ local slots = fonts.helpers.mathscriptslots(tfmdata,u)
+ if slots then
+ if p == "*" then
+ action(u,data)
+ for i=1,#slots do
+ action(slots[i],data)
+ end
+ else
+ p = tonumber(p)
+ if p then
+ action(slots[p],data)
+ end
+ end
+ end
+ end
+ end
+ else
+ action(unicode,data)
+ end
+end
+
+local function finalize(tfmdata,feature,value)
+-- if tfmdata.mathparameters then -- funny, cambria text has this
+ local goodies = tfmdata.goodies
+ if goodies then
+ local virtualized = mathematics.virtualized
+ for i=1,#goodies do
+ local goodie = goodies[i]
+ local mathematics = goodie.mathematics
+ local dimensions = mathematics and mathematics.dimensions
+ if dimensions then
+ if trace_defining then
+ report_math("overloading dimensions in %a @ %p",tfmdata.properties.fullname,tfmdata.parameters.size)
+ end
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local parameters = tfmdata.parameters
+ local factor = parameters.factor
+ local hfactor = parameters.hfactor
+ local vfactor = parameters.vfactor
+ --
+ tfmdata.type = "virtual"
+ tfmdata.properties.virtualized = true
+ --
+ local function overloadone(unicode,data)
+ local character = characters[unicode]
+ if not character then
+ local c = virtualized[unicode]
+ if c then
+ character = characters[c]
+ end
+ end
+ if character then
+ local width = data.width
+ local height = data.height
+ local depth = data.depth
+ if trace_defining and (width or height or depth) then
+ report_math("overloading dimensions of %C, width %p, height %p, depth %p",
+ unicode,width or 0,height or 0,depth or 0)
+ end
+ if width then character.width = width * hfactor end
+ if height then character.height = height * vfactor end
+ if depth then character.depth = depth * vfactor end
+ --
+ local xoffset = data.xoffset
+ local yoffset = data.yoffset
+ if xoffset == "llx" then
+ local d = descriptions[unicode]
+ if d then
+ xoffset = - d.boundingbox[1] * hfactor
+ character.width = character.width + xoffset
+ xoffset = rightcommand[xoffset]
+ else
+ xoffset = nil
+ end
+ elseif xoffset and xoffset ~= 0 then
+ xoffset = rightcommand[xoffset * hfactor]
+ else
+ xoffset = nil
+ end
+ if yoffset and yoffset ~= 0 then
+ yoffset = upcommand[yoffset * vfactor]
+ else
+ yoffset = nil
+ end
+ if xoffset or yoffset then
+ local commands = characters.commands
+ if commands then
+ prependcommands(commands,yoffset,xoffset)
+ else
+ local slot = charcommand[unicode]
+ if xoffset and yoffset then
+ character.commands = { xoffset, yoffset, slot }
+ elseif xoffset then
+ character.commands = { xoffset, slot }
+ else
+ character.commands = { yoffset, slot }
+ end
+ end
+ end
+ elseif trace_defining then
+ report_math("no overloading dimensions of %C, not in font",unicode)
+ end
+ end
+ local function overload(dimensions)
+ for unicode, data in next, dimensions do
+ withscriptcode(tfmdata,unicode,data,overloadone)
+ end
+ end
+ if value == nil then
+ value = { "default" }
+ end
+ if value == "all" or value == true then
+ for name, value in next, dimensions do
+ overload(value)
+ end
+ else
+ if type(value) == "string" then
+ value = utilities.parsers.settings_to_array(value)
+ end
+ if type(value) == "table" then
+ for i=1,#value do
+ local d = dimensions[value[i]]
+ if d then
+ overload(d)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathdimensions",
+ description = "manipulate math dimensions",
+ -- default = true,
+ manipulators = {
+ base = finalize,
+ node = finalize,
+ }
+}
+
+local function initialize(goodies)
+ local mathgoodies = goodies.mathematics
+ if mathgoodies then
+ local virtuals = mathgoodies.virtuals
+ local mapfiles = mathgoodies.mapfiles
+ local maplines = mathgoodies.maplines
+ if virtuals then
+ for name, specification in next, virtuals do
+ -- beware, they are all constructed ... we should be more selective
+ mathematics.makefont(name,specification,goodies)
+ end
+ end
+ if mapfiles then
+ for i=1,#mapfiles do
+ fonts.mappings.loadfile(mapfiles[i]) -- todo: backend function
+ end
+ end
+ if maplines then
+ for i=1,#maplines do
+ fonts.mappings.loadline(maplines[i]) -- todo: backend function
+ end
+ end
+ end
+end
+
+fontgoodies.register("mathematics", initialize)
+
+-- local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end)
+
+local function initialize(tfmdata)
+-- if enabled and tfmdata.mathparameters then -- funny, cambria text has this
+ if tfmdata.mathparameters then -- funny, cambria text has this
+ local goodies = tfmdata.goodies
+ if goodies then
+ local characters = tfmdata.characters
+ if characters[0x1D44E] then -- 119886
+ -- we have at least an italic a
+ for i=1,#goodies do
+ local mathgoodies = goodies[i].mathematics
+ if mathgoodies then
+ local kerns = mathgoodies.kerns
+ if kerns then
+ local function kernone(unicode,data)
+ local chardata = characters[unicode]
+ if chardata and (not chardata.mathkerns or data.force) then
+ chardata.mathkerns = data
+ end
+ end
+ for unicode, data in next, kerns do
+ withscriptcode(tfmdata,unicode,data,kernone)
+ end
+ return
+ end
+ end
+ end
+ else
+ return -- no proper math font anyway
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathkerns",
+ description = "math kerns",
+ -- default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- math italics (not really needed)
+--
+-- it would be nice to have a \noitalics\font option
+
+local function initialize(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ local shared = tfmdata.shared
+ for i=1,#goodies do
+ local mathgoodies = goodies[i].mathematics
+ if mathgoodies then
+ local mathitalics = mathgoodies.italics
+ if mathitalics then
+ local properties = tfmdata.properties
+ if properties.setitalics then
+ mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics
+ if mathitalics then
+ if trace_goodies then
+ report_goodies("loading mathitalics for font %a",properties.name)
+ end
+ local corrections = mathitalics.corrections
+ local defaultfactor = mathitalics.defaultfactor
+ -- properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change)
+ if corrections then
+ fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy)
+ -- better make a helper so that we have less code being defined
+ local properties = tfmdata.properties
+ local parameters = tfmdata.parameters
+ local characters = tfmdata.characters
+ properties.mathitalic_defaultfactor = defaultfactor
+ properties.mathitalic_defaultvalue = defaultfactor * parameters.quad
+ if trace_goodies then
+ report_goodies("assigning mathitalics for font %a",properties.name)
+ end
+ local quad = parameters.quad
+ local hfactor = parameters.hfactor
+ for k, v in next, corrections do
+ local c = characters[k]
+ if c then
+ if v > -1 and v < 1 then
+ c.italic = v * quad
+ else
+ c.italic = v * hfactor
+ end
+ else
+ report_goodies("invalid mathitalics entry %U for font %a",k,properties.name)
+ end
+ end
+ end)
+ end
+ return -- maybe not as these can accumulate
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathitalics",
+ description = "additional math italic corrections",
+ -- default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- fontgoodies.register("mathitalics", initialize)
+
+local function mathradicalaction(n,h,v,font,mchar,echar)
+ local characters = fontcharacters[font]
+ local mchardata = characters[mchar]
+ local echardata = characters[echar]
+ local ewidth = echardata.width
+ local mwidth = mchardata.width
+ local delta = h - ewidth
+ local glyph = new_glyph(font,echar)
+ local head = glyph
+ if delta > 0 then
+ local count = ceil(delta/mwidth)
+ local kern = (delta - count * mwidth) / count
+ for i=1,count do
+ local k = new_kern(kern)
+ local g = new_glyph(font,mchar)
+ setlink(k,head)
+ setlink(g,k)
+ head = g
+ end
+ end
+ local height = mchardata.height
+ local list = new_hlist(head)
+ local kern = new_kern(height-v)
+ list = setlink(kern,list)
+ local list = new_vlist(kern)
+ insert_node_after(n,n,list)
+end
+
+local function mathhruleaction(n,h,v,font,bchar,mchar,echar)
+ local characters = fontcharacters[font]
+ local bchardata = characters[bchar]
+ local mchardata = characters[mchar]
+ local echardata = characters[echar]
+ local bwidth = bchardata.width
+ local mwidth = mchardata.width
+ local ewidth = echardata.width
+ local delta = h - ewidth - bwidth
+ local glyph = new_glyph(font,echar)
+ local head = glyph
+ if delta > 0 then
+ local count = ceil(delta/mwidth)
+ local kern = (delta - count * mwidth) / (count+1)
+ for i=1,count do
+ local k = new_kern(kern)
+ local g = new_glyph(font,mchar)
+ setlink(k,head)
+ setlink(g,k)
+ head = g
+ end
+ local k = new_kern(kern)
+ setlink(k,head)
+ head = k
+ end
+ local g = new_glyph(font,bchar)
+ setlink(g,head)
+ head = g
+ local height = mchardata.height
+ local list = new_hlist(head)
+ local kern = new_kern(height-v)
+ list = setlink(kern,list)
+ local list = new_vlist(kern)
+ insert_node_after(n,n,list)
+end
+
+local function initialize(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ local resources = tfmdata.resources
+ local ruledata = { }
+ for i=1,#goodies do
+ local mathematics = goodies[i].mathematics
+ if mathematics then
+ local rules = mathematics.rules
+ if rules then
+ for tag, name in next, rules do
+ ruledata[tag] = name
+ end
+ end
+ end
+ end
+ if next(ruledata) then
+ local characters = tfmdata.characters
+ local unicodes = resources.unicodes
+ if characters and unicodes then
+ local mathruleactions = resources.mathruleactions
+ if not mathruleactions then
+ mathruleactions = { }
+ resources.mathruleactions = mathruleactions
+ end
+ --
+ local mchar = unicodes[ruledata["radical.extender"] or false]
+ local echar = unicodes[ruledata["radical.end"] or false]
+ if mchar and echar then
+ mathruleactions.radicalaction = function(n,h,v,font)
+ mathradicalaction(n,h,v,font,mchar,echar)
+ end
+ end
+ --
+ local bchar = unicodes[ruledata["hrule.begin"] or false]
+ local mchar = unicodes[ruledata["hrule.extender"] or false]
+ local echar = unicodes[ruledata["hrule.end"] or false]
+ if bchar and mchar and echar then
+ mathruleactions.hruleaction = function(n,h,v,font)
+ mathhruleaction(n,h,v,font,bchar,mchar,echar)
+ end
+ end
+ -- not that nice but we need to register it at the tex end
+ -- context.enablemathrules("\\fontclass")
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathrules",
+ description = "check math rules",
+ default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
diff --git a/tex/context/base/mkxl/layo-ini.lmt b/tex/context/base/mkxl/layo-ini.lmt
new file mode 100644
index 000000000..1570075d9
--- /dev/null
+++ b/tex/context/base/mkxl/layo-ini.lmt
@@ -0,0 +1,115 @@
+if not modules then modules = { } end modules ['layo-ini'] = {
+ version = 1.001,
+ comment = "companion to layo-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- We need to share information between the TeX and Lua end about the typographical
+-- model. This happens here. This code might move.
+
+local texgetcount = tex.getcount
+local conditionals = tex.conditionals
+
+layouts = {
+ status = { },
+}
+
+local status = layouts.status
+
+function status.leftorrightpageaction(left,right)
+ if left == nil then
+ left, right = false, true
+ end
+ if not conditionals.layoutisdoublesided then
+ return left, right
+ elseif conditionals.layoutissinglesided then
+ return left, right
+ elseif texgetcount("pagenoshift") % 2 == 0 then
+ if texgetcount("realpageno") % 2 == 0 then
+ return right, left
+ else
+ return left, right
+ end
+ else
+ if texgetcount("realpageno") % 2 == 0 then
+ return left, right
+ else
+ return right, left
+ end
+ end
+end
+
+function status.isleftpage(r)
+ if not conditionals.layoutisdoublesided then
+ return false
+ elseif conditionals.layoutissinglesided then
+ return false
+ elseif texgetcount("pagenoshift") % 2 == 0 then
+ return (r or texgetcount("realpageno")) % 2 == 0
+ else
+ return not (r or texgetcount("realpageno")) % 2 == 0
+ end
+end
+
+-- Instead of making these these driver specific we make them generic. We can even consider
+-- to make these registers at the tex end.
+
+local canvas = {
+ pagespec = "default", -- v_default
+ paperwidth = 0,
+ paperheight = 0,
+ topoffset = 0,
+ leftoffset = 0,
+ height = 0,
+ width = 0,
+ cropoffset = 0,
+ bleedoffset = 0,
+ trimoffset = 0,
+ artoffset = 0,
+ doublesided = false,
+ marked = false,
+ copies = false,
+}
+
+function layouts.setupcanvas(specification)
+ local paperheight = specification.paperheight or canvas.paperheight
+ local paperwidth = specification.paperwidth or canvas.paperwidth
+ local cropoffset = specification.cropoffset or 0
+ local trimoffset = cropoffset - (specification.trimoffset or 0)
+ local bleedoffset = trimoffset - (specification.bleedoffset or 0)
+ local artoffset = bleedoffset - (specification.artoffset or 0)
+ --
+ canvas.paperheight = paperheight
+ canvas.paperwidth = paperwidth
+ canvas.cropoffset = cropoffset
+ canvas.trimoffset = trimoffset
+ canvas.bleedoffset = bleedoffset
+ canvas.artoffset = artoffset
+ --
+ canvas.pagespec = specification.mode or pagespec
+ canvas.topoffset = specification.topoffset or 0
+ canvas.leftoffset = specification.leftoffset or 0
+ canvas.height = specification.height or paperheight
+ canvas.width = specification.width or paperwidth
+ canvas.marked = specification.print
+ --
+ local copies = specification.copies
+ if type(copies) == "number" and copies < 2 then
+ canvas.copies = false
+ end
+ --
+ local doublesided = specification.doublesided
+ if doublesided ~= nil then
+ canvas.doublesided = doublesided
+ end
+end
+
+function layouts.getpagedimensions()
+ return canvas.paperwidth, canvas.paperheight
+end
+
+function layouts.getcanvas()
+ return canvas
+end
diff --git a/tex/context/base/mkxl/layo-ini.mkxl b/tex/context/base/mkxl/layo-ini.mkxl
index 4979989cd..73b7e978e 100644
--- a/tex/context/base/mkxl/layo-ini.mkxl
+++ b/tex/context/base/mkxl/layo-ini.mkxl
@@ -25,6 +25,6 @@
\ifdefined\pagenoshift \else \newcount \pagenoshift \fi
\ifdefined\realpageno \else \newcount \realpageno \fi
-\registerctxluafile{layo-ini}{}
+\registerctxluafile{layo-ini}{autosuffix}
\protect \endinput
diff --git a/tex/context/base/mkxl/lpdf-col.lmt b/tex/context/base/mkxl/lpdf-col.lmt
index 778d250c6..a999cb2c7 100644
--- a/tex/context/base/mkxl/lpdf-col.lmt
+++ b/tex/context/base/mkxl/lpdf-col.lmt
@@ -6,8 +6,6 @@ if not modules then modules = { } end modules ['lpdf-col'] = {
license = "see context related readme files"
}
--- slants also page ?
-
local type, next, tostring, tonumber = type, next, tostring, tonumber
local char, byte, format, gsub, rep, gmatch = string.char, string.byte, string.format, string.gsub, string.rep, string.gmatch
local settings_to_array, settings_to_numbers = utilities.parsers.settings_to_array, utilities.parsers.settings_to_numbers
@@ -25,7 +23,7 @@ local registrations = backends.pdf.registrations
local nodepool = nodes.nuts.pool
local register = nodepool.register
-local pageliteral = nodepool.pageliteral
+local setstate = nodepool.setstate
local pdfconstant = lpdf.constant
local pdfdictionary = lpdf.dictionary
@@ -131,26 +129,26 @@ lpdf.registerpagefinalizer(addpagegroup,3,"pagegroup")
-- color injection
function nodeinjections.rgbcolor(r,g,b)
- return register(pageliteral(f_rgb(r,g,b,r,g,b)))
+ return register(setstate(f_rgb(r,g,b,r,g,b)))
end
function nodeinjections.cmykcolor(c,m,y,k)
- return register(pageliteral(f_cmyk(c,m,y,k,c,m,y,k)))
+ return register(setstate(f_cmyk(c,m,y,k,c,m,y,k)))
end
function nodeinjections.graycolor(s) -- caching 0/1 does not pay off
- return register(pageliteral(f_gray(s,s)))
+ return register(setstate(f_gray(s,s)))
end
function nodeinjections.spotcolor(n,f,d,p)
if type(p) == "string" then
p = gsub(p,","," ") -- brr misuse of spot
end
- return register(pageliteral(f_spot(n,n,p,p)))
+ return register(setstate(f_spot(n,n,p,p)))
end
function nodeinjections.transparency(n)
- return register(pageliteral(f_tr_gs(n)))
+ return register(setstate(f_tr_gs(n)))
end
-- a bit weird but let's keep it here for a while
@@ -169,7 +167,7 @@ function nodeinjections.effect(effect,stretch,rulethickness)
-- always, no zero test (removed)
rulethickness = bp * rulethickness
effect = effects[effect] or effects['normal']
- return register(pageliteral(f_effect(stretch,rulethickness,effect))) -- watch order
+ return register(setstate(f_effect(stretch,rulethickness,effect))) -- watch order
end
-- spot- and indexcolors
@@ -727,29 +725,20 @@ function lpdf.finishtransparencycode()
end
end
--- this will move to lpdf-spe.lua an dwe then can also add a metatable with
--- normal context colors
-
do
- local pdfcolor = lpdf.color
- local pdftransparency = lpdf.transparency
-
- local f_slant = formatters["q 1 0 %N 1 0 0 cm"]
+ local pdfprint, pdfcolor, pdftransparency
- local slants = setmetatableindex(function(t,k)
- local v = { "pdf", "origin", f_slant(a) }
- t[k] = v
- return k
+ updaters.register("backend.update.lpdf",function()
+ pdfprint = lpdf.print
+ pdfcolor = lpdf.color
+ pdftransparency = lpdf.transparency
end)
- local function startslant(a)
- return slants[a]
- end
-
local c_cache = setmetatableindex(function(t,m)
+ -- We inherit the outer transparency.
local v = setmetatableindex(function(t,c)
- local p = { "pdf", "page", "q " .. pdfcolor(m,c) }
+ local p = "q " .. pdfcolor(m,c)
t[c] = p
return p
end)
@@ -757,13 +746,11 @@ do
return v
end)
- -- we inherit the outer transparency
-
local t_cache = setmetatableindex(function(t,transparency)
local p = pdftransparency(transparency)
local v = setmetatableindex(function(t,colormodel)
local v = setmetatableindex(function(t,color)
- local v = { "pdf", "page", "q " .. pdfcolor(colormodel,color) .. " " .. p }
+ local v = "q " .. pdfcolor(colormodel,color) .. " " .. p
t[color] = v
return v
end)
@@ -774,120 +761,33 @@ do
return v
end)
- local function startcolor(k)
- local m, c = colortoattributes(k)
- local t = transparencytoattribute(k)
- if t and t ~= unsetvalue then
- return t_cache[t][m][c]
- else
- return c_cache[m][c]
- end
- end
-
- -- A problem is that we need to transfer back and this is kind of
- -- messy so we force text mode .. i'll do a better job on that but
- -- will experiment first (both engines). Virtual fonts will change
- -- anyway.
-
- local vfspecials = backends.pdf.tables.vfspecials or allocate { }
- backends.pdf.tables.vfspecials = vfspecials
-
- vfspecials.startcolor = startcolor
- -- vfspecials.stopcolor = { "pdf", "text", "Q" } -- fails
- vfspecials.stopcolor = { "pdf", "page", "Q" }
-
- vfspecials.startslant = startslant
- vfspecials.stopslant = { "pdf", "page", "Q" } -- fails
-
-end
-
--- new method:
-
-do
-
updaters.register("backend.update.lpdf",function()
- pdfprint = lpdf.print
- end)
-
- -- Is this still used? It's a font property now.
-
- local f_slant = formatters["q 1 0 %N 1 0 0 cm"]
-
- local slants = setmetatableindex(function(t,k)
- local v = f_slant(a)
- t[k] = v
- return k
- end)
- local function startslant(a)
- return pdfprint("origin", slants[a])
- end
+ local vfinjectors = fonts.helpers.vfinjectors
- local function stopslant()
- pdfprint("text", "Q")
- end
+ vfinjectors.pdf = function(pos_h,pos_v,packet)
+ pdfprint(packet[2],packet[3])
+ end
- -- We inherit the outer transparency.
-
- local pdfcolor = lpdf.color
- local pdftransparency = lpdf.transparency
-
- -- local c_cache = setmetatableindex(function(t,m)
- -- local v = setmetatableindex(function(t,c)
- -- local p = "q " .. pdfcolor(m,c)
- -- t[c] = p
- -- return p
- -- end)
- -- t[m] = v
- -- return v
- -- end)
- --
- -- local t_cache = setmetatableindex(function(t,transparency)
- -- local p = pdftransparency(transparency)
- -- local v = setmetatableindex(function(t,colormodel)
- -- local v = setmetatableindex(function(t,color)
- -- local v = "q " .. pdfcolor(colormodel,color) .. " " .. p
- -- t[color] = v
- -- return v
- -- end)
- -- t[colormodel] = v
- -- return v
- -- end)
- -- t[transparency] = v
- -- return v
- -- end)
-
- -- local function startcolor(color)
- -- local m, c = colortoattributes(color)
- -- local t = transparencytoattribute(color)
- -- if t then
- -- pdfprint("page", t_cache[t][m][c])
- -- else
- -- pdfprint("page", c_cache[m][c])
- -- end
- -- end
-
- local function startcolor(color)
- local m, c = colortoattributes(color)
- local t = transparencytoattribute(color)
- if t and t ~= unsetvalue then
- pdfprint("page", "q " .. pdfcolor(m,c) .. " " .. pdftransparency(t))
- else
- pdfprint("page", "q " .. pdfcolor(m,c))
+ vfinjectors.startcolor = function(pos_h,pos_v,packet)
+ local color = type(packet) == "table" and packet[2] or packet
+ if color then
+ local m, c = colortoattributes(color)
+ local t = transparencytoattribute(color)
+ if t and t ~= unsetvalue then
+ pdfprint("page", t_cache[t][m][c]) -- "q " .. pdfcolor(m,c) .. " " .. pdftransparency(t)
+ else
+ pdfprint("page", c_cache[m][c]) -- "q " .. pdfcolor(m,c))
+ end
+ else
+ pdfprint("page", "q")
+ end
end
- end
- local function stopcolor()
- pdfprint("text", "Q")
- end
+ vfinjectors.stopcolor = function()
+ pdfprint("text", "Q")
+ end
- updaters.register("backend.update.lpdf",function()
- fonts.vfcommands = {
- startslant = startslant,
- stopslant = stopslant,
- startcolor = startcolor,
- stopcolor = stopcolor,
- }
end)
end
diff --git a/tex/context/base/mkxl/lpdf-ini.lmt b/tex/context/base/mkxl/lpdf-ini.lmt
index 59e728dfb..ea9466d39 100644
--- a/tex/context/base/mkxl/lpdf-ini.lmt
+++ b/tex/context/base/mkxl/lpdf-ini.lmt
@@ -82,12 +82,11 @@ do
lpdf.getpos = drivers.getpos
end)
- local pdfgetmatrix, pdfhasmatrix, pdfprint, pdfgetpos
+ local pdfgetmatrix, pdfhasmatrix, pdfgetpos
updaters.register("backend.update.lpdf",function()
pdfgetmatrix = lpdf.getmatrix
pdfhasmatrix = lpdf.hasmatrix
- pdfprint = lpdf.print
pdfgetpos = lpdf.getpos
end)
@@ -541,21 +540,6 @@ end
local function add_x(t,k,v) rawset(t,k,tostring(v)) end
--- local mt_x = { __index = { __lpdftype__ = "stream" }, __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x }
--- local mt_d = { __index = { __lpdftype__ = "dictionary" }, __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d, __add = add_to_d }
--- local mt_a = { __index = { __lpdftype__ = "array" }, __lpdftype = "array", __tostring = tostring_a, __call = value_a, __add = add_to_a }
--- local mt_u = { __index = { __lpdftype__ = "unicode" }, __lpdftype = "unicode", __tostring = tostring_u, __call = value_u }
--- local mt_s = { __index = { __lpdftype__ = "string" }, __lpdftype = "string", __tostring = tostring_s, __call = value_s }
--- local mt_p = { __index = { __lpdftype__ = "docstring" }, __lpdftype = "docstring", __tostring = tostring_p, __call = value_p }
--- local mt_n = { __index = { __lpdftype__ = "number" }, __lpdftype = "number", __tostring = tostring_n, __call = value_n }
--- local mt_c = { __index = { __lpdftype__ = "constant" }, __lpdftype = "constant", __tostring = tostring_c, __call = value_c }
--- local mt_z = { __index = { __lpdftype__ = "null" }, __lpdftype = "null", __tostring = tostring_z, __call = value_z }
--- local mt_t = { __index = { __lpdftype__ = "true" }, __lpdftype = "true", __tostring = tostring_t, __call = value_t }
--- local mt_f = { __index = { __lpdftype__ = "false" }, __lpdftype = "false", __tostring = tostring_f, __call = value_f }
--- local mt_r = { __index = { __lpdftype__ = "reference" }, __lpdftype = "reference", __tostring = tostring_r, __call = value_r }
--- local mt_v = { __index = { __lpdftype__ = "verbose" }, __lpdftype = "verbose", __tostring = tostring_v, __call = value_v }
--- local mt_l = { __index = { __lpdftype__ = "literal" }, __lpdftype = "literal", __tostring = tostring_l, __call = value_l }
-
local mt_x = { __index = { __lpdftype__ = "stream" }, __tostring = tostring_x, __call = value_x, __newindex = add_x }
local mt_d = { __index = { __lpdftype__ = "dictionary" }, __tostring = tostring_d, __call = value_d, __add = add_to_d }
local mt_a = { __index = { __lpdftype__ = "array" }, __tostring = tostring_a, __call = value_a, __add = add_to_a }
@@ -1259,6 +1243,17 @@ do
end
}
+ local setstate = nodes.nuts.pool.setstate
+
+ function nodeinjections.startalternate(str)
+ return setstate(f_actual_text(tosixteen(str)))
+ end
+
+ function nodeinjections.stopalternate()
+ return setstate("EMC")
+ end
+
+
end
-- interface
diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt
index 44352994a..b57557aee 100644
--- a/tex/context/base/mkxl/lpdf-lmt.lmt
+++ b/tex/context/base/mkxl/lpdf-lmt.lmt
@@ -100,6 +100,10 @@ local report_objects = logs.reporter("backend","objects")
local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end)
local trace_details = false trackers.register("backend.details", function(v) trace_details = v end)
+-- we collect them:
+
+local flushers = { }
+
-- used variables
local pdf_h, pdf_v
@@ -185,7 +189,7 @@ local tjfactor = 100 / 65536
lpdf.usedcharacters = usedcharacters
-local function updatefontstate(font)
+function flushers.updatefontstate(font)
fontcharacters = characters[font]
fontdescriptions = descriptions[font]
fontparameters = parameters[font]
@@ -400,8 +404,7 @@ local function pdf_goto_fontmode()
end
-- characters
-
-local flushcharacter do
+do
local round = math.round
@@ -413,52 +416,23 @@ local flushcharacter do
local hshift = false
local vshift = false
- -- local naturalwidths = setmetatableindex(function(t,font)
- -- local d = descriptions[font]
- -- local c = characters[font]
- -- local f = parameters[font].hfactor
- -- local v = setmetatableindex(function(t,char)
- -- local w
- -- local e = d and d[char]
- -- if e then
- -- w = e.width
- -- if w then
- -- w = w * f
- -- end
- -- end
- -- if not w then
- -- e = c[char]
- -- if e then
- -- w = e.width or 0
- -- end
- -- end
- -- if not w then
- -- w = 0
- -- end
- -- t[char] = w
- -- return w
- -- end)
- -- t[font] = v
- -- return v
- -- end)
-
local naturalwidths = setmetatableindex(function(t,font)
local d = descriptions[font]
local c = characters[font]
- local f = parameters[font].hfactor
+ local f = parameters[font].hfactor or parameters[font].factor
local v = setmetatableindex(function(t,char)
local w
- local e = c[char]
+ local e = d and d[char]
if e then
- w = e.width or 0
+ w = e.width
+ if w then
+ w = w * f
+ end
end
if not w then
- e = d and d[char]
+ e = c[char]
if e then
- w = e.width
- if w then
- w = w * f
- end
+ w = e.width or 0
end
end
if not w then
@@ -592,7 +566,7 @@ local flushcharacter do
-- luatex (a precursor to lmtx and also for comparison) but only in lmtx now so ...
-- time to move on I guess.
- flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
+ flushers.character = function(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
if sx ~= f_x_scale or sy ~= f_y_scale or need_tf or font ~= f_cur or f_pdf ~= f_pdf_cur or fs ~= fs_cur or mode == "page" then
pdf_goto_textmode()
setup_fontparameters(font,factor,f,e,sx,sy)
@@ -665,7 +639,7 @@ local flushcharacter do
end
- flushfontchar = function(font,char,data)
+ flushers.fontchar = function(font,char,data)
local dummy = usedfonts[font]
local index = data.index or char
if not pdfcharacters[index] then
@@ -690,14 +664,12 @@ local flushliteral do
local textliteral_code = literalvalues.text
local fontliteral_code = literalvalues.font
- local getdata = nuts.getdata
-
- flushliteral = function(current,pos_h,pos_v,mode,str)
- if mode then
- if not str then
- mode, str = originliteral_code, mode
- elseif mode == "mode" then
- mode = literalvalues[str]
+ flushliteral = function(current,pos_h,pos_v)
+ local p = nodeproperties[current]
+ if p then
+ local str = p.data
+ if str and str ~= "" then
+ local mode = p.mode
if mode == originliteral_code then
pdf_goto_pagemode()
pdf_set_pos(pos_h,pos_v)
@@ -707,49 +679,22 @@ local flushliteral do
pdf_goto_textmode()
elseif mode == fontliteral_code then
pdf_goto_fontmode()
- elseif mode == alwaysliteral_code then
+ elseif mode == alwaysliteral_code then -- aka direct
pdf_end_string_nl()
need_tm = true
elseif mode == rawliteral_code then
pdf_end_string_nl()
+ else
+ report("invalid literal mode %a when flushing %a",mode,str)
+ return
end
- return
- else
- mode = literalvalues[mode]
- end
- else
- local p = nodeproperties[current]
- if p then
- str = p.data
- mode = p.mode
- else
- str, mode = getdata(current)
- end
- end
- if str and str ~= "" then
- if mode == originliteral_code then
- pdf_goto_pagemode()
- pdf_set_pos(pos_h,pos_v)
- elseif mode == pageliteral_code then
- pdf_goto_pagemode()
- elseif mode == textliteral_code then
- pdf_goto_textmode()
- elseif mode == fontliteral_code then
- pdf_goto_fontmode()
- elseif mode == alwaysliteral_code then
- pdf_end_string_nl()
- need_tm = true
- elseif mode == rawliteral_code then
- pdf_end_string_nl()
- else
- report("check literal")
- pdf_goto_pagemode()
- pdf_set_pos(pos_h,pos_v)
+ b = b + 1 ; buffer[b] = str
end
- b = b + 1 ; buffer[b] = str
end
end
+ flushers.literal = flushliteral
+
function lpdf.print(mode,str)
-- This only works inside objects, don't change this to flush
-- in between. It's different from luatex but okay.
@@ -774,8 +719,8 @@ local flushliteral do
elseif mode == rawliteral_code then
pdf_end_string_nl()
else
- pdf_goto_pagemode()
- -- pdf_set_pos(pdf_h,pdf_v)
+ report("invalid literal mode %a when flushing %a",mode,str)
+ return
end
b = b + 1 ; buffer[b] = str
end
@@ -785,14 +730,14 @@ end
-- grouping & orientation
-local flushsave, flushrestore, flushsetmatrix do
+do
local matrices = { }
local positions = { }
local nofpositions = 0
local nofmatrices = 0
- flushsave = function(current,pos_h,pos_v)
+ local flushsave = function(current,pos_h,pos_v)
nofpositions = nofpositions + 1
positions[nofpositions] = { pos_h, pos_v, nofmatrices }
pdf_goto_pagemode()
@@ -800,7 +745,7 @@ local flushsave, flushrestore, flushsetmatrix do
b = b + 1 ; buffer[b] = "q"
end
- flushrestore = function(current,pos_h,pos_v)
+ local flushrestore = function(current,pos_h,pos_v)
if nofpositions < 1 then
return
end
@@ -822,7 +767,7 @@ local flushsave, flushrestore, flushsetmatrix do
local f_matrix_2 = formatters["%.6N 0 0 %.6N 0 0 cm"]
local f_matrix_4 = formatters["%.6N %.6N %.6N %.6N 0 0 cm"]
- flushsetmatrix = function(current,pos_h,pos_v)
+ local flushsetmatrix = function(current,pos_h,pos_v)
local p = nodeproperties[current]
if p then
local m = p.matrix
@@ -879,6 +824,10 @@ local flushsave, flushrestore, flushsetmatrix do
end
end
+ flushers.setmatrix = flushsetmatrix
+ flushers.save = flushsave
+ flushers.restore = flushrestore
+
function lpdf.hasmatrix()
return nofmatrices > 0
end
@@ -891,7 +840,7 @@ local flushsave, flushrestore, flushsetmatrix do
end
end
- pushorientation = function(orientation,pos_h,pos_v,pos_r)
+ flushers.pushorientation = function(orientation,pos_h,pos_v,pos_r)
pdf_goto_pagemode()
pdf_set_pos(pos_h,pos_v)
b = b + 1 ; buffer[b] = "q"
@@ -904,12 +853,76 @@ local flushsave, flushrestore, flushsetmatrix do
end
end
- poporientation = function(orientation,pos_h,pos_v,pos_r)
+ flushers.poporientation = function(orientation,pos_h,pos_v,pos_r)
pdf_goto_pagemode()
pdf_set_pos(pos_h,pos_v)
b = b + 1 ; buffer[b] = "Q"
end
+ --
+
+ flushers.startmatrix = function(current,pos_h,pos_v)
+ flushsave(current,pos_h,pos_v)
+ flushsetmatrix(current,pos_h,pos_v)
+ end
+
+ flushers.stopmatrix = function(current,pos_h,pos_v)
+ flushrestore(current,pos_h,pos_v)
+ end
+
+ flushers.startscaling = function(current,pos_h,pos_v)
+ flushsave(current,pos_h,pos_v)
+ flushsetmatrix(current,pos_h,pos_v)
+ end
+
+ flushers.stopscaling = function(current,pos_h,pos_v)
+ flushrestore(current,pos_h,pos_v)
+ end
+
+ flushers.startrotation = function(current,pos_h,pos_v)
+ flushsave(current,pos_h,pos_v)
+ flushsetmatrix(current,pos_h,pos_v)
+ end
+
+ flushers.stoprotation = function(current,pos_h,pos_v)
+ flushrestore(current,pos_h,pos_v)
+ end
+
+ flushers.startmirroring = function(current,pos_h,pos_v)
+ flushsave(current,pos_h,pos_v)
+ flushsetmatrix(current,pos_h,pos_v)
+ end
+
+ flushers.stopmirroring = function(current,pos_h,pos_v)
+ flushrestore(current,pos_h,pos_v)
+ end
+
+ flushers.startclipping = function(current,pos_h,pos_v)
+ flushsave(current,pos_h,pos_v)
+ flushliteral("origin",formatters["0 w %s W n"](properties[current].path))
+ end
+
+ flushers.stopclipping = function(current,pos_h,pos_v)
+ flushrestore(current,pos_h,pos_v)
+ end
+
+end
+
+do
+
+ local nodeproperties = nodes.properties.data
+
+ flushers.setstate = function(current,pos_h,pos_v)
+ local p = nodeproperties[current]
+ if p then
+ local d = p.data
+ if d and d ~= "" then
+ pdf_goto_pagemode()
+ b = b + 1 ; buffer[b] = d
+ end
+ end
+ end
+
end
-- rules
@@ -917,7 +930,7 @@ end
local flushedxforms = { } -- actually box resources but can also be direct
local localconverter = nil -- will be set
-local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
+local flushimage do
local rulecodes = nodes.rulecodes
local newrule = nodes.pool.rule
@@ -1041,7 +1054,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
end
end
--- updaters.register("backend.update.tex",function()
+ -- updaters.register("backend.update.tex",function()
updaters.register("backend.update.lpdf",function()
tex.saveboxresource = saveboxresource
tex.useboxresource = useboxresource
@@ -1115,7 +1128,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
local groups = 0
local group = nil
- flushgroup = function(content,bbox)
+ local flushgroup = function(content,bbox)
if not group then
group = pdfdictionary {
Type = pdfconstant("Group"),
@@ -1136,6 +1149,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
return f_gr(groups)
end
+ flushers.group = flushgroup
lpdf.flushgroup = flushgroup -- todo: access via driver in mlib-pps
-- end of experiment
@@ -1287,6 +1301,8 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
b = b + 1 ; buffer[b] = s_e
end
+ flushers.image = flushimage
+
-- For the moment we need this hack because the engine checks the 'image'
-- command in virtual fonts (so we use lua instead).
--
@@ -1294,7 +1310,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
-- never because the next are like the other engines and compensate for
-- small sizes which is needed for inaccurate viewers.
- flushrule = function(current,pos_h,pos_v,pos_r,size_h,size_v,subtype)
+ flushers.rule = function(current,pos_h,pos_v,pos_r,size_h,size_v,subtype)
if subtype == emptyrule_code then
return
@@ -1350,7 +1366,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
end
- flushsimplerule = function(pos_h,pos_v,pos_r,size_h,size_v)
+ flushers.simplerule = function(pos_h,pos_v,pos_r,size_h,size_v)
pdf_goto_pagemode()
b = b + 1 ; buffer[b] = s_b
@@ -1374,7 +1390,7 @@ local flushrule, flushsimplerule, flushspecialrule, flushimage, flushgroup do
b = b + 1 ; buffer[b] = s_e
end
- flushspecialrule = function(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline)
+ flushers.specialrule = function(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline)
pdf_goto_pagemode()
b = b + 1 ; buffer[b] = s_b
@@ -2953,24 +2969,7 @@ do
drivers.install {
name = "pdf",
- flushers = {
- character = flushcharacter,
- fontchar = flushfontchar,
- rule = flushrule,
- simplerule = flushsimplerule,
- specialrule = flushspecialrule,
- pushorientation = pushorientation,
- poporientation = poporientation,
- --
- literal = flushliteral,
- setmatrix = flushsetmatrix,
- save = flushsave,
- restore = flushrestore,
- image = flushimage,
- group = flushgroup,
- --
- updatefontstate = updatefontstate,
- },
+ flushers = flushers,
actions = {
prepare = prepare,
wrapup = wrapup,
diff --git a/tex/context/base/mkxl/lpdf-mis.lmt b/tex/context/base/mkxl/lpdf-mis.lmt
index 46accf9a4..afb149d8a 100644
--- a/tex/context/base/mkxl/lpdf-mis.lmt
+++ b/tex/context/base/mkxl/lpdf-mis.lmt
@@ -26,11 +26,14 @@ local nodeinjections = backends.pdf.nodeinjections
local codeinjections = backends.pdf.codeinjections
local registrations = backends.pdf.registrations
+local getpagedimensions = layouts.getpagedimensions
+local getcanvas = layouts.getcanvas
+
local nuts = nodes.nuts
local copy_node = nuts.copy
local nodepool = nuts.pool
-local pageliteral = nodepool.pageliteral
+local setstate = nodepool.setstate
local register = nodepool.register
local pdfdictionary = lpdf.dictionary
@@ -86,10 +89,10 @@ local v_righttoleft = variables.righttoleft
local v_title = variables.title
local v_nomenubar = variables.nomenubar
-local positive = register(pageliteral("/GSpositive gs"))
-local negative = register(pageliteral("/GSnegative gs"))
-local overprint = register(pageliteral("/GSoverprint gs"))
-local knockout = register(pageliteral("/GSknockout gs"))
+local positive = register(setstate("/GSpositive gs"))
+local negative = register(setstate("/GSnegative gs"))
+local overprint = register(setstate("/GSoverprint gs"))
+local knockout = register(setstate("/GSknockout gs"))
local omitextraboxes = false
@@ -410,46 +413,12 @@ local pagespecs = {
},
}
-local pagespec, topoffset, leftoffset, height, width, doublesided = "default", 0, 0, 0, 0, false
-local cropoffset, bleedoffset, trimoffset, artoffset = 0, 0, 0, 0
-local marked = false
-local copies = false
+local function documentspecification()
+ local canvas = getcanvas()
-local getpagedimensions getpagedimensions = function()
- getpagedimensions = backends.codeinjections.getpagedimensions
- return getpagedimensions()
-end
+ -- move this to layo-ini ?
-function codeinjections.setupcanvas(specification)
- local paperheight = specification.paperheight
- local paperwidth = specification.paperwidth
- local paperdouble = specification.doublesided
- --
- paperwidth, paperheight = codeinjections.setpagedimensions(paperwidth,paperheight)
- --
- pagespec = specification.mode or pagespec
- topoffset = specification.topoffset or 0
- leftoffset = specification.leftoffset or 0
- height = specification.height or paperheight
- width = specification.width or paperwidth
- marked = specification.print
- --
- copies = specification.copies
- if copies and copies < 2 then
- copies = false
- end
- --
- cropoffset = specification.cropoffset or 0
- trimoffset = cropoffset - (specification.trimoffset or 0)
- bleedoffset = trimoffset - (specification.bleedoffset or 0)
- artoffset = bleedoffset - (specification.artoffset or 0)
- --
- if paperdouble ~= nil then
- doublesided = paperdouble
- end
-end
-
-local function documentspecification()
+ local pagespec = canvas.pagespec
if not pagespec or pagespec == "" then
pagespec = v_default
end
@@ -460,7 +429,7 @@ local function documentspecification()
local spec = defaults or pagespecs[v_default]
-- successive keys can modify this
if spec.layout == "auto" then
- if doublesided then
+ if canvas.doublesided then
local s = pagespecs[v_doublesided] -- to be checked voor interfaces
for k, v in next, s do
spec[k] = v
@@ -478,6 +447,7 @@ local function documentspecification()
end
end
end
+
-- maybe interfaces.variables
local layout = spec.layout
local mode = spec.mode
@@ -495,6 +465,8 @@ local function documentspecification()
addtocatalog("PageMode",pdfconstant(mode))
end
local prints = nil
+ local marked = canvas.marked
+ local copies = canvas.copies
if marked then
local pages = structures.pages
local marked = pages.allmarked(marked)
@@ -534,10 +506,15 @@ local function boxvalue(n) -- we could share them
end
local function pagespecification()
- local paperwidth, paperheight = codeinjections.getpagedimensions()
+ local canvas = getcanvas()
+ local paperwidth = canvas.paperwidth
+ local paperheight = canvas.paperheight
+ local leftoffset = canvas.leftoffset
+ local topoffset = canvas.topoffset
+ --
local llx = leftoffset
- local lly = paperheight + topoffset - height
- local urx = width - leftoffset
+ local urx = canvas.width - leftoffset
+ local lly = paperheight + topoffset - canvas.height
local ury = paperheight - topoffset
-- boxes can be cached
local function extrabox(WhatBox,offset,always)
@@ -553,10 +530,10 @@ local function pagespecification()
if omitextraboxes then
-- only useful for testing / comparing
else
- extrabox("CropBox",cropoffset,true) -- mandate for rendering
- extrabox("TrimBox",trimoffset,true) -- mandate for pdf/x
- extrabox("BleedBox",bleedoffset) -- optional
- -- extrabox("ArtBox",artoffset) -- optional .. unclear what this is meant to do
+ extrabox("CropBox",canvas.cropoffset,true) -- mandate for rendering
+ extrabox("TrimBox",canvas.trimoffset,true) -- mandate for pdf/x
+ extrabox("BleedBox",canvas.bleedoffset) -- optional
+ -- extrabox("ArtBox",canvas.artoffset) -- optional .. unclear what this is meant to do
end
end
diff --git a/tex/context/base/mkxl/lpdf-ren.lmt b/tex/context/base/mkxl/lpdf-ren.lmt
index 8aa61e1dc..3794250d9 100644
--- a/tex/context/base/mkxl/lpdf-ren.lmt
+++ b/tex/context/base/mkxl/lpdf-ren.lmt
@@ -60,7 +60,7 @@ local copy_node = nuts.copy
local nodepool = nuts.pool
local register = nodepool.register
-local pageliteral = nodepool.pageliteral
+local setstate = nodepool.setstate
local pdf_ocg = pdfconstant("OCG")
local pdf_ocmd = pdfconstant("OCMD")
@@ -267,7 +267,7 @@ function nodeinjections.startlayer(name)
local c = cache[name]
if not c then
useviewerlayer(name)
- c = register(pageliteral(f_bdc(escapednames[name])))
+ c = register(setstate(f_bdc(escapednames[name])))
cache[name] = c
end
return copy_node(c)
@@ -275,7 +275,7 @@ end
function nodeinjections.stoplayer()
if not stop then
- stop = register(pageliteral(s_emc))
+ stop = register(setstate(s_emc))
end
return copy_node(stop)
end
@@ -292,7 +292,7 @@ function nodeinjections.startstackedlayer(s,t,first,last)
r[#r+1] = startlayer(values[t[i]])
end
r = concat(r," ")
- return pageliteral(r)
+ return setstate(r)
end
function nodeinjections.stopstackedlayer(s,t,first,last)
@@ -301,7 +301,7 @@ function nodeinjections.stopstackedlayer(s,t,first,last)
r[#r+1] = stoplayer()
end
r = concat(r," ")
- return pageliteral(r)
+ return setstate(r)
end
function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
@@ -313,7 +313,7 @@ function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
r[#r+1] = startlayer(values[t2[i]])
end
r = concat(r," ")
- return pageliteral(r)
+ return setstate(r)
end
-- transitions
diff --git a/tex/context/base/mkxl/lpdf-rul.lmt b/tex/context/base/mkxl/lpdf-rul.lmt
index ae2142a8e..efcc62073 100644
--- a/tex/context/base/mkxl/lpdf-rul.lmt
+++ b/tex/context/base/mkxl/lpdf-rul.lmt
@@ -33,13 +33,9 @@ local formatters = string.formatters
-- This is very pdf specific. Maybe move some to lpdf-rul.lua some day.
-local pdfprint
+local pdfprint ; pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end
-pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end
-
--- updaters.register("backend.update",function()
--- pdfprint = lpdf.print
--- end)
+-- updaters.register("backend.update",function() pdfprint = lpdf.print end)
do
diff --git a/tex/context/base/mkxl/lpdf-tag.lmt b/tex/context/base/mkxl/lpdf-tag.lmt
index 4ea92d951..44a84ea59 100644
--- a/tex/context/base/mkxl/lpdf-tag.lmt
+++ b/tex/context/base/mkxl/lpdf-tag.lmt
@@ -63,7 +63,7 @@ local a_image = attributes.private('image')
local nuts = nodes.nuts
local nodepool = nuts.pool
-local pageliteral = nodepool.pageliteral
+local setstate = nodepool.setstate
local register = nodepool.register
local getid = nuts.getid
@@ -369,7 +369,7 @@ local visualize = nil
function nodeinjections.addtags(head)
if not EMCliteral then
- EMCliteral = register(pageliteral("EMC"))
+ EMCliteral = register(setstate("EMC"))
end
local last = nil
@@ -516,9 +516,9 @@ end
end
end
if prev then
- literal = pageliteral(makecontent(prev,id,specification))
+ literal = setstate(makecontent(prev,id,specification))
elseif ignore then
- literal = pageliteral(makeignore(specification))
+ literal = setstate(makeignore(specification))
else
-- maybe also ignore or maybe better: comment or so
end
@@ -543,7 +543,7 @@ end
else
- local literal = pageliteral(makeignore(specification))
+ local literal = setstate(makeignore(specification))
inject(start,stop,list,literal)
@@ -667,9 +667,9 @@ end
-- end
--
-- if r > 0 then
--- local literal = pageliteral(concat(result,"\n"))
+-- local literal = setstate(concat(result,"\n"))
-- -- use insert instead:
--- local literal = pageliteral(result)
+-- local literal = setstate(result)
-- local prev = getprev(start)
-- if prev then
-- setlink(prev,literal)
@@ -691,7 +691,7 @@ end
-- for i=1,noftop do
-- result[i] = "EMC"
-- end
--- local literal = pageliteral(concat(result,"\n"))
+-- local literal = setstate(concat(result,"\n"))
-- -- use insert instead:
-- local next = getnext(last)
-- if next then
diff --git a/tex/context/base/mkxl/lpdf-vfc.lmt b/tex/context/base/mkxl/lpdf-vfc.lmt
deleted file mode 100644
index 6030bb028..000000000
--- a/tex/context/base/mkxl/lpdf-vfc.lmt
+++ /dev/null
@@ -1,42 +0,0 @@
-if not modules then modules = { } end modules ['lpdf-vfc'] = {
- version = 1.001,
- comment = "companion to lpdf-ini.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local setmetatableindex = table.setmetatableindex
-
-local defaultline = 16384
-
-local vfspecials = backends.pdf.tables.vfspecials or utilities.storage.allocate { }
-backends.pdf.tables.vfspecials = vfspecials
-
-vfspecials.backgrounds = setmetatableindex(function(t,h)
- local v = setmetatableindex(function(t,d)
- local v = setmetatableindex(function(t,w)
- local v = { "frame", w, h, d, defaultline, true, true }
- t[w] = v
- return v
- end)
- t[d] = v
- return v
- end)
- t[h] = v
- return v
-end)
-
-vfspecials.outlines = setmetatableindex(function(t,h)
- local v = setmetatableindex(function(t,d)
- local v = setmetatableindex(function(t,w)
- local v = { "frame", w, h, d, defaultline, false, true }
- t[w] = v
- return v
- end)
- t[d] = v
- return v
- end)
- t[h] = v
- return v
-end)
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
new file mode 100644
index 000000000..3076f2ac9
--- /dev/null
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -0,0 +1,480 @@
+if not modules then modules = { } end modules ['math-act'] = {
+ version = 1.001,
+ comment = "companion to math-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Here we tweak some font properties (if needed). The commented sections
+-- have been removed (no longer viable) but can be found in the .lua variant.
+
+local type, next = type, next
+local fastcopy, insert, remove = table.fastcopy, table.insert, table.remove
+local formatters = string.formatters
+
+local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
+local trace_collecting = false trackers.register("math.collecting", function(v) trace_collecting = v end)
+
+local report_math = logs.reporter("mathematics","initializing")
+
+local context = context
+local commands = commands
+local mathematics = mathematics
+local texsetdimen = tex.setdimen
+local abs = math.abs
+
+local helpers = fonts.helpers
+local upcommand = helpers.commands.up
+local rightcommand = helpers.commands.right
+local charcommand = helpers.commands.char
+local prependcommands = helpers.prependcommands
+
+local sequencers = utilities.sequencers
+local appendgroup = sequencers.appendgroup
+local appendaction = sequencers.appendaction
+
+local fontchars = fonts.hashes.characters
+local fontproperties = fonts.hashes.properties
+
+local mathfontparameteractions = sequencers.new {
+ name = "mathparameters",
+ arguments = "target,original",
+}
+
+appendgroup("mathparameters","before") -- user
+appendgroup("mathparameters","system") -- private
+appendgroup("mathparameters","after" ) -- user
+
+function fonts.constructors.assignmathparameters(original,target)
+ local runner = mathfontparameteractions.runner
+ if runner then
+ runner(original,target)
+ end
+end
+
+function mathematics.initializeparameters(target,original)
+ local mathparameters = original.mathparameters
+ if mathparameters and next(mathparameters) then
+ mathparameters = mathematics.dimensions(mathparameters)
+ if not mathparameters.SpaceBeforeScript then
+ mathparameters.SpaceBeforeScript = mathparameters.SpaceAfterScript
+ end
+ target.mathparameters = mathparameters
+ end
+end
+
+sequencers.appendaction("mathparameters","system","mathematics.initializeparameters")
+
+local how = {
+ -- RadicalKernBeforeDegree = "horizontal",
+ -- RadicalKernAfterDegree = "horizontal",
+ ScriptPercentScaleDown = "unscaled",
+ ScriptScriptPercentScaleDown = "unscaled",
+ RadicalDegreeBottomRaisePercent = "unscaled",
+ NoLimitSupFactor = "unscaled",
+ NoLimitSubFactor = "unscaled",
+}
+
+function mathematics.scaleparameters(target,original)
+ if not target.properties.math_is_scaled then
+ local mathparameters = target.mathparameters
+ if mathparameters and next(mathparameters) then
+ local parameters = target.parameters
+ local factor = parameters.factor
+ local hfactor = parameters.hfactor
+ local vfactor = parameters.vfactor
+ for name, value in next, mathparameters do
+ local h = how[name]
+ if h == "unscaled" then
+ -- kept
+ elseif h == "horizontal" then
+ value = value * hfactor
+ elseif h == "vertical"then
+ value = value * vfactor
+ else
+ value = value * factor
+ end
+ mathparameters[name] = value
+ end
+ end
+ target.properties.math_is_scaled = true
+ end
+end
+
+-- AccentBaseHeight vs FlattenedAccentBaseHeight
+
+function mathematics.checkaccentbaseheight(target,original)
+ local mathparameters = target.mathparameters
+ if mathparameters and mathparameters.AccentBaseHeight == 0 then
+ mathparameters.AccentBaseHeight = target.parameters.x_height -- needs checking
+ end
+end
+
+function mathematics.checkprivateparameters(target,original)
+ local mathparameters = target.mathparameters
+ if mathparameters then
+ local parameters = target.parameters
+ local properties = target.properties
+ if parameters then
+ local size = parameters.size
+ if size then
+ if not mathparameters.FractionDelimiterSize then
+ mathparameters.FractionDelimiterSize = 1.01 * size
+ end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then
+ mathparameters.FractionDelimiterDisplayStyleSize = 2.40 * size
+ end
+ elseif properties then
+ report_math("invalid parameters in font %a",properties.fullname or "?")
+ else
+ report_math("invalid parameters in font")
+ end
+ elseif properties then
+ report_math("no parameters in font %a",properties.fullname or "?")
+ else
+ report_math("no parameters and properties in font")
+ end
+ end
+end
+
+function mathematics.overloadparameters(target,original)
+ local mathparameters = target.mathparameters
+ if mathparameters and next(mathparameters) then
+ local goodies = target.goodies
+ if goodies then
+ for i=1,#goodies do
+ local goodie = goodies[i]
+ local mathematics = goodie.mathematics
+ local parameters = mathematics and mathematics.parameters
+ if parameters then
+ if trace_defining then
+ report_math("overloading math parameters in %a @ %p",target.properties.fullname,target.parameters.size)
+ end
+ for name, value in next, parameters do
+ local tvalue = type(value)
+ if tvalue == "string" then
+ report_math("comment for math parameter %a: %s",name,value)
+ else
+ local oldvalue = mathparameters[name]
+ local newvalue = oldvalue
+ if oldvalue then
+ if tvalue == "number" then
+ newvalue = value
+ elseif tvalue == "function" then
+ newvalue = value(oldvalue,target,original)
+ elseif not tvalue then
+ newvalue = nil
+ end
+ if trace_defining and oldvalue ~= newvalue then
+ report_math("overloading math parameter %a: %S => %S",name,oldvalue,newvalue)
+ end
+ else
+ report_math("invalid math parameter %a",name)
+ end
+ mathparameters[name] = newvalue
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function applytweaks(when,target,original)
+ local goodies = original.goodies
+ if goodies then
+ for i=1,#goodies do
+ local goodie = goodies[i]
+ local mathematics = goodie.mathematics
+ local tweaks = mathematics and mathematics.tweaks
+ if type(tweaks) == "table" then
+ tweaks = tweaks[when]
+ if type(tweaks) == "table" then
+ if trace_defining then
+ report_math("tweaking math of %a @ %p (%s)",target.properties.fullname,target.parameters.size,when)
+ end
+ for i=1,#tweaks do
+ local tweak= tweaks[i]
+ local tvalue = type(tweak)
+ if tvalue == "function" then
+ tweak(target,original)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+function mathematics.tweakbeforecopyingfont(target,original)
+ local mathparameters = target.mathparameters -- why not hasmath
+ if mathparameters then
+ applytweaks("beforecopying",target,original)
+ end
+end
+
+function mathematics.tweakaftercopyingfont(target,original)
+ local mathparameters = target.mathparameters -- why not hasmath
+ if mathparameters then
+ applytweaks("aftercopying",target,original)
+ end
+end
+
+sequencers.appendaction("mathparameters","system","mathematics.scaleparameters")
+sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
+sequencers.appendaction("mathparameters","system","mathematics.checkprivateparameters") -- after scaling !
+sequencers.appendaction("mathparameters","system","mathematics.overloadparameters")
+
+sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont")
+sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont")
+
+local virtualized = mathematics.virtualized
+
+-- no, it's a feature now (see good-mth):
+--
+-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
+
+-- a couple of predefined tweaks:
+
+local tweaks = { }
+mathematics.tweaks = tweaks
+
+-- helpers
+
+local setmetatableindex = table.setmetatableindex
+
+local getfontoffamily = tex.getfontoffamily
+
+local fontcharacters = fonts.hashes.characters
+local extensibles = utilities.storage.allocate()
+fonts.hashes.extensibles = extensibles
+
+local chardata = characters.data
+local extensibles = mathematics.extensibles
+
+-- we use numbers at the tex end (otherwise we could stick to chars)
+
+local e_left = extensibles.left
+local e_right = extensibles.right
+local e_horizontal = extensibles.horizontal
+local e_mixed = extensibles.mixed
+local e_unknown = extensibles.unknown
+
+local unknown = { e_unknown, false, false }
+
+local function extensiblecode(font,unicode)
+ local characters = fontcharacters[font]
+ local character = characters[unicode]
+ if not character then
+ return unknown
+ end
+ local first = character.next
+ local code = unicode
+ local next = first
+ while next do
+ code = next
+ character = characters[next]
+ next = character.next
+ end
+ local char = chardata[unicode]
+ if not char then
+ return unknown
+ end
+ if character.horiz_variants then
+ if character.vert_variants then
+ return { e_mixed, code, character }
+ else
+ local m = char.mathextensible
+ local e = m and extensibles[m]
+ return e and { e, code, character } or unknown
+ end
+ elseif character.vert_variants then
+ local m = char.mathextensible
+ local e = m and extensibles[m]
+ return e and { e, code, character } or unknown
+ elseif first then
+ -- assume accent (they seldom stretch .. sizes)
+ local m = char.mathextensible or char.mathstretch
+ local e = m and extensibles[m]
+ return e and { e, code, character } or unknown
+ else
+ return unknown
+ end
+end
+
+setmetatableindex(extensibles,function(extensibles,font)
+ local codes = { }
+ setmetatableindex(codes, function(codes,unicode)
+ local status = extensiblecode(font,unicode)
+ codes[unicode] = status
+ return status
+ end)
+ extensibles[font] = codes
+ return codes
+end)
+
+local function extensiblecode(family,unicode)
+ return extensibles[getfontoffamily(family or 0)][unicode][1]
+end
+
+-- left : [head] ...
+-- right : ... [head]
+-- horizontal : [head] ... [head]
+--
+-- abs(right["start"] - right["end"]) | right.advance | characters[right.glyph].width
+
+local function horizontalcode(family,unicode)
+ local font = getfontoffamily(family or 0)
+ local data = extensibles[font][unicode]
+ local kind = data[1]
+ local loffset = 0
+ local roffset = 0
+ if kind == e_left then
+ local charlist = data[3].horiz_variants
+ if charlist then
+ local left = charlist[1]
+ loffset = abs((left["start"] or 0) - (left["end"] or 0))
+ end
+ elseif kind == e_right then
+ local charlist = data[3].horiz_variants
+ if charlist then
+ local right = charlist[#charlist]
+ roffset = abs((right["start"] or 0) - (right["end"] or 0))
+ end
+ elseif kind == e_horizontal then
+ local charlist = data[3].horiz_variants
+ if charlist then
+ local left = charlist[1]
+ local right = charlist[#charlist]
+ loffset = abs((left ["start"] or 0) - (left ["end"] or 0))
+ roffset = abs((right["start"] or 0) - (right["end"] or 0))
+ end
+ end
+ return kind, loffset, roffset
+end
+
+mathematics.extensiblecode = extensiblecode
+mathematics.horizontalcode = horizontalcode
+
+interfaces.implement {
+ name = "extensiblecode",
+ arguments = { "integer", "integer" },
+ actions = { extensiblecode, context }
+}
+
+interfaces.implement {
+ name = "horizontalcode",
+ arguments = { "integer", "integer" },
+ actions = function(family,unicode)
+ local kind, loffset, roffset = horizontalcode(family,unicode)
+ texsetdimen("scratchleftoffset", loffset)
+ texsetdimen("scratchrightoffset",roffset)
+ context(kind)
+ end
+}
+
+
+local stack = { }
+
+function mathematics.registerfallbackid(n,id,name)
+ if trace_collecting then
+ report_math("resolved fallback font %i, name %a, id %a, used %a",
+ n,name,id,fontproperties[id].fontname)
+ end
+ stack[#stack][n] = id
+end
+
+interfaces.implement { -- will be shared with text
+ name = "registerfontfallbackid",
+ arguments = { "integer", "integer", "string" },
+ actions = mathematics.registerfallbackid,
+}
+
+function mathematics.resolvefallbacks(target,specification,fallbacks)
+ local definitions = fonts.collections.definitions[fallbacks]
+ if definitions then
+ local size = specification.size -- target.size
+ local list = { }
+ insert(stack,list)
+ context.pushcatcodes("prt") -- context.unprotect()
+ for i=1,#definitions do
+ local definition = definitions[i]
+ local name = definition.font
+ local features = definition.features or ""
+ local size = size * (definition.rscale or 1)
+ context.font_fallbacks_register_math(i,name,features,size)
+ if trace_collecting then
+ report_math("registering fallback font %i, name %a, size %a, features %a",i,name,size,features)
+ end
+ end
+ context.popcatcodes()
+ end
+end
+
+function mathematics.finishfallbacks(target,specification,fallbacks)
+ local list = remove(stack)
+ if list and #list > 0 then
+ local definitions = fonts.collections.definitions[fallbacks]
+ if definitions and #definitions > 0 then
+ if trace_collecting then
+ report_math("adding fallback characters to font %a",specification.hash)
+ end
+ local definedfont = fonts.definers.internal
+ local copiedglyph = fonts.handlers.vf.math.copy_glyph
+ local fonts = target.fonts
+ local size = specification.size -- target.size
+ local characters = target.characters
+ if not fonts then
+ fonts = { }
+ target.fonts = fonts
+ end
+ if #fonts == 0 then
+ fonts[1] = { id = 0, size = size } -- self, will be resolved later
+ end
+ local done = { }
+ for i=1,#definitions do
+ local definition = definitions[i]
+ local name = definition.font
+ local start = definition.start
+ local stop = definition.stop
+ local gaps = definition.gaps
+ local check = definition.check
+ local force = definition.force
+ local rscale = definition.rscale or 1
+ local offset = definition.offset or start
+ local id = list[i]
+ if id then
+ local index = #fonts + 1
+ fonts[index] = { id = id, size = size }
+ local chars = fontchars[id]
+ local function remap(unic,unicode,gap)
+ if check and not chars[unicode] then
+ return
+ end
+ if force or (not done[unic] and not characters[unic]) then
+ if trace_collecting then
+ report_math("replacing math character %C by %C using vector %a and font id %a for %a%s%s",
+ unic,unicode,fallbacks,id,fontproperties[id].fontname,check and ", checked",gap and ", gap plugged")
+ end
+ characters[unic] = copiedglyph(target,characters,chars,unicode,index)
+ done[unic] = true
+ end
+ end
+ local step = offset - start
+ for unicode = start, stop do
+ remap(unicode + step,unicode,false)
+ end
+ if gaps then
+ for unic, unicode in next, gaps do
+ remap(unic,unicode,true)
+ remap(unicode,unicode,true)
+ end
+ end
+ end
+ end
+ elseif trace_collecting then
+ report_math("no fallback characters added to font %a",specification.hash)
+ end
+ end
+end
diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl
index d90f3ab0f..72f857720 100644
--- a/tex/context/base/mkxl/math-ali.mkxl
+++ b/tex/context/base/mkxl/math-ali.mkxl
@@ -285,7 +285,7 @@
\math_number_right_of_eqalign
\global\settrue\c_math_eqalign_first
\crcr
- \dostoptagged} % finish row
+ \noalign{\dostoptagged}} % finish row
\permanent\protected\def\math_alignment_NC
{\relax
diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl
index 95501be65..01ecd63a2 100644
--- a/tex/context/base/mkxl/math-ini.mkxl
+++ b/tex/context/base/mkxl/math-ini.mkxl
@@ -66,7 +66,7 @@
\registerctxluafile{math-ini}{}
\registerctxluafile{math-dim}{}
-\registerctxluafile{math-act}{}
+\registerctxluafile{math-act}{autosuffix}
\registerctxluafile{math-ext}{}
\registerctxluafile{math-vfu}{autosuffix}
\registerctxluafile{math-ttv}{}
diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt
index c884e6927..92edbc441 100644
--- a/tex/context/base/mkxl/math-noa.lmt
+++ b/tex/context/base/mkxl/math-noa.lmt
@@ -693,7 +693,8 @@ do
end
-- We can optimize this if we really think that math is a bottleneck which it never
- -- really is.
+ -- really is. Beware: the font is the text font in the family, so we only check the
+ -- text font here.
relocate[mathchar_code] = function(pointer)
local g = getattr(pointer,a_mathgreek) or 0
@@ -757,7 +758,13 @@ do
end
end
if not characters[char] then
+ local fam = getfam(pointer)
+ local fnt = getfontoffamily(fam,1)
setchar(pointer,errorchar(font,char))
+ if font ~= fnt then
+ errorchar(fnt,char)
+ errorchar(getfontoffamily(fam,2),char)
+ end
end
if trace_analyzing then
setnodecolor(pointer,"font:medi")
diff --git a/tex/context/base/mkxl/meta-imp-punk.mkxl b/tex/context/base/mkxl/meta-imp-punk.mkxl
new file mode 100644
index 000000000..050023642
--- /dev/null
+++ b/tex/context/base/mkxl/meta-imp-punk.mkxl
@@ -0,0 +1,272 @@
+%D \module
+%D [ file=meta-imp-punk,
+%D version=2020.01.16,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Punk,
+%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.
+
+% This file is a merge of the original punk files by Donald Knuth, who
+% added this comment:
+%
+% Font inspired by Gerard and Marjan Unger's lectures, Feb 1985
+%
+% The regular punk files are part of TeXLive and in metafont format. All
+% errors introduced are ours. We also changed the encoding to unicode. In
+% due time we might add a few more more characters. We still need to
+% improve some of the metrics which involves a bit of trial and error. The
+% font just covers basic latin shapes but in ConTeXt MkIV we add virtual
+% composed shapes. There is a module m-punk.tex that implements this. This
+% derivate is also used in mk.tex (mk.pdf) which is one of our tests for
+% LuaTeX. We published an article on it in the MAPS (NTG magazine).
+%
+% 2008, mkiv variant: Taco Hoekwater & Hans Hagen
+% 2020, lmtx variant: Hans Hagen (playground)
+
+\startMPcalculation{simplefun}
+
+ picture PunkShapes[][];
+
+ numeric PunkId ; PunkId := 0 ;
+ numeric PunkBase ; PunkBase := 0 ;
+ string PunkName ; PunkName := "punk" ;
+ numeric PunkUsed ; PunkUsed := 0 ;
+ numeric PunkSlant ; PunkSlant := 0 ;
+ numeric PunkWeight ; PunkWeight := 1 ;
+ numeric PunkSqueeze ; PunkSqueeze := 1 ;
+ numeric PunkExtend ; PunkExtend := 1 ;
+ numeric PunkVariants ; PunkVariants := 0 ;
+
+ numeric PunkRatio ; PunkRatio := 2/3 ;
+ numeric PunkScale ; PunkScale := 20 ; % when zero we use the knuth values
+ numeric PunkN ; PunkN := 0 ;
+
+ def beginpunkchar(expr c, n, hor, ver) =
+ begingroup ;
+ save uc, w, h, d, hdev, vdev ;
+ hdev := hor * dev ; % modify horizontal amounts of deviation
+ vdev := ver * dev ; % modify vertical amounts of deviation
+ uc := if string c : utfnum(c) else : c fi ;
+ h := if PunkScale > 0 : PunkN else : n fi / PunkSqueeze ;
+ w := n * PunkExtend ;
+ d := 0 ;
+ clearxy ;
+ clearit ;
+ enddef ;
+
+ def endpunkchar =
+ if PunkSlant <> 0 :
+ currentpicture := currentpicture slanted PunkSlant ;
+ fi ;
+ save llx, lly, uly ;
+ llx := xpart llcorner currentpicture ;
+ lly := ypart llcorner currentpicture ;
+ uly := ypart ulcorner currentpicture ;
+
+ currentpicture := currentpicture shifted (- llx + 1, 0);
+ w := bbwidth(currentpicture) + 2 ;
+ h := uly ;
+ d := if lly < 0 : - lly else : 0 fi ;
+
+ PunkUsed := if PunkBase > 0 : PunkBase else : uc fi;
+ PunkShapes[PunkId][PunkUsed] := currentpicture ;
+ lmt_registerglyph [
+ category = PunkName,
+ unicode = PunkUsed,
+ tounicode = uc,
+ width = w,
+ height = h,
+ depth = d,
+ code = "draw PunkShapes[" & decimal PunkId & "][" & decimal PunkUsed & "]",
+ ] ;
+ if PunkBase > 0 :
+ PunkBase := PunkBase + 1 ;
+ fi ;
+ endgroup ;
+ enddef ;
+
+ def initialize_punk_upper =
+ PunkN := PunkScale ;
+ dev := 1 ;
+ enddef ;
+
+ def initialize_punk_lower =
+ PunkN := PunkScale * PunkRatio ;
+ dev := .5 ;
+ enddef ;
+
+ def revert_punk_lower =
+ PunkN := PunkScale ;
+ dev := 1 ;
+ enddef ;
+
+ def beginpunkfont =
+
+ begingroup ;
+
+ save dev;
+
+ save u ; u := 1 ;
+
+ PunkBase := 0 ;
+
+ pen linepen ; linepen := pencircle scaled (PunkWeight * u) ;
+ pen dotpen ; dotpen := linepen scaled 2 slanted -PunkSlant ;
+
+ pickup linepen ;
+
+ save pp ; vardef pp expr z =
+ z + (hdev * normaldeviate, vdev * normaldeviate)
+ enddef ;
+
+ save pd ; def pd expr z =
+ drawdot z withpen dotpen ;
+ enddef ;
+
+ PunkId := PunkId + 1 ;
+
+ lmt_registerglyphs [
+ name = PunkName, % todo: when we do name = name we get ['"name"'] = name
+ units = 25,
+ width = 25,
+ height = 25,
+ depth = 0,
+ usecolor = true,
+ ] ;
+
+ def endchar = endpunkchar enddef ;
+
+ enddef ;
+
+ def endpunkfont =
+ endgroup;
+ enddef ;
+
+ % We started out with immediate:
+
+ % def MakePunkFont (expr name, filename, slant, weight, squeeze, extend) =
+ % begingroup ;
+ % save PunkName, PunkFileName, PunkSlant, PunkWeight, PunkSqueeze, PunkExend, PunkVariants ;
+ % string PunkName, PunkFileName ;
+ % PunkFileName := filename ;
+ % PunkName := name ;
+ % PunkSlant := slant ;
+ % PunkWeight := weight ;
+ % PunkSqueeze := squeeze ;
+ % PunkExtend := extend ;
+ % PunkVariants := 0 ;
+ % beginpunkfont ;
+ % loadfile(PunkFileName) ;
+ % endpunkfont ;
+ % endgroup ;
+ % enddef ;
+ %
+ % MakePunkFont("punk", "punkfont-characters.mp", 1, 0 ) ;
+ % MakePunkFont("punkbold", "punkfont-characters.mp", 2, 0 ) ;
+ % MakePunkFont("punkslanted", "punkfont-characters.mp", 1, 0.15) ;
+ % MakePunkFont("punkboldslanted", "punkfont-characters.mp", 2, 0.15) ;
+
+ % And ended up with delayed:
+
+ def punkpreroll =
+ begingroup ;
+ save PunkName, PunkFileName, PunkSlant, PunkWeight, PunkSqueeze, PunkExtend, PunkVariants ;
+ string PunkName, PunkFileName ;
+ PunkName := getparameterdefault "mpsfont" "name" "punk" ;
+ PunkFileName := getparameterdefault "mpsfont" "filename" "punkfont-characters.mp" ;
+ PunkSlant := scantokens(getparameterdefault "mpsfont" "slant" "0") ;
+ PunkWeight := scantokens(getparameterdefault "mpsfont" "weight" "1") ;
+ PunkSqueeze := scantokens(getparameterdefault "mpsfont" "squeeze" "1") ;
+ PunkExtend := scantokens(getparameterdefault "mpsfont" "extend" "1") ;
+ PunkVariants := scantokens(getparameterdefault "mpsfont" "variants" "0");
+ beginpunkfont ;
+ loadfile(PunkFileName) ;
+ if PunkVariants > 0 :
+ PunkBase := 57344 ; % 0xE000 ; 0xF0000 ;
+ for i=1 upto PunkVariants :
+ loadfile(PunkFileName) ;
+ endfor ;
+ fi ;
+ endpunkfont ;
+ endgroup ;
+ enddef ;
+
+\stopMPcalculation
+
+% Are these names okay? If so it can go into the core.
+
+\permanent\protected\def\enablerandomvariants{\setcharactercasing[randomvariant]}
+\permanent\protected\def\randomvariants {\groupedcommand\enablerandomvariants\donothing}
+\permanent\protected\def\startrandomvariants {\begingroup\enablerandomvariants}
+\permanent\protected\def\stoprandomvariants {\endgroup}
+
+\definefontfeature [punk] [metapost={category=punk,preroll=punkpreroll}]
+\definefontfeature [punkrandom] [metapost={category=punk,preroll=punkpreroll,variants=10}]
+\definefontfeature [punkbold] [metapost={category=punk,preroll=punkpreroll,weight=2}]
+\definefontfeature [punkslanted] [metapost={category=punk,preroll=punkpreroll,slant=.15}]
+\definefontfeature [punkboldslanted] [metapost={category=punk,preroll=punkpreroll,slant=.15,weight=2}]
+\definefontfeature [punkveryslanted] [metapost={category=punk,preroll=punkpreroll,slant=-.15}]
+\definefontfeature [punksqueezed] [metapost={category=punk,preroll=punkpreroll,squeeze=.5}]
+\definefontfeature [punkextended] [metapost={category=punk,preroll=punkpreroll,extend=1.3}]
+
+\continueifinputfile{meta-imp-punk.mkxl}
+
+% immediate:
+%
+% \definefontfeature [punk] [metapost=punk]
+% \definefontfeature [punkbold] [metapost=punkbold]
+% \definefontfeature [punkslanted] [metapost=punkslanted]
+% \definefontfeature [punkboldslanted] [metapost=punkboldslanted]
+
+% delayed:
+
+% name=punk
+% filename=punkfont-characters.mp
+
+\setupbodyfont[dejavu]
+
+\definefont[PunkA][Serif*punk]
+\definefont[PunkB][Serif*punkbold]
+\definefont[PunkC][Serif*punkslanted]
+\definefont[PunkD][Serif*punkboldslanted]
+\definefont[PunkE][Serif*punkveryslanted]
+\definefont[PunkF][Serif*punkrandom]
+\definefont[PunkG][Serif*punksqueezed]
+\definefont[PunkH][Serif*punkextended]
+
+\starttext
+
+\startTEXpage[offset=10pt,width=30cm]
+ % \showglyphs
+ {\darkcyan \PunkA \samplefile{tufte} \par}
+ {\darkmagenta \PunkB \samplefile{tufte} \par}
+ {\darkred \PunkC \samplefile{tufte} \par}
+ {\darkgreen \PunkD \samplefile{tufte} \par}
+ {\darkblue \PunkE \samplefile{tufte} \par}
+ {\darkyellow \PunkF \enablerandomvariants \samplefile{tufte} \par}
+ {\darkgray \PunkG \samplefile{tufte} \par}
+ {\darkorange \PunkH \samplefile{tufte} \par}
+\stopTEXpage
+
+\startTEXpage[offset=10pt,width=2cm]
+ \PunkF \enablerandomvariants
+ \dostepwiserecurse{1}{2000}{1}{\glyphscale#1\relax f }
+\stopTEXpage
+
+% \setupbodyfont[dejavu]
+
+\setupbodyfont[punk] %one first needs to load a bodyfont !
+
+\startTEXpage[offset=10pt,width=20cm]
+ {\darkcyan \tf \samplefile{zapf} \par}
+ {\darkmagenta \bf \samplefile{zapf} \par}
+ {\darkred \sl \samplefile{zapf} \par}
+ {\darkgreen \bs \samplefile{zapf} \par}
+\stopTEXpage
+
+\stoptext
diff --git a/tex/context/base/mkxl/mlib-mpf.lmt b/tex/context/base/mkxl/mlib-mpf.lmt
index 6bd31376c..d66491a16 100644
--- a/tex/context/base/mkxl/mlib-mpf.lmt
+++ b/tex/context/base/mkxl/mlib-mpf.lmt
@@ -86,12 +86,10 @@ do
else
runscripts[nofscripts] = name
end
--- print("set",name,nofscripts,f)
return nofscripts
end
function metapost.scriptindex(name)
--- print("get",name,runnames[name] or 0)
return runnames[name] or 0
end
@@ -945,9 +943,14 @@ do
registerscript("setcount", function() setcount(scanstring(),scannumeric()) end)
registerscript("settoks", function() settoks (scanstring(),scanstring()) end)
+ local utfnum = utf.byte
local utflen = utf.len
local utfsub = utf.sub
+ registerscript("utfnum", function()
+ injectnumeric(utfnum(scanstring()))
+ end)
+
registerscript("utflen", function()
injectnumeric(utflen(scanstring()))
end)
diff --git a/tex/context/base/mkxl/node-ext.lmt b/tex/context/base/mkxl/node-ext.lmt
new file mode 100644
index 000000000..2f909cd3d
--- /dev/null
+++ b/tex/context/base/mkxl/node-ext.lmt
@@ -0,0 +1,650 @@
+if not modules then modules = { } end modules ['back-out'] = {
+ version = 1.001,
+ comment = "companion to back-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, unpack, rawset = type, unpack, type
+local loadstring = loadstring
+local sind, cosd, abs = math.sind, math.cosd, math.abs
+local insert, remove = table.insert, table.remove
+
+local context = context
+local implement = interfaces.implement
+
+local allocate = utilities.storage.allocate
+
+local formatters = string.formatters
+
+local get = token.get_index -- getters
+local scanners = tokens.scanners
+local scaninteger = scanners.integer
+local scanstring = scanners.string
+local scankeyword = scanners.keyword
+local scantokenlist = scanners.tokenlist
+local scannumber = scanners.number
+
+local nuts = nodes.nuts
+local tonode = nuts.tonode
+local copynut = nuts.copy
+local nutpool = nuts.pool
+local nodepool = nodes.pool
+
+local nodeproperties = nodes.properties.data
+
+local register = nutpool.register
+local newnut = nuts.new
+local tonode = nodes.tonode
+
+-- Whatsits are a generic node type with very few fields. We use them to implement
+-- whatever we like. Some are good old tex whatsits but many are specific to the
+-- macro package. They are part of the backend.
+
+backends = backends or { }
+local backends = backends
+
+local whatsit_code = nodes.nodecodes.whatsit
+local whatsitcodes = allocate { }
+nodes.whatsitcodes = whatsitcodes
+local lastwhatsit = 0
+
+nodes.subtypes.whatsit = whatsitcodes
+
+local function registerwhatsit(name)
+ lastwhatsit = lastwhatsit + 1
+ whatsitcodes[lastwhatsit] = name
+ whatsitcodes[name] = lastwhatsit
+ return lastwhatsit
+end
+
+local function registerwhatsitnode(name)
+ return register(newnut(whatsit_code,registerwhatsit(name)))
+end
+
+-- We only have a subset of literals. In fact, we try to avoid literals.
+
+do
+
+ local literalvalues = allocate { }
+ nodes.literalvalues = literalvalues
+ local lastliteral = 0
+ local literalnode = registerwhatsitnode("literal")
+
+ local function registerliteral(name,alias)
+ lastliteral = lastliteral + 1
+ literalvalues[lastliteral] = name
+ literalvalues[name] = lastliteral
+ if alias then
+ literalvalues[alias] = lastliteral
+ end
+ return lastliteral
+ end
+
+ local originliteral_code = registerliteral("origin")
+ local pageliteral_code = registerliteral("page")
+ local directliteral_code = registerliteral("always","direct")
+ local rawliteral_code = registerliteral("raw")
+ local textliteral_code = registerliteral("text") -- not to be used
+ local fontliteral_code = registerliteral("font") -- not to be used
+
+ function nutpool.originliteral(str) local t = copynut(literalnode) nodeproperties[t] = { data = str, mode = originliteral_code } return t end
+ function nutpool.pageliteral (str) local t = copynut(literalnode) nodeproperties[t] = { data = str, mode = pageliteral_code } return t end
+ function nutpool.directliteral(str) local t = copynut(literalnode) nodeproperties[t] = { data = str, mode = directliteral_code } return t end
+ function nutpool.rawliteral (str) local t = copynut(literalnode) nodeproperties[t] = { data = str, mode = rawliteral_code } return t end
+
+ local pdfliterals = {
+ [originliteral_code] = originliteral_code, [literalvalues[originliteral_code]] = originliteral_code,
+ [pageliteral_code] = pageliteral_code, [literalvalues[pageliteral_code]] = pageliteral_code,
+ [directliteral_code] = directliteral_code, [literalvalues[directliteral_code]] = directliteral_code,
+ [rawliteral_code] = rawliteral_code, [literalvalues[rawliteral_code]] = rawliteral_code,
+ }
+
+ function nutpool.literal(mode,str)
+ local t = copynut(literalnode)
+ if str then
+ nodeproperties[t] = { data = str, mode = pdfliterals[mode] or pageliteral_code }
+ else
+ nodeproperties[t] = { data = mode, mode = pageliteral_code }
+ end
+ return t
+ end
+
+end
+
+-- The latelua node is just another whatsit and we handle the \LUA\ code with
+-- other \LUA\ code, contrary to \LUATEX\ where it's a native node.
+
+do
+
+ local getdata = nuts.getdata
+ local serialize = token.serialize
+
+ local lateluanode = registerwhatsitnode("latelua")
+ local noflatelua = 0
+
+ function nutpool.latelua(code)
+ local n = copynut(lateluanode)
+ nodeproperties[n] = { data = code }
+ return n
+ end
+
+ function backends.latelua(current,pos_h,pos_v) -- todo: pass pos_h and pos_v (more efficient in lmtx)
+ local p = nodeproperties[current]
+ if p then
+ data = p.data
+ else
+ data = getdata(current)
+ end
+ noflatelua = noflatelua + 1
+ local kind = type(data)
+ if kind == "table" then
+ data.action(data.specification or data)
+ elseif kind == "function" then
+ data()
+ else
+ if kind ~= "string" then
+ data = serialize(data)
+ end
+ if #data ~= "" then
+ local code = loadstring(data)
+ if code then
+ code()
+ end
+ end
+ end
+ end
+
+ function backends.getcallbackstate()
+ return { count = noflatelua }
+ end
+
+ implement {
+ name = "latelua",
+ public = true,
+ protected = true,
+ actions = function()
+ local node = copynut(lateluanode)
+ local name = "latelua"
+ if scankeyword("name") then
+ name = scanstring()
+ end
+ local data = scantokenlist()
+ nodeproperties[node] = { name = name, data = data }
+ return context(tonode(node))
+ end,
+ }
+
+end
+
+-- This can be anything. Dealing with these nodes is done via properties, as with
+-- the other whatsits.
+
+do
+
+ local usernode = registerwhatsitnode("userdefined")
+
+ local userids = allocate()
+ local lastid = 0
+
+ setmetatable(userids, {
+ __index = function(t,k)
+ if type(k) == "string" then
+ lastid = lastid + 1
+ rawset(userids,lastid,k)
+ rawset(userids,k,lastid)
+ return lastid
+ else
+ rawset(userids,k,k)
+ return k
+ end
+ end,
+ __call = function(t,k)
+ return t[k]
+ end
+ } )
+
+ function nutpool.userdefined(id,data)
+ local n = copynut(usernode)
+ nodeproperties[n] = { id = id, data = data }
+ return n
+ end
+
+ nutpool .usernode = nutpool.userdefined
+ nutpool .userids = userids
+ nodepool.userids = userids
+
+end
+
+-- This one is only used by generic packages.
+
+do
+
+ local saveposnode = registerwhatsitnode("savepos")
+
+ function nutpool.savepos()
+ return copynut(saveposnode)
+ end
+
+end
+
+do
+
+ local savenode = registerwhatsitnode("save")
+ local restorenode = registerwhatsitnode("restore")
+ local setmatrixnode = registerwhatsitnode("setmatrix")
+
+ local stack = { }
+ local restore = true -- false
+
+ -- these are old school nodes
+
+ function nutpool.save()
+ return copynut(savenode)
+ end
+
+ function nutpool.restore()
+ return copynut(restorenode)
+ end
+
+ function nutpool.setmatrix(rx,sx,sy,ry,tx,ty)
+ local t = copynut(setmatrixnode)
+ nodeproperties[t] = { matrix = { rx, sx, sy, ry, tx, ty } }
+ return t
+ end
+
+ -- common
+
+ local function stopcommon(n)
+ local top = remove(stack)
+ if top == false then
+ return -- not wrapped
+ elseif top == true then
+ return copynut(n)
+ elseif top then
+ local t = copynut(n)
+ nodeproperties[t] = { matrix = { unpack(top) } }
+ return t
+ else
+ return -- nesting error
+ end
+ end
+
+ -- matrix
+
+ local startmatrixnode = registerwhatsitnode("startmatrix")
+ local stopmatrixnode = registerwhatsitnode("stopmatrix")
+
+ local function startmatrix(rx, sx, sy, ry)
+ if rx == 1 and sx == 0 and sy == 0 and ry == 1 then
+ insert(stack,false)
+ else
+ local t = copynut(startmatrixnode)
+ nodeproperties[t] = { matrix = { rx, sx, sy, ry } }
+ insert(stack,store and { -rx, -sx, -sy, -ry } or true)
+ return t
+ end
+ end
+
+ local function stopmatrix()
+ return stopcommon(stopmatrixnode)
+ end
+
+ implement {
+ name = "startmatrix",
+ actions = function()
+ local rx, sx, sy, ry = 1, 0, 0, 1
+ while true do
+ if scankeyword("rx") then rx = scannumber()
+ elseif scankeyword("ry") then ry = scannumber()
+ elseif scankeyword("sx") then sx = scannumber()
+ elseif scankeyword("sy") then sy = scannumber()
+ else break end
+ end
+ local t = startmatrix(rx,sx,sy,ry)
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ implement {
+ name = "stopmatrix",
+ actions = function()
+ local t = stopmatrix(n)
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ -- scale
+
+ local startscalingnode = registerwhatsitnode("startscaling")
+ local stopscalingnode = registerwhatsitnode("stopscaling")
+
+ local function startscaling(rx, ry) -- at the tex end we use sx and sy instead of rx and ry
+ if rx == 1 and ry == 1 then
+ insert(stack,false)
+ else
+ if rx == 0 then
+ rx = 0.0001
+ end
+ if ry == 0 then
+ ry = 0.0001
+ end
+ local t = copynut(startscalingnode)
+ nodeproperties[t] = { matrix = { rx, 0, 0, ry } }
+ insert(stack,restore and { 1/rx, 0, 0, 1/ry } or true)
+ return t
+ end
+ end
+
+ local function stopscaling() -- at the tex end we use sx and sy instead of rx and ry
+ return stopcommon(stopscalingnode)
+ end
+
+ implement {
+ name = "startscaling",
+ actions = function()
+ local rx, ry = 1, 1
+ while true do
+ if scankeyword("rx") then
+ rx = scannumber()
+ elseif scankeyword("ry") then
+ ry = scannumber()
+ else
+ break
+ end
+ end
+ local t = startscaling(rx,ry)
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ implement {
+ name = "stopscaling",
+ actions = function()
+ local t = stopscaling(n)
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ -- rotate
+
+ local startrotationnode = registerwhatsitnode("startrotation")
+ local stoprotationnode = registerwhatsitnode("stoprotation")
+
+ local function startrotation(a)
+ if a == 0 then
+ insert(stack,false)
+ else
+ local s, c = sind(a), cosd(a)
+ if abs(s) < 0.000001 then
+ s = 0 -- otherwise funny -0.00000
+ end
+ if abs(c) < 0.000001 then
+ c = 0 -- otherwise funny -0.00000
+ end
+ local t = copynut(startrotationnode)
+ nodeproperties[t] = { matrix = { c, s, -s, c } }
+ insert(stack,restore and { c, -s, s, c } or true)
+ return t
+ end
+ end
+
+ local function stoprotation()
+ return stopcommon(stoprotationnode)
+ end
+
+ nutpool.startrotation = startrotation
+
+ implement {
+ name = "startrotation",
+ actions = function()
+ local n = scannumber()
+ local t = startrotation(n)
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ implement {
+ name = "stoprotation",
+ actions = function()
+ local t = stoprotation()
+ if t then
+ context(tonode(t))
+ end
+ end,
+ }
+
+ -- mirror
+
+ local startmirroringnode = registerwhatsitnode("startmirroring")
+ local stopmirroringnode = registerwhatsitnode("stopmirroring")
+
+ local function startmirroring()
+ local t = copynut(startmirroringnode)
+ nodeproperties[t] = { matrix = { -1, 0, 0, 1 } }
+ return t
+ end
+
+ local function stopmirroring()
+ local t = copynut(stopmirroringnode)
+ nodeproperties[t] = { matrix = { -1, 0, 0, 1 } }
+ return t
+ end
+
+ implement {
+ name = "startmirroring",
+ actions = function()
+ context(tonode(startmirroring()))
+ end,
+ }
+
+ implement {
+ name = "stopmirroring",
+ actions = function()
+ context(tonode(stopmirroring()))
+ end,
+ }
+
+ -- clip
+
+ local startclippingnode = registerwhatsitnode("startclipping")
+ local stopclippingnode = registerwhatsitnode("stopclipping")
+
+ local function startclipping(path)
+ local t = copynut(startclippingnode)
+ nodeproperties[t] = { path = path }
+ return t
+ end
+
+ local function stopclipping()
+ return copynut(stopclippingnode)
+ end
+
+ implement {
+ name = "startclipping",
+ actions = function()
+ context(tonode(startclipping(scanstring())))
+ end
+ }
+
+ implement {
+ name = "stopclipping",
+ actions = function()
+ context(tonode(stopclipping()))
+ end,
+ }
+
+end
+
+-- The (delayed and immediate) write operations are emulated in \LUA\ and presented
+-- as primitives at the \TEX\ end.
+
+do
+
+ local logwriter = logs.writer
+ local openfile = io.open
+ local flushio = io.flush
+ local serialize = token.serialize
+
+ local opennode = registerwhatsitnode("open")
+ local writenode = registerwhatsitnode("write")
+ local closenode = registerwhatsitnode("close")
+ local channels = { }
+ local immediate_code = tex.flagcodes.immediate
+
+ function backends.openout(n)
+ local p = nodeproperties[n]
+ if p then
+ local handle = openfile(p.filename,"wb") or false
+ if handle then
+ channels[p.channel] = handle
+ else
+ -- error
+ end
+ end
+ end
+
+ function backends.writeout(n)
+ local p = nodeproperties[n]
+ if p then
+ local handle = channels[p.channel]
+ local content = serialize(p.data)
+ if handle then
+ handle:write(content,"\n")
+ else
+ logwriter(content,"\n")
+ end
+ end
+ end
+
+ function backends.closeout(n)
+ local p = nodeproperties[n]
+ if p then
+ local channel = p.channel
+ local handle = channels[channel]
+ if handle then
+ handle:close()
+ channels[channel] = false
+ flushio()
+ else
+ -- error
+ end
+ end
+ end
+
+ local function immediately(prefix)
+ return prefix and (prefix & immediate_code) ~= 0
+ end
+
+ implement {
+ name = "openout",
+ public = true,
+ usage = "value",
+ actions = function(prefix)
+ local channel = scaninteger()
+ scankeyword("=") -- hack
+ local filename = scanstring()
+ if not immediately(prefix) then
+ local n = copynut(opennode)
+ nodeproperties[n] = { channel = channel, filename = filename } -- action = "open"
+ return context(tonode(n))
+ elseif not channels[channel] then
+ local handle = openfile(filename,"wb") or false
+ if handle then
+ channels[channel] = handle
+ else
+ -- error
+ end
+ end
+ end,
+ }
+
+ implement {
+ name = "write",
+ public = true,
+ usage = "value",
+ actions = function(prefix)
+ local channel = scaninteger()
+ if not immediately(prefix) then
+ local t = scantokenlist()
+ local n = copynut(writenode)
+ nodeproperties[n] = { channel = channel, data = t } -- action = "write"
+ return context(tonode(n))
+ else
+ local content = scanstring()
+ local handle = channels[channel]
+ if handle then
+ handle:write(content,"\n")
+ else
+ logwriter(content,"\n")
+ end
+ end
+ end,
+ }
+
+ implement {
+ name = "closeout",
+ public = true,
+ usage = "value",
+ actions = function(prefix)
+ local channel = scaninteger()
+ if not immediately(prefix) then
+ local n = copynut(closenode)
+ nodeproperties[n] = { channel = channel } -- action = "close"
+ return context(tonode(n))
+ else
+ local handle = channels[channel]
+ if handle then
+ handle:close()
+ channels[channel] = false
+ flushio()
+ else
+ -- error
+ end
+ end
+ end,
+ }
+
+ -- why ...
+
+ local open_command = get(token.create("openout"))
+ local write_command = get(token.create("write"))
+ local close_command = get(token.create("closeout"))
+
+end
+
+-- states: these get injected independent of grouping
+
+do
+
+ local setstatenode = registerwhatsitnode("setstate")
+
+ function nutpool.setstate(data)
+ local n = copynut(setstatenode)
+ nodeproperties[n] = { data = data }
+ return n
+ end
+
+end
+
+-- We don't support specials so we make them dummies.
+
+do
+ implement {
+ name = "special",
+ actions = scanstring,
+ public = true,
+ protected = true,
+ }
+end
diff --git a/tex/context/base/mkxl/node-fin.lmt b/tex/context/base/mkxl/node-fin.lmt
index dab90863a..a9180ddb2 100644
--- a/tex/context/base/mkxl/node-fin.lmt
+++ b/tex/context/base/mkxl/node-fin.lmt
@@ -36,6 +36,7 @@ local setlist = nuts.setlist
local setleader = nuts.setleader
local copy_node = nuts.copy
+local find_tail = nuts.tail
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
@@ -165,13 +166,15 @@ function states.finalize(namespace,attribute,head) -- is this one ok?
if id == hlist_code or id == vlist_code then
local content = getlist(head)
if content then
- local list = insert_node_before(content,content,copy_node(nsnone)) -- two return values
+-- local list = insert_node_before(content,content,copy_node(nsnone)) -- two return values
+ local list = insert_node_after(content,find_tail(content),copy_node(nsnone)) -- two return values
if list ~= content then
setlist(head,list)
end
end
else
- head = insert_node_before(head,head,copy_node(nsnone))
+-- head = insert_node_before(head,head,copy_node(nsnone))
+ head = insert_node_after(find_tail(head),head,copy_node(nsnone))
end
return head, true
end
@@ -295,6 +298,75 @@ states.process = function(namespace,attribute,head,default)
return process(attribute,head,default)
end
+local function simple(attribute,head)
+ local check = false
+ local leader = nil
+ for stack, id, subtype, content in nextcontent, head do
+ if id == glyph_code or id == disc_code then
+ check = true
+ elseif id == glue_code then
+ check = true
+ leader = content
+ elseif id == hlist_code or id == vlist_code then
+ if getorientation(stack) then
+ local outer = getattr(stack,attribute)
+ if outer then
+ if current ~= outer then
+ if current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ end
+ head = insert_node_before(head,stack,copy_node(nsdata[c]))
+ current = outer
+ end
+ elseif current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ current = 0
+ end
+ end
+ local list = simple(attribute,content)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ elseif id == rule_code then
+ check = has_dimensions(stack)
+ end
+ if check then
+ local c = getattr(stack,attribute)
+ if c then
+ if current ~= c then
+ if current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ end
+ head = insert_node_before(head,stack,copy_node(nsdata[c]))
+ current = c
+ end
+ if leader then
+ local savedcurrent = current
+ local ci = getid(leader)
+ if ci == hlist_code or ci == vlist_code then
+ current = 0
+ end
+ local list = simple(attribute,leader)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ current = savedcurrent
+ leader = false
+ end
+ elseif current > 0 then
+ head = insert_node_before(head,stack,copy_node(nsnone))
+ current = 0
+ end
+ check = false
+ end
+ end
+ return head
+end
+
+states.simple = function(namespace,attribute,head,default)
+ return simple(attribute,head,default)
+end
+
-- we can force a selector, e.g. document wide color spaces, saves a little
-- watch out, we need to check both the selector state (like colorspace) and
-- the main state (like color), otherwise we get into troubles when a selector
diff --git a/tex/context/base/mkxl/node-ini.lmt b/tex/context/base/mkxl/node-ini.lmt
index 0fba0a4d9..4ba4b4000 100644
--- a/tex/context/base/mkxl/node-ini.lmt
+++ b/tex/context/base/mkxl/node-ini.lmt
@@ -65,31 +65,6 @@ local function simplified(t)
return r
end
-local nodecodes = simplified(node.types())
-
-local whatcodes = allocate {
- literal = 0x1, [0x1] = "literal",
- latelua = 0x2, [0x2] = "latelua",
- userdefined = 0x3, [0x3] = "userdefined",
- savepos = 0x4, [0x4] = "savepos",
- save = 0x5, [0x5] = "save",
- restore = 0x6, [0x6] = "restore",
- setmatrix = 0x7, [0x7] = "setmatrix",
- open = 0x8, [0x8] = "open",
- close = 0x9, [0x9] = "close",
- write = 0xA, [0xA] = "write",
-}
-
-local usercodes = allocate {
- [ 97] = "attribute", -- a
- [100] = "number", -- d
- [102] = "float", -- f
- [108] = "lua", -- l
- [110] = "node", -- n
- [115] = "string", -- s
- [116] = "token" -- t
-}
-
local noadoptions = allocate {
set = 0x08,
unused_1 = 0x00 + 0x08,
@@ -102,15 +77,7 @@ local noadoptions = allocate {
right = 0x14 + 0x08,
}
-local literalvalues = allocate {
- [0] = "origin",
- [1] = "page",
- [2] = "always",
- [3] = "raw",
- [4] = "text",
- [5] = "font",
- [6] = "special",
-}
+local nodecodes = simplified(node.types())
gluecodes = allocate(swapped(gluecodes,gluecodes))
dircodes = allocate(swapped(dircodes,dircodes))
@@ -118,7 +85,6 @@ boundarycodes = allocate(swapped(boundarycodes,boundarycodes))
noadcodes = allocate(swapped(noadcodes,noadcodes))
radicalcodes = allocate(swapped(radicalcodes,radicalcodes))
nodecodes = allocate(swapped(nodecodes,nodecodes))
-whatcodes = allocate(swapped(whatcodes,whatcodes))
listcodes = allocate(swapped(listcodes,listcodes))
glyphcodes = allocate(swapped(glyphcodes,glyphcodes))
kerncodes = allocate(swapped(kerncodes,kerncodes))
@@ -129,18 +95,15 @@ accentcodes = allocate(swapped(accentcodes,accentcodes))
fencecodes = allocate(swapped(fencecodes,fencecodes))
parcodes = allocate(swapped(parcodes,parcodes))
rulecodes = allocate(swapped(rulecodes,rulecodes))
-usercodes = allocate(swapped(usercodes,usercodes))
noadoptions = allocate(swapped(noadoptions,noadoptions))
dirvalues = allocate(swapped(dirvalues,dirvalues))
-literalvalues = allocate(swapped(literalvalues,literalvalues))
fillvalues = allocate(swapped(fillvalues,fillvalues))
nodes.gluecodes = gluecodes
nodes.dircodes = dircodes
nodes.boundarycodes = boundarycodes
nodes.noadcodes = noadcodes
-nodes.whatcodes = whatcodes
nodes.listcodes = listcodes
nodes.glyphcodes = glyphcodes
nodes.kerncodes = kerncodes
@@ -152,13 +115,11 @@ nodes.radicalcodes = radicalcodes
nodes.fencecodes = fencecodes
nodes.parcodes = parcodes
nodes.rulecodes = rulecodes
-nodes.usercodes = usercodes
nodes.noadoptions = noadoptions
nodes.fillvalues = fillvalues
nodes.fillcodes = fillvalues -- for now
nodes.dirvalues = dirvalues
-nodes.literalvalues = literalvalues
nodes.nodecodes = nodecodes
@@ -167,7 +128,6 @@ local subtypes = allocate {
dir = dircodes,
boundary = boundarycodes,
noad = noadcodes,
- whatsit = whatcodes,
glyph = glyphcodes,
kern = kerncodes,
penalty = penaltycodes,
@@ -201,11 +161,9 @@ nodes.subtypes = subtypes
nodes.skipcodes = gluecodes
nodes.directioncodes = dircodes
-nodes.whatsitcodes = whatcodes
nodes.discretionarycodes = disccodes
nodes.directionvalues = dirvalues
-nodes.literalvalues = literalvalues
glyphcodes.glyph = glyphcodes.character
@@ -218,8 +176,6 @@ listcodes.column = listcodes.alignment
kerncodes.kerning = kerncodes.fontkern
kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new
-literalvalues.direct = literalvalues.always
-
nodes.noadoptions = {
set = 0x08,
unused_1 = 0x00 + 0x08,
diff --git a/tex/context/base/mkxl/node-ini.mkxl b/tex/context/base/mkxl/node-ini.mkxl
index 4de4e00b4..b3f17e041 100644
--- a/tex/context/base/mkxl/node-ini.mkxl
+++ b/tex/context/base/mkxl/node-ini.mkxl
@@ -22,6 +22,7 @@
\registerctxluafile{node-met}{autosuffix}
\registerctxluafile{node-nut}{autosuffix}
\registerctxluafile{node-res}{autosuffix}
+\registerctxluafile{node-ext}{autosuffix}
%registerctxluafile{node-ppt}{} % experimental, not used so probably useless
\registerctxluafile{node-aux}{autosuffix}
\registerctxluafile{node-gcm}{autosuffix}
@@ -33,11 +34,10 @@
\registerctxluafile{node-dir}{} % experimental, not yet (and maybe never) used
\registerctxluafile{node-pro}{autosuffix}
\registerctxluafile{node-ser}{autosuffix}
-%registerctxluafile{node-ext}{}
\registerctxluafile{node-acc}{autosuffix} % experimental
%registerctxluafile{node-prp}{} % makes no sense (yet)
\registerctxluafile{node-scn}{autosuffix}
-\registerctxluafile{node-syn}{}
+\registerctxluafile{node-syn}{autosuffix}
\registerctxluafile{node-par}{autosuffix}
%D This might go away (needs checking anyway, very old code):
diff --git a/tex/context/base/mkxl/node-res.lmt b/tex/context/base/mkxl/node-res.lmt
index 7a37b1b9e..fbb1d1fe2 100644
--- a/tex/context/base/mkxl/node-res.lmt
+++ b/tex/context/base/mkxl/node-res.lmt
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['node-res'] = {
license = "see context related readme files"
}
-local type, next = type, next
+local type, next, rawset = type, next, rawset
local gmatch, format = string.gmatch, string.format
--[[ldx--
@@ -21,7 +21,6 @@ local report_nodes = logs.reporter("nodes","housekeeping")
nodes.pool = nodes.pool or { }
local nodepool = nodes.pool
-local whatsitcodes = nodes.whatsitcodes
local gluecodes = nodes.gluecodes
local kerncodes = nodes.kerncodes
local rulecodes = nodes.rulecodes
@@ -36,7 +35,6 @@ local rule_code = nodecodes.rule
local kern_code = nodecodes.kern
local glue_code = nodecodes.glue
local gluespec_code = nodecodes.gluespec
-local whatsit_code = nodecodes.whatsit
local currentfont = font.current
local texgetcount = tex.getcount
@@ -45,25 +43,6 @@ local allocate = utilities.storage.allocate
local reserved = { }
local nofreserved = 0
-local userids = allocate()
-local lastid = 0
-
-setmetatable(userids, {
- __index = function(t,k)
- if type(k) == "string" then
- lastid = lastid + 1
- rawset(userids,lastid,k)
- rawset(userids,k,lastid)
- return lastid
- else
- rawset(userids,k,k)
- return k
- end
- end,
- __call = function(t,k)
- return t[k]
- end
-} )
-- nuts overload
@@ -149,10 +128,7 @@ local function register_node(n)
return n
end
-nodepool.userids = userids
nodepool.register = register_node
-
-nutpool.userids = userids
nutpool.register = register_node -- could be register_nut
-- so far
@@ -168,11 +144,6 @@ local glyph = register_nut(new_nut(glyph_code,0))
local textdir = register_nut(new_nut(nodecodes.dir))
-local latelua = register_nut(new_nut(whatsit_code,whatsitcodes.latelua))
-local savepos = register_nut(new_nut(whatsit_code,whatsitcodes.savepos))
-
-local user_node = new_nut(whatsit_code,whatsitcodes.userdefined)
-
local left_margin_kern = register_nut(new_nut(kern_code,kerncodes.leftmargincode))
local right_margin_kern = register_nut(new_nut(kern_code,kerncodes.rightmargincode))
@@ -414,16 +385,6 @@ function nutpool.leader(width,list)
return n
end
-function nutpool.savepos()
- return copy_nut(savepos)
-end
-
-function nutpool.latelua(code)
- local n = copy_nut(latelua)
- nodeproperties[n] = { data = code }
- return n
-end
-
function nutpool.leftmarginkern(glyph,width)
local n = copy_nut(left_margin_kern)
if not glyph then
diff --git a/tex/context/base/mkxl/node-syn.lmt b/tex/context/base/mkxl/node-syn.lmt
new file mode 100644
index 000000000..ce5f0d2dd
--- /dev/null
+++ b/tex/context/base/mkxl/node-syn.lmt
@@ -0,0 +1,782 @@
+if not modules then modules = { } end modules ['node-syn'] = {
+ 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"
+}
+
+-- Because we have these fields in some node that are used by synctex, and because
+-- some users seem to like that feature, I decided to implement a variant that might
+-- work out better for ConTeXt. This is experimental code. I don't use it myself so
+-- it will take a while to mature. There will be some helpers that one can use in
+-- more complex situations like included xml files. Currently (somewhere else) we
+-- take care of valid files, that is: we prohibit access to files in the tree
+-- because we don't want users to mess up styles.
+--
+-- It is unclear how the output gets interpreted but by reverse engineering (and
+-- stripping) the file generated by generic synctex, I got there eventually. For
+-- instance, we only need to be able to go back to a place where text is entered,
+-- but still we need all that redundant box wrapping. Anyway, I was able to get a
+-- minimal output and cross my fingers that the parser used in editors is not
+-- changed in fundamental ways.
+--
+-- I only tested SumatraPDF with SciTE, for which one needs to configure in the
+-- viewer:
+--
+-- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $
+--
+-- In fact, a way more powerful implementation would have been not to add a library
+-- to a viewer, but letthe viewer call an external program:
+--
+-- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $
+--
+-- which would (re)launch the editor in the right spot. That way we can really
+-- tune well to the macro package used and also avoid the fuzzy heuristics of
+-- the library.
+--
+-- Unfortunately syntex always removes the files at the end and not at the start
+-- (this happens in synctexterminate) so we need to work around that by using an
+-- intermediate file. This is no big deal in context (which has a runner) but
+-- definitely not nice.
+--
+-- The visualizer code is only needed for testing so we don't use fancy colors or
+-- provide more detail. After all we're only interested in rendered source text
+-- anyway. We try to play safe which sometimes means that we'd better no go
+-- somewhere than go someplace wrong.
+--
+-- A previous version had a mode for exporting boxes and such but I removed that
+-- as it made no sense. Also, collecting output in a table was not faster than
+-- directly piping to the file, probably because the amount is not that large. We
+-- keep some left-overs commented.
+--
+-- A significate reduction in file size can be realized when reusing the same
+-- values. Actually that triggered the current approach in ConTeXt. In the latest
+-- synctex parser vertical positions can be repeated by an "=" sign but for some
+-- reason only for that field. It's probably trivial to do that for all of "w h d v
+-- h" but it currently not the case so I'll delay that till all are supported. (We
+-- could benefit a lot from such a repetition scheme but not much from a "v" alone
+-- which -alas- indicates that synctex is still mostly a latex targeted story.)
+--
+-- It's kind of hard to fight the parser because it really wants to go to some file
+-- but maybe some day I can figure it out. Some untagged text (in the pdf) somehow
+-- gets seen as part of the last box. Anonymous content is simply not part of the
+-- concept. Using a dummy name doesn't help either as the editor gets a signal to
+-- open that dummy. Even an empty filename doesn't work.
+--
+-- We output really simple and compact code, like:
+--
+-- SyncTeX Version:1
+-- Input:1:e:/tmp/oeps.tex
+-- Input:2:c:/data/develop/context/sources/klein.tex
+-- Output:pdf
+-- Magnification:1000
+-- Unit:1
+-- X Offset:0
+-- Y Offset:0
+-- Content:
+-- !160
+-- {1
+-- h0,0:0,0,0,0,0
+-- v0,0:0,55380990:39158276,55380990,0
+-- h2,1:4661756,9176901:27969941,655360,327680
+-- h2,2:4661756,10125967:26048041,655360,327680
+-- h2,3:30962888,10125967:1668809,655360,327680
+-- h2,3:4661756,11075033:23142527,655360,327680
+-- h2,4:28046650,11075033:4585047,655360,327680
+-- h2,4:4661756,12024099:22913954,655360,327680
+-- h2,5:27908377,12024099:4723320,655360,327680
+-- h2,5:4661756,12973165:22918783,655360,327680
+-- h2,6:27884864,12973165:4746833,655360,327680
+-- h2,6:4661756,13922231:18320732,655360,327680
+-- ]
+-- !533
+-- }1
+-- Input:3:c:/data/develop/context/sources/ward.tex
+-- !57
+-- {2
+-- h0,0:0,0,0,0,0
+-- v0,0:0,55380990:39158276,55380990,0
+-- h3,1:4661756,9176901:18813145,655360,327680
+-- h3,2:23713999,9176901:8917698,655360,327680
+-- h3,2:4661756,10125967:10512978,655360,327680
+-- h3,3:15457206,10125967:17174491,655360,327680
+-- h3,3:4661756,11075033:3571223,655360,327680
+-- h3,4:8459505,11075033:19885281,655360,327680
+-- h3,5:28571312,11075033:4060385,655360,327680
+-- h3,5:4661756,12024099:15344870,655360,327680
+-- ]
+-- !441
+-- }2
+-- !8
+-- Postamble:
+-- Count:22
+-- !23
+-- Post scriptum:
+--
+-- But for some reason, when the pdf file has some extra content (like page numbers)
+-- the main document is consulted. Bah. It would be nice to have a mode for *only*
+-- looking at marked areas. It somehow works not but maybe depends on the parser.
+--
+-- Supporting reuseable objects makes not much sense as these are often graphics or
+-- ornamental. They can not have hyperlinks etc (at least not without some hackery
+-- which I'm not willing to do) so basically they are sort of useless for text.
+--
+-- Some generic (more clever code) has been removed as I don't see things change
+-- that much.
+
+local type, rawset = type, rawset
+local concat = table.concat
+local formatters = string.formatters
+local replacesuffix, suffixonly, nameonly = file.replacesuffix, file.suffix, file.nameonly
+local openfile, renamefile, removefile = io.open, os.rename, os.remove
+
+local report_system = logs.reporter("system")
+
+local tex = tex
+local texget = tex.get
+
+local nuts = nodes.nuts
+
+local getid = nuts.getid
+local getlist = nuts.getlist
+local setlist = nuts.setlist
+local getnext = nuts.getnext
+local getwhd = nuts.getwhd
+local getwidth = nuts.getwidth
+local getsubtype = nuts.getsubtype
+
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
+
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local kern_code = nodecodes.kern
+----- rule_code = nodecodes.rule
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local dir_code = nodecodes.dir
+local fontkern_code = kerncodes.fontkern
+
+local cancel_code = nodes.dircodes.cancel
+
+local insert_before = nuts.insert_before
+local insert_after = nuts.insert_after
+
+local nodepool = nuts.pool
+local new_latelua = nodepool.latelua
+local new_rule = nodepool.rule
+local new_kern = nodepool.kern
+
+local getdimensions = nuts.dimensions
+local getrangedimensions = nuts.rangedimensions
+
+local getsynctexfields = nuts.getsynctexfields or nuts.get_synctex_fields
+local forcesynctextag = tex.forcesynctextag or tex.force_synctex_tag
+local forcesynctexline = tex.forcesynctexline or tex.force_synctex_line
+local getsynctexline = tex.getsynctexline or tex.get_synctex_line
+local setsynctexmode = tex.setsynctexmode or tex.set_synctex_mode
+
+local foundintree = resolvers.foundintree
+
+local getpagedimensions = layouts.getpagedimensions
+
+local eol = "\010"
+
+----- f_glue = formatters["g%i,%i:%i,%i\010"]
+----- f_glyph = formatters["x%i,%i:%i,%i\010"]
+----- f_kern = formatters["k%i,%i:%i,%i:%i\010"]
+----- f_rule = formatters["r%i,%i:%i,%i:%i,%i,%i\010"]
+----- f_form = formatters["f%i,%i,%i\010"]
+local z_hlist = "[0,0:0,0:0,0,0\010"
+local z_vlist = "(0,0:0,0:0,0,0\010"
+----- z_xform = "<0,0:0,0,0\010" -- or so
+local s_hlist = "]\010"
+local s_vlist = ")\010"
+----- s_xform = ">\010"
+local f_hlist_1 = formatters["h%i,%i:%i,%i:%i,%i,%i\010"]
+local f_hlist_2 = formatters["h%i,%i:%i,%s:%i,%i,%i\010"]
+local f_vlist_1 = formatters["v%i,%i:%i,%i:%i,%i,%i\010"]
+local f_vlist_2 = formatters["v%i,%i:%i,%s:%i,%i,%i\010"]
+
+local synctex = luatex.synctex or { }
+luatex.synctex = synctex
+
+local getpos ; getpos = function() getpos = job.positions.getpos return getpos() end
+
+-- status stuff
+
+local enabled = false
+local paused = 0
+local used = false
+local never = false
+
+-- the file name stuff
+
+local noftags = 0
+local stnums = { }
+local nofblocked = 0
+local blockedfilenames = { }
+local blockedsuffixes = {
+ mkii = true,
+ mkiv = true,
+ mkvi = true,
+ mkxl = true,
+ mklx = true,
+ mkix = true,
+ mkxi = true,
+ -- lfg = true,
+}
+
+local sttags = table.setmetatableindex(function(t,name)
+ if blockedsuffixes[suffixonly(name)] then
+ -- Just so that I don't get the ones on my development tree.
+ nofblocked = nofblocked + 1
+ return 0
+ elseif blockedfilenames[nameonly(name)] then
+ -- So we can block specific files.
+ nofblocked = nofblocked + 1
+ return 0
+ elseif foundintree(name) then
+ -- One shouldn't edit styles etc this way.
+ nofblocked = nofblocked + 1
+ return 0
+ else
+ noftags = noftags + 1
+ t[name] = noftags
+ stnums[noftags] = name
+ return noftags
+ end
+end)
+
+function synctex.blockfilename(name)
+ blockedfilenames[nameonly(name)] = name
+end
+
+function synctex.setfilename(name,line)
+ if paused == 0 and name then
+ forcesynctextag(sttags[name])
+ if line then
+ forcesynctexline(line)
+ end
+ end
+end
+
+function synctex.resetfilename()
+ if paused == 0 then
+ forcesynctextag(0)
+ forcesynctexline(0)
+ end
+end
+
+do
+
+ local nesting = 0
+ local ignored = false
+
+ function synctex.pushline()
+ nesting = nesting + 1
+ if nesting == 1 then
+ local l = getsynctexline()
+ ignored = l and l > 0
+ if not ignored then
+ forcesynctexline(texget("inputlineno"))
+ end
+ end
+ end
+
+ function synctex.popline()
+ if nesting == 1 then
+ if not ignored then
+ forcesynctexline()
+ ignored = false
+ end
+ end
+ nesting = nesting - 1
+ end
+
+end
+
+-- the node stuff
+
+local filehandle = nil
+local nofsheets = 0
+local nofobjects = 0
+local last = 0
+local filesdone = 0
+local tmpfile = false
+local logfile = false
+
+local function writeanchor()
+ local size = filehandle:seek("end")
+ filehandle:write("!",size-last,eol)
+ last = size
+end
+
+local function writefiles()
+ local total = #stnums
+ if filesdone < total then
+ for i=filesdone+1,total do
+ filehandle:write("Input:",i,":",stnums[i],eol)
+ end
+ filesdone = total
+ end
+end
+
+local function makenames()
+ logfile = replacesuffix(tex.jobname,"synctex")
+ tmpfile = replacesuffix(logfile,"syncctx")
+end
+
+local function flushpreamble()
+ makenames()
+ filehandle = openfile(tmpfile,"wb")
+ if filehandle then
+ filehandle:write("SyncTeX Version:1",eol)
+ writefiles()
+ filehandle:write("Output:pdf",eol)
+ filehandle:write("Magnification:1000",eol)
+ filehandle:write("Unit:1",eol)
+ filehandle:write("X Offset:0",eol)
+ filehandle:write("Y Offset:0",eol)
+ filehandle:write("Content:",eol)
+ flushpreamble = function()
+ writefiles()
+ return filehandle
+ end
+ else
+ enabled = false
+ end
+ return filehandle
+end
+
+function synctex.wrapup()
+ if tmpfile then
+ renamefile(tmpfile,logfile)
+ tmpfile = nil
+ end
+end
+
+local function flushpostamble()
+ if not filehandle then
+ return
+ end
+ writeanchor()
+ filehandle:write("Postamble:",eol)
+ filehandle:write("Count:",nofobjects,eol)
+ writeanchor()
+ filehandle:write("Post scriptum:",eol)
+ filehandle:close()
+ enabled = false
+end
+
+local x_hlist do
+
+ local function doaction_1(t,l,w,h,d)
+ local pagewidth, pageheight = getpagedimensions()
+ local x, y = getpos()
+ filehandle:write(f_hlist_1(t,l,x,pageheight-y,w,h,d))
+ nofobjects = nofobjects + 1
+ end
+
+ local lasty = false
+
+ local function doaction_2(t,l,w,h,d)
+ local pagewidth, pageheight = getpagedimensions()
+ local x, y = getpos()
+ y = pageheight - y
+ filehandle:write(f_hlist_2(t,l,x,y == lasty and "=" or y,w,h,d))
+ lasty = y
+ nofobjects = nofobjects + 1
+ end
+
+ local doaction = doaction_1
+
+ x_hlist = function(head,current,t,l,w,h,d)
+ if filehandle then
+ return insert_before(head,current,new_latelua(function() doaction(t,l,w,h,d) end))
+ else
+ return head
+ end
+ end
+
+ directives.register("system.synctex.compression", function(v)
+ doaction = tonumber(v) == 2 and doaction_2 or doaction_1
+ end)
+
+end
+
+-- color is already handled so no colors
+
+local collect = nil
+local fulltrace = false
+local trace = false
+local height = 10 * 65536
+local depth = 5 * 65536
+local traceheight = 32768
+local tracedepth = 32768
+
+trackers.register("system.synctex.visualize", function(v)
+ trace = v
+ fulltrace = v == "real"
+end)
+
+local function inject(head,first,last,tag,line)
+ local w, h, d = getdimensions(first,getnext(last))
+ if h < height then
+ h = height
+ end
+ if d < depth then
+ d = depth
+ end
+ if trace then
+ head = insert_before(head,first,new_rule(w,fulltrace and h or traceheight,fulltrace and d or tracedepth))
+ head = insert_before(head,first,new_kern(-w))
+ end
+ head = x_hlist(head,first,tag,line,w,h,d)
+ return head
+end
+
+local function collect_min(head)
+ local current = head
+ while current do
+ local id = getid(current)
+ if id == glyph_code then
+ local first = current
+ local last = current
+ local tag = 0
+ local line = 0
+ while true do
+ if id == glyph_code then
+ local tc, lc = getsynctexfields(current)
+ if tc and tc > 0 then
+ tag = tc
+ line = lc
+ end
+ last = current
+ elseif id == disc_code or (id == kern_code and getsubtype(current) == fontkern_code) then
+ last = current
+ else
+ if tag > 0 then
+ head = inject(head,first,last,tag,line)
+ end
+ break
+ end
+ current = getnext(current)
+ if current then
+ id = getid(current)
+ else
+ if tag > 0 then
+ head = inject(head,first,last,tag,line)
+ end
+ return head
+ end
+ end
+ end
+ -- pick up (as id can have changed)
+ if id == hlist_code or id == vlist_code then
+ local list = getlist(current)
+ if list then
+ local l = collect(list)
+ if l ~= list then
+ setlist(current,l)
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ return head
+end
+
+local function inject(parent,head,first,last,tag,line)
+ local w, h, d = getrangedimensions(parent,first,getnext(last))
+ if h < height then
+ h = height
+ end
+ if d < depth then
+ d = depth
+ end
+ if trace then
+ head = insert_before(head,first,new_rule(w,fulltrace and h or traceheight,fulltrace and d or tracedepth))
+ head = insert_before(head,first,new_kern(-w))
+ end
+ head = x_hlist(head,first,tag,line,w,h,d)
+ return head
+end
+
+local function collect_max(head,parent)
+ local current = head
+ while current do
+ local id = getid(current)
+ if id == glyph_code then
+ local first = current
+ local last = current
+ local tag = 0
+ local line = 0
+ while true do
+ if id == glyph_code then
+ local tc, lc = getsynctexfields(current)
+ if tc and tc > 0 then
+ if tag > 0 and (tag ~= tc or line ~= lc) then
+ head = inject(parent,head,first,last,tag,line)
+ first = current
+ end
+ tag = tc
+ line = lc
+ last = current
+ else
+ if tag > 0 then
+ head = inject(parent,head,first,last,tag,line)
+ tag = 0
+ end
+ first = nil
+ last = nil
+ end
+ elseif id == disc_code then
+ if not first then
+ first = current
+ end
+ last = current
+ elseif id == kern_code and getsubtype(current) == fontkern_code then
+ if first then
+ last = current
+ end
+ elseif id == glue_code then
+ if tag > 0 then
+ local tc, lc = getsynctexfields(current)
+ if tc and tc > 0 then
+ if tag ~= tc or line ~= lc then
+ head = inject(parent,head,first,last,tag,line)
+ tag = 0
+ break
+ end
+ else
+ head = inject(parent,head,first,last,tag,line)
+ tag = 0
+ break
+ end
+ else
+ tag = 0
+ break
+ end
+ id = nil -- so no test later on
+ elseif id == penalty_code then
+ -- go on (and be nice for math)
+ else
+ if tag > 0 then
+ head = inject(parent,head,first,last,tag,line)
+ tag = 0
+ end
+ break
+ end
+ current = getnext(current)
+ if current then
+ id = getid(current)
+ else
+ if tag > 0 then
+ head = inject(parent,head,first,last,tag,line)
+ end
+ return head
+ end
+ end
+ end
+ -- pick up (as id can have changed)
+ if id == hlist_code or id == vlist_code then
+ local list = getlist(current)
+ if list then
+ local l = collect(list,current)
+ if l and l ~= list then
+ setlist(current,l)
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ return head
+end
+
+collect = collect_max
+
+function synctex.collect(head,where)
+ if enabled and where ~= "object" then
+ return collect(head,head)
+ else
+ return head
+ end
+end
+
+-- also no solution for bad first file resolving in sumatra
+
+function synctex.start()
+ if enabled then
+ nofsheets = nofsheets + 1 -- could be realpageno
+ if flushpreamble() then
+ writeanchor()
+ filehandle:write("{",nofsheets,eol)
+ -- this seems to work:
+ local pagewidth, pageheight = getpagedimensions()
+ filehandle:write(z_hlist)
+ filehandle:write(f_vlist_1(0,0,0,pageheight,pagewidth,pageheight,0))
+ end
+ end
+end
+
+function synctex.stop()
+ if enabled then
+ -- filehandle:write(s_vlist,s_hlist)
+ filehandle:write(s_hlist)
+ writeanchor()
+ filehandle:write("}",nofsheets,eol)
+ nofobjects = nofobjects + 2
+ end
+end
+
+local enablers = { }
+local disablers = { }
+
+function synctex.registerenabler(f)
+ enablers[#enablers+1] = f
+end
+
+function synctex.registerdisabler(f)
+ disablers[#disablers+1] = f
+end
+
+function synctex.enable()
+ if not never and not enabled then
+ enabled = true
+ setsynctexmode(3) -- we want details
+ if not used then
+ nodes.tasks.enableaction("shipouts","luatex.synctex.collect")
+ report_system("synctex functionality is enabled, expect 5-10 pct runtime overhead!")
+ used = true
+ end
+ for i=1,#enablers do
+ enablers[i](true)
+ end
+ end
+end
+
+function synctex.disable()
+ if enabled then
+ setsynctexmode(0)
+ report_system("synctex functionality is disabled!")
+ enabled = false
+ for i=1,#disablers do
+ disablers[i](false)
+ end
+ end
+end
+
+function synctex.finish()
+ if enabled then
+ flushpostamble()
+ else
+ makenames()
+ removefile(logfile)
+ removefile(tmpfile)
+ end
+end
+
+local filename = nil
+
+function synctex.pause()
+ paused = paused + 1
+ if enabled and paused == 1 then
+ setsynctexmode(0)
+ end
+end
+
+function synctex.resume()
+ if enabled and paused == 1 then
+ setsynctexmode(3)
+ end
+ paused = paused - 1
+end
+
+-- not the best place
+
+luatex.registerstopactions(synctex.finish)
+
+statistics.register("synctex tracing",function()
+ if used then
+ return string.format("%i referenced files, %i files ignored, %i objects flushed, logfile: %s",
+ noftags,nofblocked,nofobjects,logfile)
+ end
+end)
+
+local implement = interfaces.implement
+local variables = interfaces.variables
+
+function synctex.setup(t)
+ if t.state == variables.never then
+ synctex.disable() -- just in case
+ never = true
+ return
+ end
+ if t.method == variables.max then
+ collect = collect_max
+ else
+ collect = collect_min
+ end
+ if t.state == variables.start then
+ synctex.enable()
+ else
+ synctex.disable()
+ end
+end
+
+implement {
+ name = "synctexblockfilename",
+ arguments = "string",
+ actions = synctex.blockfilename,
+}
+
+implement {
+ name = "synctexsetfilename",
+ arguments = "string",
+ actions = synctex.setfilename,
+}
+
+implement {
+ name = "synctexresetfilename",
+ actions = synctex.resetfilename,
+}
+
+implement {
+ name = "setupsynctex",
+ actions = synctex.setup,
+ arguments = {
+ {
+ { "state" },
+ { "method" },
+ },
+ },
+}
+
+implement {
+ name = "synctexpause",
+ actions = synctex.pause,
+}
+
+implement {
+ name = "synctexresume",
+ actions = synctex.resume,
+}
+
+implement {
+ name = "synctexpushline",
+ actions = synctex.pushline,
+}
+
+implement {
+ name = "synctexpopline",
+ actions = synctex.popline,
+}
+
+implement {
+ name = "synctexdisable",
+ actions = synctex.disable,
+}
diff --git a/tex/context/base/mkxl/node-tra.lmt b/tex/context/base/mkxl/node-tra.lmt
index da3cb1d33..6060522be 100644
--- a/tex/context/base/mkxl/node-tra.lmt
+++ b/tex/context/base/mkxl/node-tra.lmt
@@ -704,7 +704,7 @@ table.setmetatableindex(nodestracerpool,function(t,k,v)
return v
end)
-function nutstracerpool.rule(w,h,d,c,s) -- so some day we can consider using literals (speedup)
+function nutstracerpool.rule(w,h,d,c,s)
return setproperties(new_rule(w,h,d),c,s)
end
diff --git a/tex/context/base/mkxl/page-lin.lmt b/tex/context/base/mkxl/page-lin.lmt
index 9ea502899..f50031ab3 100644
--- a/tex/context/base/mkxl/page-lin.lmt
+++ b/tex/context/base/mkxl/page-lin.lmt
@@ -192,7 +192,7 @@ local function resolve(n,m) -- we can now check the 'line' flag (todo)
if content then
if id == hlist_code then
for current, subtype in nextwhatsit, content do
- if subtype == latelua_code then
+ if subtype == latelua_code then -- this has to change!
local a = getattr(current,a_linereference)
if a then
cross_references[a] = m
diff --git a/tex/context/base/mkxl/scrn-pag.lmt b/tex/context/base/mkxl/scrn-pag.lmt
new file mode 100644
index 000000000..210a57707
--- /dev/null
+++ b/tex/context/base/mkxl/scrn-pag.lmt
@@ -0,0 +1,56 @@
+if not modules then modules = { } end modules ['scrn-pag'] = {
+ version = 1.001,
+ comment = "companion to scrn-pag.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+interactions = interactions or { }
+interactions.pages = interactions.pages or { }
+local pages = interactions.pages
+
+local implement = interfaces.implement
+
+pages.setupcanvas = layouts.setupcanvas
+
+local codeinjections = backends.codeinjections
+
+function pages.setpagetransition(specification)
+ codeinjections.setpagetransition(specification)
+end
+
+implement {
+ name = "setupcanvas",
+ actions = pages.setupcanvas,
+ arguments = {
+ {
+ { "mode" },
+ { "singlesided", "boolean" },
+ { "doublesided", "boolean" },
+ { "leftoffset", "dimen" },
+ { "topoffset", "dimen" },
+ { "width", "dimen" },
+ { "height", "dimen" },
+ { "paperwidth", "dimen" },
+ { "paperheight", "dimen" },
+ { "cropoffset", "dimen" },
+ { "bleedoffset", "dimen" },
+ { "artoffset", "dimen" },
+ { "trimoffset", "dimen" },
+ { "copies", "integer" },
+ { "print", "string" }, -- , tohash
+ }
+ }
+}
+
+implement {
+ name = "setpagetransition",
+ actions = pages.setpagetransition,
+ arguments = {
+ {
+ { "n" },
+ { "delay", "integer" },
+ }
+ }
+}
diff --git a/tex/context/base/mkxl/scrn-pag.mklx b/tex/context/base/mkxl/scrn-pag.mklx
index 80e16f63d..67e24178e 100644
--- a/tex/context/base/mkxl/scrn-pag.mklx
+++ b/tex/context/base/mkxl/scrn-pag.mklx
@@ -15,7 +15,7 @@
\writestatus{loading}{ConTeXt Screen Macros / Pages}
-\registerctxluafile{scrn-pag}{}
+\registerctxluafile{scrn-pag}{autosuffix}
\unprotect
diff --git a/tex/context/base/mkxl/spac-hor.mkxl b/tex/context/base/mkxl/spac-hor.mkxl
index 426580c7d..13d1f9021 100644
--- a/tex/context/base/mkxl/spac-hor.mkxl
+++ b/tex/context/base/mkxl/spac-hor.mkxl
@@ -677,6 +677,29 @@
\newskip \s_spac_narrower_right_last
\newconditional\s_spac_narrower_last_swap
+% \def\spac_narrower_start_apply#1%
+% {\narrowerparameter\c!before
+% \global\s_spac_narrower_left \zeropoint
+% \global\s_spac_narrower_right \zeropoint
+% \global\s_spac_narrower_middle\zeropoint
+% \edef\askednarrower{#1}%
+% \ifx\askednarrower\v!reverse
+% \ifconditional\s_spac_narrower_last_swap
+% \leftskip \s_spac_narrower_right_last
+% \rightskip\s_spac_narrower_left_last
+% \setfalse\s_spac_narrower_last_swap
+% \else
+% \leftskip \s_spac_narrower_left_last
+% \rightskip\s_spac_narrower_right_last
+% \settrue\s_spac_narrower_last_swap
+% \fi
+% \else
+% \normalexpanded{\processcommalistwithparameters[\askednarrower]}\spac_narrower_initialize
+% \advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
+% \advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
+% \fi
+% \seteffectivehsize}
+
\def\spac_narrower_start_apply#1%
{\narrowerparameter\c!before
\global\s_spac_narrower_left \zeropoint
@@ -685,18 +708,18 @@
\edef\askednarrower{#1}%
\ifx\askednarrower\v!reverse
\ifconditional\s_spac_narrower_last_swap
- \leftskip \s_spac_narrower_right_last
- \rightskip\s_spac_narrower_left_last
+ \frozen\leftskip \s_spac_narrower_right_last
+ \frozen\rightskip\s_spac_narrower_left_last
\setfalse\s_spac_narrower_last_swap
\else
- \leftskip \s_spac_narrower_left_last
- \rightskip\s_spac_narrower_right_last
+ \frozen\leftskip \s_spac_narrower_left_last
+ \frozen\rightskip\s_spac_narrower_right_last
\settrue\s_spac_narrower_last_swap
\fi
\else
\normalexpanded{\processcommalistwithparameters[\askednarrower]}\spac_narrower_initialize
- \advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
- \advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
+ \frozen\advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
+ \frozen\advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
\fi
\seteffectivehsize}
diff --git a/tex/context/base/mkxl/strc-reg.mkxl b/tex/context/base/mkxl/strc-reg.mkxl
index af98ca481..dcfdd0946 100644
--- a/tex/context/base/mkxl/strc-reg.mkxl
+++ b/tex/context/base/mkxl/strc-reg.mkxl
@@ -40,6 +40,20 @@
% \index[pageclass::] {textclass::entry}
% \index[pageclass::key]{textclass::entry}
+% nice example:
+%
+% \setupregister[index]
+% [n=1,
+% pageleft=\hfilll,
+% pageright=\frozen\parfillleftskip 0pt plus 1fill\frozen\parfillrightskip 0pt\par]
+%
+% \starttext
+%
+% {\showmakeup \placeindex \page}
+%
+% % \dorecurse{10}{\dontleavehmode \index{AAA}\page}
+% \dorecurse{100}{\dontleavehmode\index{AAA}\page}
+
% tzt variant with n entries, parameters and userdata (altnum)
\installcorenamespace{register}
diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt
index 8c04a0372..6e9bd8e8c 100644
--- a/tex/context/base/mkxl/trac-vis.lmt
+++ b/tex/context/base/mkxl/trac-vis.lmt
@@ -595,17 +595,28 @@ local whatsit do
local w_cache = caches["whatsit"]
local tags = {
- open = "OPN",
- write = "WRI",
- close = "CLS",
- special = "SPE",
- latelua = "LUA",
- savepos = "POS",
- userdefined = "USR",
- literal = "LIT",
- setmatrix = "MAT",
- save = "SAV",
- restore = "RES",
+ [whatsitcodes.open] = "OPN",
+ [whatsitcodes.write] = "WRI",
+ [whatsitcodes.close] = "CLS",
+ -- [whatsitcodes.special] = "SPE",
+ [whatsitcodes.latelua] = "LUA",
+ [whatsitcodes.savepos] = "POS",
+ [whatsitcodes.userdefined] = "USR",
+ [whatsitcodes.literal] = "LIT",
+ [whatsitcodes.setmatrix] = "MAT",
+ [whatsitcodes.save] = "SAV",
+ [whatsitcodes.restore] = "RES",
+ [whatsitcodes.startscaling] = "+SCA",
+ [whatsitcodes.stopscaling] = "-SCA",
+ [whatsitcodes.startrotation] = "+ROT",
+ [whatsitcodes.stoprotation] = "-ROT",
+ [whatsitcodes.startmirroring] = "+MIR",
+ [whatsitcodes.stopmirroring] = "-MIR",
+ [whatsitcodes.startclipping] = "+CLP",
+ [whatsitcodes.stopclipping] = "-CLP",
+ [whatsitcodes.startmatrix] = "+MAT",
+ [whatsitcodes.stopmatrix] = "-MAT",
+ [whatsitcodes.setstate] = "SET", -- can't happen because these are added after visualizing
}
whatsit = function(head,current)
@@ -614,7 +625,7 @@ local whatsit do
if info then
-- print("hit whatsit")
else
- info = sometext(formatters["W:%s"](what),usedfont,nil,c_white)
+ info = sometext(formatters["W:%s"](tags[what] or what),usedfont,nil,c_white)
setattr(info,a_layer,l_whatsit)
w_cache[what] = info
end
@@ -880,20 +891,13 @@ local ruledglyph do
setboth(current)
local linewidth = emwidth/(2*fraction)
local x_offset, y_offset, l_margin, r_margin, raise = getoffsets(current)
- wd = wd - l_margin - r_margin
- local info = (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
+ local info = setlink((dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
line = linewidth,
type = "box",
- }
- if l_margin == 0 then
- info = setlink(info,new_kern(-wd))
- else
- info = setlink(new_kern(-l_margin),info,new_kern(-wd+l_margin))
- end
- --
+ },new_kern(-wd))
local c, f = isglyph(current)
local char = chardata[f][c]
if char and type(char.unicode) == "table" then -- hackery test
@@ -1409,7 +1413,7 @@ do
trace_marginkern = band(a,0x100000) ~= 0
trace_mathlistkern = band(a,0x200000) ~= 0
trace_dir = band(a,0x400000) ~= 0
- trace_whatsit = band(a,0x800000) ~= 0
+ trace_par = band(a,0x800000) ~= 0
end
elseif a == unsetvalue then
goto list
diff --git a/tex/context/base/mkxl/typo-cap.lmt b/tex/context/base/mkxl/typo-cap.lmt
index dbf6950c8..67acb2535 100644
--- a/tex/context/base/mkxl/typo-cap.lmt
+++ b/tex/context/base/mkxl/typo-cap.lmt
@@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['typo-cap'] = {
local next, type, tonumber = next, type, tonumber
local format, insert = string.format, table.insert
-local div, getrandom = math.div, utilities.randomizer.get
+local div, getrandom, random = math.div, utilities.randomizer.get, math.random
local trace_casing = false trackers.register("typesetters.casing", function(v) trace_casing = v end)
@@ -435,3 +435,24 @@ interfaces.implement {
actions = cases.set,
arguments = { "argument" }
}
+
+-- An example of a special plug, see type-imp-punk for usage.
+
+cases.register("randomvariant", function(start)
+ local char, fnt = isglyph(start)
+ local data = fontchar[fnt][char]
+ if data then
+ local variants = data.variants
+ if variants then
+ local n = #variants
+ local i = getrandom("variant",1,n+1)
+ if i > n then
+ -- we keep the original
+ else
+ setchar(start,variants[i])
+ end
+ return start, true
+ end
+ end
+ return start, false
+end)
diff --git a/tex/context/fonts/mkiv/bonum-math.lfg b/tex/context/fonts/mkiv/bonum-math.lfg
index 8dfa63405..51ca2d7f1 100644
--- a/tex/context/fonts/mkiv/bonum-math.lfg
+++ b/tex/context/fonts/mkiv/bonum-math.lfg
@@ -1,5 +1,8 @@
-local kern_200 = { bottomright = { { kern = -200 } } }
-local kern_100 = { bottomright = { { kern = -100 } } }
+local kern_V = { bottomright = { { kern = -200 } } }
+local kern_W = { bottomright = { { kern = -100 } } }
+local offset_f = { xoffset = "llx" }
+
+-- Beware of updates in ssty slots!
return {
name = "bonum-math",
@@ -10,12 +13,21 @@ return {
mathematics = {
dimensions = {
default = {
- [0x1D453] = { xoffset = "llx" },-- ð‘“
+ -- [0x1D453] = offset_f, -- ð‘“
+ -- ["1:0x1D453"] = offset_f, -- needed for compact
+ -- ["2:0x1D453"] = offset_f, -- needed for compact
+ ["*:0x1D453"] = offset_f, -- ð‘“
},
},
kerns = {
- [0x1D449] = kern_200, -- ð‘‰
- [0x1D44A] = kern_100, -- ð‘Š
+ -- [0x1D449] = kern_V, -- ð‘‰
+ -- ["1:0x1D449"] = kern_V, -- needed for compact
+ -- ["2:0x1D449"] = kern_V, -- needed for compact
+ -- [0x1D44A] = kern_W, -- ð‘Š
+ -- ["1:0x1D44A"] = kern_W, -- needed for compact
+ -- ["2:0x1D44A"] = kern_W, -- needed for compact
+ ["*:0x1D449"] = kern_V, -- ð‘‰
+ ["*:0x1D44A"] = kern_W, -- ð‘Š
},
alternates = {
dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" },
diff --git a/tex/context/fonts/mkiv/dejavu-math.lfg b/tex/context/fonts/mkiv/dejavu-math.lfg
index d28c69060..608b396f8 100644
--- a/tex/context/fonts/mkiv/dejavu-math.lfg
+++ b/tex/context/fonts/mkiv/dejavu-math.lfg
@@ -1,4 +1,7 @@
-local kern_250 = { bottomright = { { kern = -250 } } }
+local kern_V = { bottomright = { { kern = -250 } } }
+local kern_W = kern_W
+
+-- Beware of updates in ssty slots!
return {
name = "dejavu-math",
@@ -8,8 +11,14 @@ return {
copyright = "ConTeXt development team",
mathematics = {
kerns = {
- [0x1D449] = kern_250, --
- [0x1D44A] = kern_250, -- ð‘Š
+ -- [0x1D449] = kern_V, -- ð‘‰
+ -- ["1:0x1D449"] = kern_V, -- needed for compact
+ -- ["2:0x1D449"] = kern_V, -- needed for compact
+ -- [0x1D44A] = kern_W, -- ð‘Š
+ -- ["1:0x1D44A"] = kern_W, -- needed for compact
+ -- ["2:0x1D44A"] = kern_W, -- needed for compact
+ ["*:0x1D449"] = kern_V, -- ð‘‰
+ ["*:0x1D44A"] = kern_W, -- ð‘Š
},
alternates = {
dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" },
diff --git a/tex/context/fonts/mkiv/minion-math.lfg b/tex/context/fonts/mkiv/minion-math.lfg
index a4f539ec7..863836c1c 100644
--- a/tex/context/fonts/mkiv/minion-math.lfg
+++ b/tex/context/fonts/mkiv/minion-math.lfg
@@ -1,6 +1,5 @@
-local kern_100 = { bottomright = { { kern = -100 } } }
-local kern_150 = { bottomright = { { kern = -150 } } }
-local kern_200 = { bottomright = { { kern = -200 } } }
+local kern_W = { bottomright = { { kern = -150 } } }
+local kern_V = { bottomright = { { kern = -200 } } }
return {
name = "minion-math",
@@ -23,8 +22,9 @@ return {
},
mathematics = {
kerns = {
- [0x1D449] = kern_200, -- ð‘‰
- [0x1D44A] = kern_150, -- ð‘Š
+ [0x1D449] = kern_V, -- ð‘‰
+ [0x1D44A] = kern_W, -- ð‘Š
+ -- todo: ssty 1/2
},
},
}
diff --git a/tex/context/fonts/mkiv/pagella-math.lfg b/tex/context/fonts/mkiv/pagella-math.lfg
index c85ff3f6b..d4ae14162 100644
--- a/tex/context/fonts/mkiv/pagella-math.lfg
+++ b/tex/context/fonts/mkiv/pagella-math.lfg
@@ -1,7 +1,8 @@
-local kern_200 = { bottomright = { { kern = -200 } } }
-local kern_100 = { bottomright = { { kern = -100 } } }
+local kern_V = { bottomright = { { kern = -200 } } }
+local kern_W = { bottomright = { { kern = -100 } } }
+local offset_f = { xoffset = "llx" }
--- Beware of updates !
+-- Beware of updates in ssty slots!
return {
name = "pagella-math",
@@ -12,13 +13,22 @@ return {
mathematics = {
dimensions = {
default = {
- -- [0x1D453] = { xoffset = 162, width = 278 + 162 },-- ð‘“
- [0x1D453] = { xoffset = "llx" },-- ð‘“
+ -- [0x1D453] = { xoffset = 162, width = 278 + 162 },-- ð‘“
+ -- [0x1D453] = offset_f, -- ð‘“
+ -- ["1:0x1D453"] = offset_f, -- needed for compact
+ -- ["2:0x1D453"] = offset_f, -- needed for compact
+ ["*:0x1D453"] = offset_f, -- ð‘“
},
},
kerns = {
- [0x1D449] = kern_200, -- ð‘‰
- [0x1D44A] = kern_100, -- ð‘Š
+ -- [0x1D449] = kern_V, -- ð‘‰
+ -- ["1:0x1D449"] = kern_V, -- needed for compact
+ -- ["2:0x1D449"] = kern_V, -- needed for compact
+ -- [0x1D44A] = kern_W, -- ð‘Š
+ -- ["1:0x1D44A"] = kern_W, -- needed for compact
+ -- ["2:0x1D44A"] = kern_W, -- needed for compact
+ ["*:0x1D449"] = kern_V, -- ð‘‰
+ ["*:0x1D44A"] = kern_W, -- ð‘Š
},
alternates = {
dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" },
diff --git a/tex/context/fonts/mkiv/schola-math.lfg b/tex/context/fonts/mkiv/schola-math.lfg
index 9787c18a9..b60bc6d99 100644
--- a/tex/context/fonts/mkiv/schola-math.lfg
+++ b/tex/context/fonts/mkiv/schola-math.lfg
@@ -1,5 +1,7 @@
-local kern_200_050 = { bottomright = { { kern = -200 } }, topright = { { kern = 50 } } }
-local kern_100_050 = { bottomright = { { kern = -100 } }, topright = { { kern = 50 } } }
+local kern_V = { bottomright = { { kern = -200 } }, topright = { { kern = 50 } } }
+local kern_W = { bottomright = { { kern = -100 } }, topright = { { kern = 50 } } }
+
+-- Beware of updates in ssty slots!
return {
name = "schola-math",
@@ -9,8 +11,14 @@ return {
copyright = "ConTeXt development team",
mathematics = {
kerns = {
- [0x1D449] = kern_200_050, --
- [0x1D44A] = kern_100_050, -- ð‘Š
+ -- [0x1D449] = kern_V, -- ð‘‰
+ -- ["1:0x1D449"] = kern_V, -- needed for compact
+ -- ["2:0x1D449"] = kern_V, -- needed for compact
+ -- [0x1D44A] = kern_W, -- ð‘Š
+ -- ["1:0x1D44A"] = kern_W, -- needed for compact
+ -- ["2:0x1D44A"] = kern_W, -- needed for compact
+ ["*:0x1D449"] = kern_V, -- ð‘‰
+ ["*:0x1D44A"] = kern_W, -- ð‘Š
},
alternates = {
dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" },
diff --git a/tex/context/fonts/mkiv/termes-math.lfg b/tex/context/fonts/mkiv/termes-math.lfg
index 1501fd536..3cf8685eb 100644
--- a/tex/context/fonts/mkiv/termes-math.lfg
+++ b/tex/context/fonts/mkiv/termes-math.lfg
@@ -1,5 +1,8 @@
-local kern_200 = { bottomright = { { kern = -200 } } }
-local kern_100 = { bottomright = { { kern = -100 } } }
+local kern_V = { bottomright = { { kern = -200 } } }
+local kern_W = { bottomright = { { kern = -100 } } }
+local offset_f = { xoffset = "llx" }
+
+-- Beware of updates in ssty slots!
return {
name = "termes-math",
@@ -10,12 +13,21 @@ return {
mathematics = {
dimensions = {
default = {
- [0x1D453] = { xoffset = "llx" },-- ð‘“
+ -- [0x1D453] = offset_f, -- ð‘“
+ -- ["1:0x1D453"] = offset_f, -- needed for compact
+ -- ["2:0x1D453"] = offset_f, -- needed for compact
+ ["*:0x1D453"] = offset_f, -- ð‘“
},
},
kerns = {
- [0x1D449] = kern_200, -- ð‘‰
- [0x1D44A] = kern_100, -- ð‘Š
+ -- [0x1D449] = kern_V, -- ð‘‰
+ -- ["1:0x1D449"] = kern_V, -- needed for compact
+ -- ["2:0x1D449"] = kern_V, -- needed for compact
+ -- [0x1D44A] = kern_W, -- ð‘Š
+ -- ["1:0x1D44A"] = kern_W, -- needed for compact
+ -- ["2:0x1D44A"] = kern_W, -- needed for compact
+ ["*:0x1D449"] = kern_V, -- ð‘‰
+ ["*:0x1D44A"] = kern_W, -- ð‘Š
},
alternates = {
dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" },
diff --git a/tex/context/fonts/mkiv/type-imp-punk.mkxl b/tex/context/fonts/mkiv/type-imp-punk.mkxl
new file mode 100644
index 000000000..aa01a1d4e
--- /dev/null
+++ b/tex/context/fonts/mkiv/type-imp-punk.mkxl
@@ -0,0 +1,54 @@
+%D \module
+%D [ file=type-imp-punk,
+%D version=2020.01.17,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Punk Again,
+%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 Yet another look at punk.
+
+\ifdefined\enablerandomvariants\else
+ \useMPlibrary[punk]
+\fi
+
+\doifelse {\truefontname{Serif}} {unknown} {
+ \writestatus{fonts}{you need to load a base bodyfont first}
+ \endinput
+} {
+ % we're ok
+}
+
+\starttypescriptcollection[punk]
+
+ \definefontfeature [punk] [metapost={category=punk,preroll=punkpreroll}]
+ \definefontfeature [punkrandom] [metapost={category=punk,preroll=punkpreroll,variants=5}]
+ \definefontfeature [punkbold] [metapost={category=punk,preroll=punkpreroll,weight=2}]
+ \definefontfeature [punkslanted] [metapost={category=punk,preroll=punkpreroll,slant=.15}]
+ \definefontfeature [punkboldslanted] [metapost={category=punk,preroll=punkpreroll,slant=.15,weight=2}]
+ \definefontfeature [punkveryslanted] [metapost={category=punk,preroll=punkpreroll,slant=-.15}]
+ \definefontfeature [punksqueezed] [metapost={category=punk,preroll=punkpreroll,squeeze=.5}]
+ \definefontfeature [punkextended] [metapost={category=punk,preroll=punkpreroll,extend=1.3}]
+
+ \definefontsynonym [punkbase] [\truefontname{Serif}]
+
+ \starttypescript [\s!serif] [punk]
+ \definefontsynonym [\s!Serif] [punkbase] [\s!features=punk]
+ \definefontsynonym [\s!SerifSlanted] [punkbase] [\s!features=punkslanted]
+ \definefontsynonym [\s!SerifBold] [punkbase] [\s!features=punkbold]
+ \definefontsynonym [\s!SerifBoldSlanted][punkbase] [\s!features=punkboldslanted]
+ \definefontsynonym [\s!SerifItalic] [\s!SerifSlanted]
+ \definefontsynonym [\s!SerifBoldItalic] [\s!SerifBoldSlanted]
+ \stoptypescript
+
+ \starttypescript [punk]
+ \definetypeface [punk] [\s!rm] [\s!serif] [punk] [\s!default]
+ \stoptypescript
+
+\stoptypescriptcollection
+
diff --git a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv
index d10fe505f..72d3b3588 100644
--- a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv
@@ -247,8 +247,8 @@
\starttypescript [\s!math][times,termes][\s!all]
% \loadfontgoodies[texgyre]
% \definefontsynonym[\s!MathRoman][file:texgyre-termes-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre]
- \definefontsynonym[\s!MathRoman] [file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=termes-math]
- \definefontsynonym[\s!MathRomanBold][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,termes-math-bold,mathextra},\s!goodies=termes-math]
+ \definefontsynonym[\s!MathRoman] [file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=termes-math]
+ \definefontsynonym[\s!MathRomanBold][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,termes-math-bold,mathextra},\s!goodies=termes-math]
\stoptypescript
\stoptypescriptcollection
@@ -276,8 +276,8 @@
\starttypescript [\s!math][palatino,pagella][\s!all]
% \loadfontgoodies[texgyre]
% \definefontsynonym[\s!MathRoman][file:texgyre-pagella-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre]
- \definefontsynonym[\s!MathRoman] [file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=pagella-math]
- \definefontsynonym[\s!MathRomanBold][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,pagella-math-bold,mathextra},\s!goodies=pagella-math]
+ \definefontsynonym[\s!MathRoman] [file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=pagella-math]
+ \definefontsynonym[\s!MathRomanBold][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,pagella-math-bold,mathextra},\s!goodies=pagella-math]
\stoptypescript
\stoptypescriptcollection
@@ -289,8 +289,8 @@
\starttypescript [\s!math][bookman,bonum][\s!all]
% \loadfontgoodies[texgyre]
% \definefontsynonym[\s!MathRoman][file:texgyre-bonum-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre]
- \definefontsynonym[\s!MathRoman] [file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=bonum-math]
- \definefontsynonym[\s!MathRomanBold][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,bonum-math-bold,mathextra},\s!goodies=bonum-math]
+ \definefontsynonym[\s!MathRoman] [file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=bonum-math]
+ \definefontsynonym[\s!MathRomanBold][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,bonum-math-bold,mathextra},\s!goodies=bonum-math]
\stoptypescript
\stoptypescriptcollection
@@ -300,8 +300,8 @@
\starttypescript [\s!math][schoolbook,schola][\s!all]
% \loadfontgoodies[texgyre]
% \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre]
- \definefontsynonym[\s!MathRoman] [file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=schola-math]
- \definefontsynonym[\s!MathRomanBold][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,schola-math-bold,mathextra},\s!goodies=schola-math]
+ \definefontsynonym[\s!MathRoman] [file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=schola-math]
+ \definefontsynonym[\s!MathRomanBold][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,schola-math-bold,mathextra},\s!goodies=schola-math]
\stoptypescript
\stoptypescriptcollection
diff --git a/tex/context/fonts/mkiv/xits-math.lfg b/tex/context/fonts/mkiv/xits-math.lfg
index b37ab1277..88d3a8d45 100644
--- a/tex/context/fonts/mkiv/xits-math.lfg
+++ b/tex/context/fonts/mkiv/xits-math.lfg
@@ -14,6 +14,7 @@ local italics = {
-- [0x1D44E] = 0.99, -- a (fraction of quad)
-- [0x1D44F] = 100, -- b (font points)
[0x1D453] = -0.0375, -- f
+ -- todo: ssty 1/2
}
}
diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv
index 47f1a0177..9eb7411ba 100644
--- a/tex/context/modules/mkiv/m-punk.mkiv
+++ b/tex/context/modules/mkiv/m-punk.mkiv
@@ -17,6 +17,11 @@
%D https://www.youtube.com/watch?v=g5c2Htj8Vtw
%D \stoptyping
+\ifcase\contextlmtxmode\else
+ \writestatus{punk}{use metapost library punk instead}
+ \endinput
+\fi
+
\startluacode
local concat = table.concat
local round = math.round
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index c1300a71b..552559e96 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-01-11 16:28
+-- merge date : 2021-01-17 21:39
do -- begin closure to overcome local limits and interference