diff options
author | Hans Hagen <pragma@wxs.nl> | 2021-12-03 15:33:58 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2021-12-03 15:33:58 +0100 |
commit | 9c5a6d1bc8ad88a74f8d5243ed057819ce6bec2d (patch) | |
tree | b401a140de2a7832b8288908fc4c4ea2deda4361 | |
parent | 9ebf314056d5adab360cfd796925cf9e73c2bcce (diff) | |
download | context-9c5a6d1bc8ad88a74f8d5243ed057819ce6bec2d.tar.gz |
2021-12-03 15:19:00
72 files changed, 6205 insertions, 582 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-tex.lua b/context/data/scite/context/lexers/data/scite-context-data-tex.lua index 35df3104e..e57e0af4f 100644 --- a/context/data/scite/context/lexers/data/scite-context-data-tex.lua +++ b/context/data/scite/context/lexers/data/scite-context-data-tex.lua @@ -1,7 +1,7 @@ return { ["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" }, ["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracinglevels", "tracingnesting", "unexpanded", "unless", "widowpenalties" }, - ["luatex"]={ "UUskewed", "UUskewedwithdelims", "Uabove", "Uabovewithdelims", "Uatop", "Uatopwithdelims", "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaccentbaseheight", "Umathaccentvariant", "Umathadapttoleft", "Umathadapttoright", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathbotaccentvariant", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclass", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathdegreevariant", "Umathdelimiterovervariant", "Umathdelimiterundervariant", "Umathdenominatorvariant", "Umathextrasubpreshift", "Umathextrasubshift", "Umathextrasuppreshift", "Umathextrasupshift", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathfractionvariant", "Umathhextensiblevariant", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathlimits", "Umathnoaxis", "Umathnolimits", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathnumeratorvariant", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathopenupdepth", "Umathopenupheight", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervariant", "Umathoverdelimitervgap", "Umathoverlayaccentvariant", "Umathoverlinevariant", "Umathphantom", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvariant", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathspacebeforescript", "Umathspacingmode", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvariant", "Umathstackvgap", "Umathsubscriptvariant", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsuperscriptvariant", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathtopaccentvariant", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervariant", "Umathunderdelimitervgap", "Umathunderlinevariant", "Umathvextensiblevariant", "Umathvoid", "Umathxscale", "Umathyscale", "Umiddle", "Unosubprescript", "Unosubscript", "Unosuperprescript", "Unosuperscript", "Uover", "Uoverdelimiter", "Uoverwithdelims", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Ustyle", "Usubprescript", "Usubscript", "Usuperprescript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "adjustspacingshrink", "adjustspacingstep", "adjustspacingstretch", "afterassigned", "aftergrouped", "aliased", "alignmark", "aligntab", "atendofgroup", "atendofgrouped", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenpenalty", "automigrationmode", "autoparagraphmode", "begincsname", "beginlocalcontrol", "boundary", "boxattribute", "boxdirection", "boxorientation", "boxshift", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "catcodetable", "clearmarks", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "currentmarks", "defcsname", "dimensiondef", "dimexpression", "directlua", "edefcsname", "efcode", "endlocalcontrol", "enforced", "etoksapp", "etokspre", "everybeforepar", "everytab", "exceptionpenalty", "expand", "expandafterpars", "expandafterspaces", "expandcstoken", "expanded", "expandtoken", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "flushmarks", "fontid", "fontmathcontrol", "fontspecdef", "fontspecid", "fontspecifiedsize", "fontspecscale", "fontspecxscale", "fontspecyscale", "fonttextcontrol", "formatname", "frozen", "futurecsname", "futuredef", "futureexpand", "futureexpandis", "futureexpandisap", "gdefcsname", "gleaders", "glet", "gletcsname", "glettonothing", "gluespecdef", "glyphdatafield", "glyphoptions", "glyphscale", "glyphscriptfield", "glyphscriptscale", "glyphscriptscriptscale", "glyphstatefield", "glyphtextscale", "glyphxoffset", "glyphxscale", "glyphyoffset", "glyphyscale", "gtoksapp", "gtokspre", "hccode", "hjcode", "hpack", "hyphenationmin", "hyphenationmode", "ifabsdim", "ifabsnum", "ifarguments", "ifboolean", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimexpression", "ifdimval", "ifempty", "ifflags", "ifhaschar", "ifhastok", "ifhastoks", "ifhasxtoks", "ifincsname", "ifinsert", "ifmathparameter", "ifmathstyle", "ifnumexpression", "ifnumval", "ifparameter", "ifparameters", "ifrelax", "iftok", "ignorearguments", "ignorepars", "immediate", "immutable", "initcatcodetable", "insertbox", "insertcopy", "insertdepth", "insertdistance", "insertheight", "insertheights", "insertlimit", "insertmaxdepth", "insertmode", "insertmultiplier", "insertpenalty", "insertprogress", "insertstorage", "insertstoring", "insertunbox", "insertuncopy", "insertwidth", "instance", "integerdef", "lastarguments", "lastchkdim", "lastchknum", "lastnamedcs", "lastnodesubtype", "lastparcontext", "leftmarginkern", "letcharcode", "letcsname", "letfrozen", "letprotected", "lettonothing", "linedirection", "localbrokenpenalty", "localcontrol", "localcontrolled", "localinterlinepenalty", "localleftbox", "localleftboxbox", "localmiddlebox", "localmiddleboxbox", "localrightbox", "localrightboxbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathcontrolmode", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathfontcontrol", "mathlimitsmode", "mathnolimitsmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscale", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "mugluespecdef", "mutable", "noaligned", "noboundary", "nohrule", "norelax", "normalizelinemode", "nospaces", "novrule", "numericscale", "numexpression", "orelse", "orphanpenalties", "orphanpenalty", "orunless", "outputbox", "overloaded", "overloadmode", "pageboundary", "pagevsize", "parametercount", "parametermark", "parattribute", "pardirection", "permanent", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitvmode", "retokenized", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "semiexpanded", "semiprotected", "setfontid", "shapingpenaltiesmode", "shapingpenalty", "snapshotpar", "supmarkmode", "swapcsvalues", "tabsize", "textdirection", "thewithoutunit", "tokenized", "toksapp", "tokspre", "tolerant", "tpack", "tracingadjusts", "tracingalignments", "tracingexpressions", "tracingfonts", "tracingfullboxes", "tracinghyphenation", "tracinginserts", "tracingmarks", "tracingmath", "undent", "unletfrozen", "unletprotected", "untraced", "vpack", "wordboundary", "wrapuppar", "xdefcsname", "xtoksapp", "xtokspre" }, + ["luatex"]={ "UUskewed", "UUskewedwithdelims", "Uabove", "Uabovewithdelims", "Uatop", "Uatopwithdelims", "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaccentbaseheight", "Umathaccentvariant", "Umathadapttoleft", "Umathadapttoright", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathbotaccentvariant", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclass", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathdegreevariant", "Umathdelimiterovervariant", "Umathdelimiterundervariant", "Umathdenominatorvariant", "Umathextrasubpreshift", "Umathextrasubshift", "Umathextrasuppreshift", "Umathextrasupshift", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathfractionvariant", "Umathhextensiblevariant", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathlimits", "Umathnoaxis", "Umathnolimits", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathnumeratorvariant", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathopenupdepth", "Umathopenupheight", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervariant", "Umathoverdelimitervgap", "Umathoverlayaccentvariant", "Umathoverlinevariant", "Umathphantom", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvariant", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathspacebeforescript", "Umathspacingmode", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvariant", "Umathstackvgap", "Umathsubscriptvariant", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsuperscriptvariant", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathtopaccentvariant", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervariant", "Umathunderdelimitervgap", "Umathunderlinevariant", "Umathvextensiblevariant", "Umathvoid", "Umathxscale", "Umathyscale", "Umiddle", "Unosubprescript", "Unosubscript", "Unosuperprescript", "Unosuperscript", "Uover", "Uoverdelimiter", "Uoverwithdelims", "Uradical", "Uright", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Ustyle", "Usubprescript", "Usubscript", "Usuperprescript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "adjustspacingshrink", "adjustspacingstep", "adjustspacingstretch", "afterassigned", "aftergrouped", "aliased", "alignmark", "aligntab", "atendofgroup", "atendofgrouped", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenpenalty", "automigrationmode", "autoparagraphmode", "begincsname", "beginlocalcontrol", "boundary", "boxattribute", "boxdirection", "boxorientation", "boxshift", "boxtotal", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "catcodetable", "clearmarks", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csstring", "currentloopiterator", "currentloopnesting", "currentmarks", "defcsname", "dimensiondef", "dimexpression", "directlua", "edefcsname", "efcode", "endlocalcontrol", "enforced", "etoksapp", "etokspre", "everybeforepar", "everytab", "exceptionpenalty", "expand", "expandafterpars", "expandafterspaces", "expandcstoken", "expanded", "expandedloop", "expandtoken", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "flushmarks", "fontid", "fontmathcontrol", "fontspecdef", "fontspecid", "fontspecifiedsize", "fontspecscale", "fontspecxscale", "fontspecyscale", "fonttextcontrol", "formatname", "frozen", "futurecsname", "futuredef", "futureexpand", "futureexpandis", "futureexpandisap", "gdefcsname", "gleaders", "glet", "gletcsname", "glettonothing", "gluespecdef", "glyphdatafield", "glyphoptions", "glyphscale", "glyphscriptfield", "glyphscriptscale", "glyphscriptscriptscale", "glyphstatefield", "glyphtextscale", "glyphxoffset", "glyphxscale", "glyphyoffset", "glyphyscale", "gtoksapp", "gtokspre", "hccode", "hjcode", "hpack", "hyphenationmin", "hyphenationmode", "ifabsdim", "ifabsnum", "ifarguments", "ifboolean", "ifchkdim", "ifchknum", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimexpression", "ifdimval", "ifempty", "ifflags", "ifhaschar", "ifhastok", "ifhastoks", "ifhasxtoks", "ifincsname", "ifinsert", "ifmathparameter", "ifmathstyle", "ifnumexpression", "ifnumval", "ifparameter", "ifparameters", "ifrelax", "iftok", "ignorearguments", "ignorepars", "immediate", "immutable", "initcatcodetable", "insertbox", "insertcopy", "insertdepth", "insertdistance", "insertheight", "insertheights", "insertlimit", "insertmaxdepth", "insertmode", "insertmultiplier", "insertpenalty", "insertprogress", "insertstorage", "insertstoring", "insertunbox", "insertuncopy", "insertwidth", "instance", "integerdef", "lastarguments", "lastchkdim", "lastchknum", "lastnamedcs", "lastnodesubtype", "lastparcontext", "leftmarginkern", "letcharcode", "letcsname", "letfrozen", "letprotected", "lettonothing", "linedirection", "localbrokenpenalty", "localcontrol", "localcontrolled", "localcontrolledloop", "localinterlinepenalty", "localleftbox", "localleftboxbox", "localmiddlebox", "localmiddleboxbox", "localrightbox", "localrightboxbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathcontrolmode", "mathdelimitersmode", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathfontcontrol", "mathlimitsmode", "mathnolimitsmode", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscale", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "mugluespecdef", "mutable", "noaligned", "noboundary", "nohrule", "norelax", "normalizelinemode", "nospaces", "novrule", "numericscale", "numexpression", "orelse", "orphanpenalties", "orphanpenalty", "orunless", "outputbox", "overloaded", "overloadmode", "pageboundary", "pagevsize", "parametercount", "parametermark", "parattribute", "pardirection", "permanent", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitloop", "quitvmode", "retokenized", "rightmarginkern", "rpcode", "savecatcodetable", "scantextokens", "semiexpanded", "semiprotected", "setfontid", "shapingpenaltiesmode", "shapingpenalty", "snapshotpar", "supmarkmode", "swapcsvalues", "tabsize", "textdirection", "thewithoutunit", "tokenized", "toksapp", "tokspre", "tolerant", "tpack", "tracingadjusts", "tracingalignments", "tracingexpressions", "tracingfonts", "tracingfullboxes", "tracinghyphenation", "tracinginserts", "tracingmarks", "tracingmath", "undent", "unexpandedloop", "unletfrozen", "unletprotected", "untraced", "vpack", "wordboundary", "wrapuppar", "xdefcsname", "xtoksapp", "xtokspre" }, ["omega"]={ "Omegaminorversion", "Omegarevision", "Omegaversion" }, ["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmajorversion", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfomitcharset", "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" }, ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "aligncontent", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "beginsimplegroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "endsimplegroup", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "fontspecifiedname", "futurelet", "gdef", "global", "globaldefs", "glyph", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "meaningasis", "meaningfull", "meaningless", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overshoot", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillleftskip", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scaledfontdimen", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "shownodedetails", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "todimension", "tointeger", "toks", "toksdef", "tolerance", "topmark", "topskip", "toscaled", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unhpack", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "unvpack", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" }, diff --git a/context/data/scite/context/scite-context-data-tex.properties b/context/data/scite/context/scite-context-data-tex.properties index 959549733..08c4074f3 100644 --- a/context/data/scite/context/scite-context-data-tex.properties +++ b/context/data/scite/context/scite-context-data-tex.properties @@ -63,56 +63,58 @@ automaticdiscretionary automatichyphenpenalty automigrationmode autoparagraphmod beginlocalcontrol boundary boxattribute boxdirection boxorientation \ boxshift boxtotal boxxmove boxxoffset boxymove \ boxyoffset catcodetable clearmarks crampeddisplaystyle crampedscriptscriptstyle \ -crampedscriptstyle crampedtextstyle csstring currentmarks defcsname \ -dimensiondef dimexpression directlua edefcsname efcode \ -endlocalcontrol enforced etoksapp etokspre everybeforepar \ -everytab exceptionpenalty expand expandafterpars expandafterspaces \ -expandcstoken expanded expandtoken explicitdiscretionary explicithyphenpenalty \ -firstvalidlanguage flushmarks fontid fontmathcontrol fontspecdef \ -fontspecid fontspecifiedsize fontspecscale fontspecxscale fontspecyscale \ -fonttextcontrol formatname frozen futurecsname futuredef \ -futureexpand futureexpandis futureexpandisap gdefcsname gleaders \ -glet gletcsname glettonothing gluespecdef glyphdatafield \ -glyphoptions glyphscale glyphscriptfield glyphscriptscale glyphscriptscriptscale \ -glyphstatefield glyphtextscale glyphxoffset glyphxscale glyphyoffset \ -glyphyscale gtoksapp gtokspre hccode hjcode \ -hpack hyphenationmin hyphenationmode ifabsdim ifabsnum \ -ifarguments ifboolean ifchkdim ifchknum ifcmpdim \ -ifcmpnum ifcondition ifcstok ifdimexpression ifdimval \ -ifempty ifflags ifhaschar ifhastok ifhastoks \ -ifhasxtoks ifincsname ifinsert ifmathparameter ifmathstyle \ -ifnumexpression ifnumval ifparameter ifparameters ifrelax \ -iftok ignorearguments ignorepars immediate immutable \ -initcatcodetable insertbox insertcopy insertdepth insertdistance \ -insertheight insertheights insertlimit insertmaxdepth insertmode \ -insertmultiplier insertpenalty insertprogress insertstorage insertstoring \ -insertunbox insertuncopy insertwidth instance integerdef \ -lastarguments lastchkdim lastchknum lastnamedcs lastnodesubtype \ -lastparcontext leftmarginkern letcharcode letcsname letfrozen \ -letprotected lettonothing linedirection localbrokenpenalty localcontrol \ -localcontrolled localinterlinepenalty localleftbox localleftboxbox localmiddlebox \ -localmiddleboxbox localrightbox localrightboxbox lpcode luabytecode \ -luabytecodecall luacopyinputnodes luadef luaescapestring luafunction \ -luafunctioncall luatexbanner luatexrevision luatexversion mathcontrolmode \ -mathdelimitersmode mathdirection mathdisplayskipmode matheqnogapstep mathflattenmode \ -mathfontcontrol mathlimitsmode mathnolimitsmode mathpenaltiesmode mathrulesfam \ -mathrulesmode mathrulethicknessmode mathscale mathscriptboxmode mathscriptcharmode \ -mathscriptsmode mathstyle mathsurroundmode mathsurroundskip mugluespecdef \ -mutable noaligned noboundary nohrule norelax \ -normalizelinemode nospaces novrule numericscale numexpression \ -orelse orphanpenalties orphanpenalty orunless outputbox \ -overloaded overloadmode pageboundary pagevsize parametercount \ -parametermark parattribute pardirection permanent postexhyphenchar \ -posthyphenchar prebinoppenalty predisplaygapfactor preexhyphenchar prehyphenchar \ -prerelpenalty protrudechars protrusionboundary pxdimen quitvmode \ +crampedscriptstyle crampedtextstyle csstring currentloopiterator currentloopnesting \ +currentmarks defcsname dimensiondef dimexpression directlua \ +edefcsname efcode endlocalcontrol enforced etoksapp \ +etokspre everybeforepar everytab exceptionpenalty expand \ +expandafterpars expandafterspaces expandcstoken expanded expandedloop \ +expandtoken explicitdiscretionary explicithyphenpenalty firstvalidlanguage flushmarks \ +fontid fontmathcontrol fontspecdef fontspecid fontspecifiedsize \ +fontspecscale fontspecxscale fontspecyscale fonttextcontrol formatname \ +frozen futurecsname futuredef futureexpand futureexpandis \ +futureexpandisap gdefcsname gleaders glet gletcsname \ +glettonothing gluespecdef glyphdatafield glyphoptions glyphscale \ +glyphscriptfield glyphscriptscale glyphscriptscriptscale glyphstatefield glyphtextscale \ +glyphxoffset glyphxscale glyphyoffset glyphyscale gtoksapp \ +gtokspre hccode hjcode hpack hyphenationmin \ +hyphenationmode ifabsdim ifabsnum ifarguments ifboolean \ +ifchkdim ifchknum ifcmpdim ifcmpnum ifcondition \ +ifcstok ifdimexpression ifdimval ifempty ifflags \ +ifhaschar ifhastok ifhastoks ifhasxtoks ifincsname \ +ifinsert ifmathparameter ifmathstyle ifnumexpression ifnumval \ +ifparameter ifparameters ifrelax iftok ignorearguments \ +ignorepars immediate immutable initcatcodetable insertbox \ +insertcopy insertdepth insertdistance insertheight insertheights \ +insertlimit insertmaxdepth insertmode insertmultiplier insertpenalty \ +insertprogress insertstorage insertstoring insertunbox insertuncopy \ +insertwidth instance integerdef lastarguments lastchkdim \ +lastchknum lastnamedcs lastnodesubtype lastparcontext leftmarginkern \ +letcharcode letcsname letfrozen letprotected lettonothing \ +linedirection localbrokenpenalty localcontrol localcontrolled localcontrolledloop \ +localinterlinepenalty localleftbox localleftboxbox localmiddlebox localmiddleboxbox \ +localrightbox localrightboxbox lpcode luabytecode luabytecodecall \ +luacopyinputnodes luadef luaescapestring luafunction luafunctioncall \ +luatexbanner luatexrevision luatexversion mathcontrolmode mathdelimitersmode \ +mathdirection mathdisplayskipmode matheqnogapstep mathflattenmode mathfontcontrol \ +mathlimitsmode mathnolimitsmode mathpenaltiesmode mathrulesfam mathrulesmode \ +mathrulethicknessmode mathscale mathscriptboxmode mathscriptcharmode mathscriptsmode \ +mathstyle mathsurroundmode mathsurroundskip mugluespecdef mutable \ +noaligned noboundary nohrule norelax normalizelinemode \ +nospaces novrule numericscale numexpression orelse \ +orphanpenalties orphanpenalty orunless outputbox overloaded \ +overloadmode pageboundary pagevsize parametercount parametermark \ +parattribute pardirection permanent postexhyphenchar posthyphenchar \ +prebinoppenalty predisplaygapfactor preexhyphenchar prehyphenchar prerelpenalty \ +protrudechars protrusionboundary pxdimen quitloop quitvmode \ retokenized rightmarginkern rpcode savecatcodetable scantextokens \ semiexpanded semiprotected setfontid shapingpenaltiesmode shapingpenalty \ snapshotpar supmarkmode swapcsvalues tabsize textdirection \ thewithoutunit tokenized toksapp tokspre tolerant \ tpack tracingadjusts tracingalignments tracingexpressions tracingfonts \ tracingfullboxes tracinghyphenation tracinginserts tracingmarks tracingmath \ -undent unletfrozen unletprotected untraced vpack \ -wordboundary wrapuppar xdefcsname xtoksapp xtokspre +undent unexpandedloop unletfrozen unletprotected untraced \ +vpack wordboundary wrapuppar xdefcsname xtoksapp \ +xtokspre keywordclass.tex.omega=\ Omegaminorversion Omegarevision Omegaversion diff --git a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json index 824723478..8c82479c6 100644 --- a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json +++ b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json @@ -216,7 +216,7 @@ ] }, "primitive" : { - "match" : "\u005C\u005C(year|xtokspre|xtoksapp|xspaceskip|xleaders|xdefcsname|xdef|wrapuppar|wordboundary|widowpenalty|widowpenalties|wd|vtop|vss|vsplit|vskip|vsize|vrule|vpack|vfuzz|vfilneg|vfill|vfil|vcenter|vbox|vbadness|valign|vadjust|uppercase|unvpack|unvcopy|unvbox|untraced|unskip|unpenalty|unletprotected|unletfrozen|unless|unkern|unhpack|unhcopy|unhbox|underline|undent|uchyph|uccode|tracingstats|tracingrestores|tracingparagraphs|tracingpages|tracingoutput|tracingonline|tracingnesting|tracingmath|tracingmarks|tracingmacros|tracinglostchars|tracinglevels|tracinginserts|tracingifs|tracinghyphenation|tracinggroups|tracingfullboxes|tracingfonts|tracingexpressions|tracingcommands|tracingassigns|tracingalignments|tracingadjusts|tpack|toscaled|topskip|topmarks|topmark|tolerant|tolerance|tokspre|toksdef|toksapp|toks|tokenized|tointeger|todimension|time|thinmuskip|thickmuskip|thewithoutunit|the|textstyle|textfont|textdirection|tabskip|tabsize|swapcsvalues|supmarkmode|string|splittopskip|splitmaxdepth|splitfirstmarks|splitfirstmark|splitdiscards|splitbotmarks|splitbotmark|span|spaceskip|spacefactor|snapshotpar|skipdef|skip|skewchar|showtokens|showthe|shownodedetails|showlists|showifs|showgroups|showboxdepth|showboxbreadth|showbox|show|shipout|shapingpenalty|shapingpenaltiesmode|sfcode|setlanguage|setfontid|setbox|semiprotected|semiexpanded|scrollmode|scriptstyle|scriptspace|scriptscriptstyle|scriptscriptfont|scriptfont|scantokens|scantextokens|scaledfontdimen|savingvdiscards|savinghyphcodes|savecatcodetable|rpcode|romannumeral|rightskip|rightmarginkern|righthyphenmin|right|retokenized|relpenalty|relax|raise|radical|quitvmode|pxdimen|protrusionboundary|protrudechars|protected|prevgraf|prevdepth|pretolerance|prerelpenalty|prehyphenchar|preexhyphenchar|predisplaysize|predisplaypenalty|predisplaygapfactor|predisplaydirection|prebinoppenalty|posthyphenchar|postexhyphenchar|postdisplaypenalty|permanent|penalty|pdfximage|pdfxformresources|pdfxformname|pdfxformmargin|pdfxformattr|pdfxform|pdfvorigin|pdfuniqueresname|pdfuniformdeviate|pdftrailerid|pdftrailer|pdftracingfonts|pdfthreadmargin|pdfthread|pdftexversion|pdftexrevision|pdftexbanner|pdfsuppressptexinfo|pdfsuppressoptionalinfo|pdfstartthread|pdfstartlink|pdfsetrandomseed|pdfsetmatrix|pdfsavepos|pdfsave|pdfretval|pdfrestore|pdfreplacefont|pdfrefximage|pdfrefxform|pdfrefobj|pdfrecompress|pdfrandomseed|pdfpxdimen|pdfprotrudechars|pdfprimitive|pdfpkresolution|pdfpkmode|pdfpkfixeddpi|pdfpagewidth|pdfpagesattr|pdfpageresources|pdfpageref|pdfpageheight|pdfpagebox|pdfpageattr|pdfoutput|pdfoutline|pdfomitcidset|pdfomitcharset|pdfobjcompresslevel|pdfobj|pdfnormaldeviate|pdfnoligatures|pdfnames|pdfminorversion|pdfmapline|pdfmapfile|pdfmajorversion|pdfliteral|pdflinkmargin|pdflastypos|pdflastxpos|pdflastximagepages|pdflastximage|pdflastxform|pdflastobj|pdflastlink|pdflastlinedepth|pdflastannot|pdfinsertht|pdfinfoomitdate|pdfinfo|pdfinclusionerrorlevel|pdfinclusioncopyfonts|pdfincludechars|pdfimageresolution|pdfimagehicolor|pdfimagegamma|pdfimageapplygamma|pdfimageaddfilename|pdfignoreunknownimages|pdfignoreddimen|pdfhorigin|pdfglyphtounicode|pdfgentounicode|pdfgamma|pdffontsize|pdffontobjnum|pdffontname|pdffontexpand|pdffontattr|pdffirstlineheight|pdfendthread|pdfendlink|pdfeachlineheight|pdfeachlinedepth|pdfdraftmode|pdfdestmargin|pdfdest|pdfdecimaldigits|pdfcreationdate|pdfcopyfont|pdfcompresslevel|pdfcolorstackinit|pdfcolorstack|pdfcatalog|pdfannot|pdfadjustspacing|pausing|patterns|parskip|parshapelength|parshapeindent|parshapedimen|parshape|parindent|parfillskip|pardirection|parattribute|parametermark|parametercount|par|pagevsize|pagetotal|pagestretch|pageshrink|pagegoal|pagefilstretch|pagefillstretch|pagefilllstretch|pagediscards|pagedepth|pageboundary|overwithdelims|overshoot|overloadmode|overloaded|overline|overfullrule|over|outputpenalty|outputbox|output|outer|orunless|orphanpenalty|orphanpenalties|orelse|or|omit|numexpression|numexpr|numericscale|number|nullfont|nulldelimiterspace|novrule|nospaces|normalyear|normalxtokspre|normalxtoksapp|normalxspaceskip|normalxleaders|normalxdefcsname|normalxdef|normalwrapuppar|normalwordboundary|normalwidowpenalty|normalwidowpenalties|normalwd|normalvtop|normalvss|normalvsplit|normalvskip|normalvsize|normalvrule|normalvpack|normalvfuzz|normalvfilneg|normalvfill|normalvfil|normalvcenter|normalvbox|normalvbadness|normalvalign|normalvadjust|normaluppercase|normalunvpack|normalunvcopy|normalunvbox|normaluntraced|normalunskip|normalunpenalty|normalunletprotected|normalunletfrozen|normalunless|normalunkern|normalunhpack|normalunhcopy|normalunhbox|normalunexpanded|normalunderline|normalundent|normaluchyph|normaluccode|normaltracingstats|normaltracingrestores|normaltracingparagraphs|normaltracingpages|normaltracingoutput|normaltracingonline|normaltracingnesting|normaltracingmath|normaltracingmarks|normaltracingmacros|normaltracinglostchars|normaltracinglevels|normaltracinginserts|normaltracingifs|normaltracinghyphenation|normaltracinggroups|normaltracingfullboxes|normaltracingfonts|normaltracingexpressions|normaltracingcommands|normaltracingassigns|normaltracingalignments|normaltracingadjusts|normaltpack|normaltoscaled|normaltopskip|normaltopmarks|normaltopmark|normaltolerant|normaltolerance|normaltokspre|normaltoksdef|normaltoksapp|normaltoks|normaltokenized|normaltointeger|normaltodimension|normaltime|normalthinmuskip|normalthickmuskip|normalthewithoutunit|normalthe|normaltextstyle|normaltextfont|normaltextdirection|normaltabskip|normaltabsize|normalswapcsvalues|normalsupmarkmode|normalstring|normalsplittopskip|normalsplitmaxdepth|normalsplitfirstmarks|normalsplitfirstmark|normalsplitdiscards|normalsplitbotmarks|normalsplitbotmark|normalspan|normalspaceskip|normalspacefactor|normalsnapshotpar|normalskipdef|normalskip|normalskewchar|normalshowtokens|normalshowthe|normalshownodedetails|normalshowlists|normalshowifs|normalshowgroups|normalshowboxdepth|normalshowboxbreadth|normalshowbox|normalshow|normalshipout|normalshapingpenalty|normalshapingpenaltiesmode|normalsfcode|normalsetlanguage|normalsetfontid|normalsetbox|normalsemiprotected|normalsemiexpanded|normalscrollmode|normalscriptstyle|normalscriptspace|normalscriptscriptstyle|normalscriptscriptfont|normalscriptfont|normalscantokens|normalscantextokens|normalscaledfontdimen|normalsavingvdiscards|normalsavinghyphcodes|normalsavecatcodetable|normalrpcode|normalromannumeral|normalrightskip|normalrightmarginkern|normalrighthyphenmin|normalright|normalretokenized|normalrelpenalty|normalrelax|normalraise|normalradical|normalquitvmode|normalpxdimen|normalprotrusionboundary|normalprotrudechars|normalprotected|normalprevgraf|normalprevdepth|normalpretolerance|normalprerelpenalty|normalprehyphenchar|normalpreexhyphenchar|normalpredisplaysize|normalpredisplaypenalty|normalpredisplaygapfactor|normalpredisplaydirection|normalprebinoppenalty|normalposthyphenchar|normalpostexhyphenchar|normalpostdisplaypenalty|normalpermanent|normalpenalty|normalpdfximage|normalpdfxformresources|normalpdfxformname|normalpdfxformmargin|normalpdfxformattr|normalpdfxform|normalpdfvorigin|normalpdfuniqueresname|normalpdfuniformdeviate|normalpdftrailerid|normalpdftrailer|normalpdftracingfonts|normalpdfthreadmargin|normalpdfthread|normalpdftexversion|normalpdftexrevision|normalpdftexbanner|normalpdfsuppressptexinfo|normalpdfsuppressoptionalinfo|normalpdfstartthread|normalpdfstartlink|normalpdfsetrandomseed|normalpdfsetmatrix|normalpdfsavepos|normalpdfsave|normalpdfretval|normalpdfrestore|normalpdfreplacefont|normalpdfrefximage|normalpdfrefxform|normalpdfrefobj|normalpdfrecompress|normalpdfrandomseed|normalpdfpxdimen|normalpdfprotrudechars|normalpdfprimitive|normalpdfpkresolution|normalpdfpkmode|normalpdfpkfixeddpi|normalpdfpagewidth|normalpdfpagesattr|normalpdfpageresources|normalpdfpageref|normalpdfpageheight|normalpdfpagebox|normalpdfpageattr|normalpdfoutput|normalpdfoutline|normalpdfomitcidset|normalpdfomitcharset|normalpdfobjcompresslevel|normalpdfobj|normalpdfnormaldeviate|normalpdfnoligatures|normalpdfnames|normalpdfminorversion|normalpdfmapline|normalpdfmapfile|normalpdfmajorversion|normalpdfliteral|normalpdflinkmargin|normalpdflastypos|normalpdflastxpos|normalpdflastximagepages|normalpdflastximage|normalpdflastxform|normalpdflastobj|normalpdflastlink|normalpdflastlinedepth|normalpdflastannot|normalpdfinsertht|normalpdfinfoomitdate|normalpdfinfo|normalpdfinclusionerrorlevel|normalpdfinclusioncopyfonts|normalpdfincludechars|normalpdfimageresolution|normalpdfimagehicolor|normalpdfimagegamma|normalpdfimageapplygamma|normalpdfimageaddfilename|normalpdfignoreunknownimages|normalpdfignoreddimen|normalpdfhorigin|normalpdfglyphtounicode|normalpdfgentounicode|normalpdfgamma|normalpdffontsize|normalpdffontobjnum|normalpdffontname|normalpdffontexpand|normalpdffontattr|normalpdffirstlineheight|normalpdfendthread|normalpdfendlink|normalpdfeachlineheight|normalpdfeachlinedepth|normalpdfdraftmode|normalpdfdestmargin|normalpdfdest|normalpdfdecimaldigits|normalpdfcreationdate|normalpdfcopyfont|normalpdfcompresslevel|normalpdfcolorstackinit|normalpdfcolorstack|normalpdfcatalog|normalpdfannot|normalpdfadjustspacing|normalpausing|normalpatterns|normalparskip|normalparshapelength|normalparshapeindent|normalparshapedimen|normalparshape|normalparindent|normalparfillskip|normalparfillleftskip|normalpardirection|normalparattribute|normalparametermark|normalparametercount|normalpar|normalpagevsize|normalpagetotal|normalpagestretch|normalpageshrink|normalpagegoal|normalpagefilstretch|normalpagefillstretch|normalpagefilllstretch|normalpagediscards|normalpagedepth|normalpageboundary|normaloverwithdelims|normalovershoot|normaloverloadmode|normaloverloaded|normaloverline|normaloverfullrule|normalover|normaloutputpenalty|normaloutputbox|normaloutput|normalouter|normalorunless|normalorphanpenalty|normalorphanpenalties|normalorelse|normalor|normalomit|normalnumexpression|normalnumexpr|normalnumericscale|normalnumber|normalnullfont|normalnulldelimiterspace|normalnovrule|normalnospaces|normalnormalizelinemode|normalnorelax|normalnonstopmode|normalnonscript|normalnolimits|normalnoindent|normalnohrule|normalnoexpand|normalnoboundary|normalnoaligned|normalnoalign|normalnewlinechar|normalmutoglue|normalmutable|normalmuskipdef|normalmuskip|normalmultiply|normalmugluespecdef|normalmuexpr|normalmskip|normalmoveright|normalmoveleft|normalmonth|normalmkern|normalmiddle|normalmessage|normalmedmuskip|normalmeaningless|normalmeaningfull|normalmeaningasis|normalmeaning|normalmaxdepth|normalmaxdeadcycles|normalmathsurroundskip|normalmathsurroundmode|normalmathsurround|normalmathstyle|normalmathscriptsmode|normalmathscriptcharmode|normalmathscriptboxmode|normalmathscale|normalmathrulethicknessmode|normalmathrulesmode|normalmathrulesfam|normalmathrel|normalmathpunct|normalmathpenaltiesmode|normalmathord|normalmathopen|normalmathop|normalmathnolimitsmode|normalmathlimitsmode|normalmathinner|normalmathfontcontrol|normalmathflattenmode|normalmatheqnogapstep|normalmathdisplayskipmode|normalmathdirection|normalmathdelimitersmode|normalmathcontrolmode|normalmathcode|normalmathclose|normalmathchoice|normalmathchardef|normalmathchar|normalmathbin|normalmathaccent|normalmarks|normalmark|normalluatexversion|normalluatexrevision|normalluatexbanner|normalluafunctioncall|normalluafunction|normalluaescapestring|normalluadef|normalluacopyinputnodes|normalluabytecodecall|normalluabytecode|normallpcode|normallowercase|normallower|normallooseness|normallong|normallocalrightboxbox|normallocalrightbox|normallocalmiddleboxbox|normallocalmiddlebox|normallocalleftboxbox|normallocalleftbox|normallocalinterlinepenalty|normallocalcontrolled|normallocalcontrol|normallocalbrokenpenalty|normallineskiplimit|normallineskip|normallinepenalty|normallinedirection|normallimits|normallettonothing|normalletprotected|normalletfrozen|normalletcsname|normalletcharcode|normallet|normalleqno|normalleftskip|normalleftmarginkern|normallefthyphenmin|normalleft|normalleaders|normallccode|normallastskip|normallastpenalty|normallastparcontext|normallastnodetype|normallastnodesubtype|normallastnamedcs|normallastlinefit|normallastkern|normallastchknum|normallastchkdim|normallastbox|normallastarguments|normallanguage|normalkern|normaljobname|normalizelinemode|normalinterlinepenalty|normalinterlinepenalties|normalinteractionmode|normalintegerdef|normalinstance|normalinsertwidth|normalinsertuncopy|normalinsertunbox|normalinsertstoring|normalinsertstorage|normalinsertprogress|normalinsertpenalty|normalinsertpenalties|normalinsertmultiplier|normalinsertmode|normalinsertmaxdepth|normalinsertlimit|normalinsertheights|normalinsertheight|normalinsertdistance|normalinsertdepth|normalinsertcopy|normalinsertbox|normalinsert|normalinputlineno|normalinput|normalinitcatcodetable|normalindent|normalimmutable|normalimmediate|normalignorespaces|normalignorepars|normalignorearguments|normalifx|normalifvoid|normalifvmode|normalifvbox|normaliftrue|normaliftok|normalifrelax|normalifpdfprimitive|normalifpdfabsnum|normalifpdfabsdim|normalifparameters|normalifparameter|normalifodd|normalifnumval|normalifnumexpression|normalifnum|normalifmmode|normalifmathstyle|normalifmathparameter|normalifinsert|normalifinner|normalifincsname|normalifhmode|normalifhbox|normalifhasxtoks|normalifhastoks|normalifhastok|normalifhaschar|normaliffontchar|normalifflags|normaliffalse|normalifempty|normalifdimval|normalifdimexpression|normalifdim|normalifdefined|normalifcstok|normalifcsname|normalifcondition|normalifcmpnum|normalifcmpdim|normalifchknum|normalifchkdim|normalifcat|normalifcase|normalifboolean|normalifarguments|normalifabsnum|normalifabsdim|normalif|normalhyphenpenalty|normalhyphenchar|normalhyphenationmode|normalhyphenationmin|normalhyphenation|normalht|normalhss|normalhskip|normalhsize|normalhrule|normalhpack|normalholdinginserts|normalhjcode|normalhfuzz|normalhfilneg|normalhfill|normalhfil|normalhccode|normalhbox|normalhbadness|normalhangindent|normalhangafter|normalhalign|normalgtokspre|normalgtoksapp|normalglyphyscale|normalglyphyoffset|normalglyphxscale|normalglyphxoffset|normalglyphtextscale|normalglyphstatefield|normalglyphscriptscriptscale|normalglyphscriptscale|normalglyphscriptfield|normalglyphscale|normalglyphoptions|normalglyphdatafield|normalglyph|normalgluetomu|normalgluestretchorder|normalgluestretch|normalgluespecdef|normalglueshrinkorder|normalglueshrink|normalglueexpr|normalglobaldefs|normalglobal|normalglettonothing|normalgletcsname|normalglet|normalgleaders|normalgdefcsname|normalgdef|normalfuturelet|normalfutureexpandisap|normalfutureexpandis|normalfutureexpand|normalfuturedef|normalfuturecsname|normalfrozen|normalformatname|normalfonttextcontrol|normalfontspecyscale|normalfontspecxscale|normalfontspecscale|normalfontspecifiedsize|normalfontspecifiedname|normalfontspecid|normalfontspecdef|normalfontname|normalfontmathcontrol|normalfontid|normalfontdimen|normalfontcharwd|normalfontcharic|normalfontcharht|normalfontchardp|normalfont|normalflushmarks|normalfloatingpenalty|normalfirstvalidlanguage|normalfirstmarks|normalfirstmark|normalfinalhyphendemerits|normalfi|normalfam|normalexplicithyphenpenalty|normalexplicitdiscretionary|normalexpandtoken|normalexpanded|normalexpandcstoken|normalexpandafterspaces|normalexpandafterpars|normalexpandafter|normalexpand|normalexhyphenpenalty|normalexhyphenchar|normalexceptionpenalty|normaleveryvbox|normaleverytab|normaleverypar|normaleverymath|normaleveryjob|normaleveryhbox|normaleveryeof|normaleverydisplay|normaleverycr|normaleverybeforepar|normaletokspre|normaletoksapp|normalescapechar|normalerrorstopmode|normalerrorcontextlines|normalerrmessage|normalerrhelp|normaleqno|normalenforced|normalendsimplegroup|normalendlocalcontrol|normalendlinechar|normalendinput|normalendgroup|normalendcsname|normalend|normalemergencystretch|normalelse|normalefcode|normaledefcsname|normaledef|normaldump|normaldp|normaldoublehyphendemerits|normaldivide|normaldisplaywidth|normaldisplaywidowpenalty|normaldisplaywidowpenalties|normaldisplaystyle|normaldisplaylimits|normaldisplayindent|normaldiscretionary|normaldirectlua|normaldimexpression|normaldimexpr|normaldimensiondef|normaldimendef|normaldimen|normaldetokenize|normaldelimitershortfall|normaldelimiterfactor|normaldelimiter|normaldelcode|normaldefcsname|normaldefaultskewchar|normaldefaulthyphenchar|normaldef|normaldeadcycles|normalday|normalcurrentmarks|normalcurrentiftype|normalcurrentiflevel|normalcurrentifbranch|normalcurrentgrouptype|normalcurrentgrouplevel|normalcsstring|normalcsname|normalcrcr|normalcrampedtextstyle|normalcrampedscriptstyle|normalcrampedscriptscriptstyle|normalcrampeddisplaystyle|normalcr|normalcountdef|normalcount|normalcopy|normalclubpenalty|normalclubpenalties|normalclearmarks|normalcleaders|normalchardef|normalchar|normalcatcodetable|normalcatcode|normalbrokenpenalty|normalboxyoffset|normalboxymove|normalboxxoffset|normalboxxmove|normalboxtotal|normalboxshift|normalboxorientation|normalboxmaxdepth|normalboxdirection|normalboxattribute|normalbox|normalboundary|normalbotmarks|normalbotmark|normalbinoppenalty|normalbelowdisplayskip|normalbelowdisplayshortskip|normalbeginsimplegroup|normalbeginlocalcontrol|normalbegingroup|normalbegincsname|normalbatchmode|normalbaselineskip|normalbadness|normalautoparagraphmode|normalautomigrationmode|normalautomatichyphenpenalty|normalautomaticdiscretionary|normalattributedef|normalattribute|normalatopwithdelims|normalatop|normalatendofgrouped|normalatendofgroup|normalaligntab|normalalignmark|normalaligncontent|normalaliased|normalaftergrouped|normalaftergroup|normalafterassignment|normalafterassigned|normaladvance|normaladjustspacingstretch|normaladjustspacingstep|normaladjustspacingshrink|normaladjustspacing|normaladjdemerits|normalaccent|normalabovewithdelims|normalabovedisplayskip|normalabovedisplayshortskip|normalabove|normalXeTeXversion|normalUvextensible|normalUunderdelimiter|normalUsuperscript|normalUsuperprescript|normalUsubscript|normalUsubprescript|normalUstyle|normalUstopmath|normalUstopdisplaymath|normalUstartmath|normalUstartdisplaymath|normalUstack|normalUskewedwithdelims|normalUskewed|normalUroot|normalUright|normalUradical|normalUoverwithdelims|normalUoverdelimiter|normalUover|normalUnosuperscript|normalUnosuperprescript|normalUnosubscript|normalUnosubprescript|normalUmiddle|normalUmathyscale|normalUmathxscale|normalUmathvoid|normalUmathvextensiblevariant|normalUmathunderlinevariant|normalUmathunderdelimitervgap|normalUmathunderdelimitervariant|normalUmathunderdelimiterbgap|normalUmathunderbarvgap|normalUmathunderbarrule|normalUmathunderbarkern|normalUmathtopaccentvariant|normalUmathsupsubbottommax|normalUmathsupshiftup|normalUmathsupshiftdrop|normalUmathsuperscriptvariant|normalUmathsupbottommin|normalUmathsubtopmax|normalUmathsubsupvgap|normalUmathsubsupshiftdown|normalUmathsubshiftdrop|normalUmathsubshiftdown|normalUmathsubscriptvariant|normalUmathstackvgap|normalUmathstackvariant|normalUmathstacknumup|normalUmathstackdenomdown|normalUmathspacingmode|normalUmathspacebeforescript|normalUmathspaceafterscript|normalUmathskewedfractionvgap|normalUmathskewedfractionhgap|normalUmathrelrelspacing|normalUmathrelpunctspacing|normalUmathrelordspacing|normalUmathrelopspacing|normalUmathrelopenspacing|normalUmathrelinnerspacing|normalUmathrelclosespacing|normalUmathrelbinspacing|normalUmathradicalvgap|normalUmathradicalvariant|normalUmathradicalrule|normalUmathradicalkern|normalUmathradicaldegreeraise|normalUmathradicaldegreebefore|normalUmathradicaldegreeafter|normalUmathquad|normalUmathpunctrelspacing|normalUmathpunctpunctspacing|normalUmathpunctordspacing|normalUmathpunctopspacing|normalUmathpunctopenspacing|normalUmathpunctinnerspacing|normalUmathpunctclosespacing|normalUmathpunctbinspacing|normalUmathphantom|normalUmathoverlinevariant|normalUmathoverlayaccentvariant|normalUmathoverdelimitervgap|normalUmathoverdelimitervariant|normalUmathoverdelimiterbgap|normalUmathoverbarvgap|normalUmathoverbarrule|normalUmathoverbarkern|normalUmathordrelspacing|normalUmathordpunctspacing|normalUmathordordspacing|normalUmathordopspacing|normalUmathordopenspacing|normalUmathordinnerspacing|normalUmathordclosespacing|normalUmathordbinspacing|normalUmathoprelspacing|normalUmathoppunctspacing|normalUmathopordspacing|normalUmathopopspacing|normalUmathopopenspacing|normalUmathopinnerspacing|normalUmathoperatorsize|normalUmathopenupheight|normalUmathopenupdepth|normalUmathopenrelspacing|normalUmathopenpunctspacing|normalUmathopenordspacing|normalUmathopenopspacing|normalUmathopenopenspacing|normalUmathopeninnerspacing|normalUmathopenclosespacing|normalUmathopenbinspacing|normalUmathopclosespacing|normalUmathopbinspacing|normalUmathnumeratorvariant|normalUmathnolimitsupfactor|normalUmathnolimitsubfactor|normalUmathnolimits|normalUmathnoaxis|normalUmathlimits|normalUmathlimitbelowvgap|normalUmathlimitbelowkern|normalUmathlimitbelowbgap|normalUmathlimitabovevgap|normalUmathlimitabovekern|normalUmathlimitabovebgap|normalUmathinnerrelspacing|normalUmathinnerpunctspacing|normalUmathinnerordspacing|normalUmathinneropspacing|normalUmathinneropenspacing|normalUmathinnerinnerspacing|normalUmathinnerclosespacing|normalUmathinnerbinspacing|normalUmathhextensiblevariant|normalUmathfractionvariant|normalUmathfractionrule|normalUmathfractionnumvgap|normalUmathfractionnumup|normalUmathfractiondenomvgap|normalUmathfractiondenomdown|normalUmathfractiondelsize|normalUmathextrasupshift|normalUmathextrasuppreshift|normalUmathextrasubshift|normalUmathextrasubpreshift|normalUmathdenominatorvariant|normalUmathdelimiterundervariant|normalUmathdelimiterovervariant|normalUmathdegreevariant|normalUmathconnectoroverlapmin|normalUmathcodenum|normalUmathcode|normalUmathcloserelspacing|normalUmathclosepunctspacing|normalUmathcloseordspacing|normalUmathcloseopspacing|normalUmathcloseopenspacing|normalUmathcloseinnerspacing|normalUmathcloseclosespacing|normalUmathclosebinspacing|normalUmathclass|normalUmathcharslot|normalUmathcharnumdef|normalUmathcharnum|normalUmathcharfam|normalUmathchardef|normalUmathcharclass|normalUmathchar|normalUmathbotaccentvariant|normalUmathbinrelspacing|normalUmathbinpunctspacing|normalUmathbinordspacing|normalUmathbinopspacing|normalUmathbinopenspacing|normalUmathbininnerspacing|normalUmathbinclosespacing|normalUmathbinbinspacing|normalUmathaxis|normalUmathadapttoright|normalUmathadapttoleft|normalUmathaccentvariant|normalUmathaccentbaseheight|normalUmathaccent|normalUleft|normalUhextensible|normalUdelimiterunder|normalUdelimiterover|normalUdelimiter|normalUdelcodenum|normalUdelcode|normalUchar|normalUatopwithdelims|normalUatop|normalUabovewithdelims|normalUabove|normalUUskewedwithdelims|normalUUskewed|normalOmegaversion|normalOmegarevision|normalOmegaminorversion|normalAlephversion|normalAlephrevision|normalAlephminorversion|normal |norelax|nonstopmode|nonscript|nolimits|noindent|nohrule|noexpand|noboundary|noaligned|noalign|newlinechar|mutoglue|mutable|muskipdef|muskip|multiply|mugluespecdef|muexpr|mskip|moveright|moveleft|month|mkern|middle|message|medmuskip|meaningless|meaningfull|meaningasis|meaning|maxdepth|maxdeadcycles|mathsurroundskip|mathsurroundmode|mathsurround|mathstyle|mathscriptsmode|mathscriptcharmode|mathscriptboxmode|mathscale|mathrulethicknessmode|mathrulesmode|mathrulesfam|mathrel|mathpunct|mathpenaltiesmode|mathord|mathopen|mathop|mathnolimitsmode|mathlimitsmode|mathinner|mathfontcontrol|mathflattenmode|matheqnogapstep|mathdisplayskipmode|mathdirection|mathdelimitersmode|mathcontrolmode|mathcode|mathclose|mathchoice|mathchardef|mathchar|mathbin|mathaccent|marks|mark|luatexversion|luatexrevision|luatexbanner|luafunctioncall|luafunction|luaescapestring|luadef|luacopyinputnodes|luabytecodecall|luabytecode|lpcode|lowercase|lower|looseness|long|localrightboxbox|localrightbox|localmiddleboxbox|localmiddlebox|localleftboxbox|localleftbox|localinterlinepenalty|localcontrolled|localcontrol|localbrokenpenalty|lineskiplimit|lineskip|linepenalty|linedirection|limits|lettonothing|letprotected|letfrozen|letcsname|letcharcode|let|leqno|leftskip|leftmarginkern|lefthyphenmin|left|leaders|lccode|lastskip|lastpenalty|lastparcontext|lastnodetype|lastnodesubtype|lastnamedcs|lastlinefit|lastkern|lastchknum|lastchkdim|lastbox|lastarguments|language|kern|jobname|interlinepenalty|interlinepenalties|interactionmode|integerdef|instance|insertwidth|insertuncopy|insertunbox|insertstoring|insertstorage|insertprogress|insertpenalty|insertpenalties|insertmultiplier|insertmode|insertmaxdepth|insertlimit|insertheights|insertheight|insertdistance|insertdepth|insertcopy|insertbox|insert|inputlineno|input|initcatcodetable|indent|immutable|immediate|ignorespaces|ignorepars|ignorearguments|ifx|ifvoid|ifvmode|ifvbox|iftrue|iftok|ifrelax|ifpdfprimitive|ifpdfabsnum|ifpdfabsdim|ifparameters|ifparameter|ifodd|ifnumval|ifnumexpression|ifnum|ifmmode|ifmathstyle|ifmathparameter|ifinsert|ifinner|ifincsname|ifhmode|ifhbox|ifhasxtoks|ifhastoks|ifhastok|ifhaschar|iffontchar|ifflags|iffalse|ifempty|ifdimval|ifdimexpression|ifdim|ifdefined|ifcstok|ifcsname|ifcondition|ifcmpnum|ifcmpdim|ifchknum|ifchkdim|ifcat|ifcase|ifboolean|ifarguments|ifabsnum|ifabsdim|if|hyphenpenalty|hyphenchar|hyphenationmode|hyphenationmin|hyphenation|ht|hss|hskip|hsize|hrule|hpack|holdinginserts|hjcode|hfuzz|hfilneg|hfill|hfil|hccode|hbox|hbadness|hangindent|hangafter|halign|gtokspre|gtoksapp|glyphyscale|glyphyoffset|glyphxscale|glyphxoffset|glyphtextscale|glyphstatefield|glyphscriptscriptscale|glyphscriptscale|glyphscriptfield|glyphscale|glyphoptions|glyphdatafield|glyph|gluetomu|gluestretchorder|gluestretch|gluespecdef|glueshrinkorder|glueshrink|glueexpr|globaldefs|global|glettonothing|gletcsname|glet|gleaders|gdefcsname|gdef|futurelet|futureexpandisap|futureexpandis|futureexpand|futuredef|futurecsname|frozen|formatname|fonttextcontrol|fontspecyscale|fontspecxscale|fontspecscale|fontspecifiedsize|fontspecifiedname|fontspecid|fontspecdef|fontname|fontmathcontrol|fontid|fontdimen|fontcharwd|fontcharic|fontcharht|fontchardp|font|flushmarks|floatingpenalty|firstvalidlanguage|firstmarks|firstmark|finalhyphendemerits|fi|fam|explicithyphenpenalty|explicitdiscretionary|expandtoken|expandcstoken|expandafterspaces|expandafterpars|expandafter|expand|exhyphenpenalty|exhyphenchar|exceptionpenalty|everyvbox|everytab|everypar|everymath|everyjob|everyhbox|everyeof|everydisplay|everycr|everybeforepar|etokspre|etoksapp|escapechar|errorstopmode|errorcontextlines|errmessage|errhelp|eqno|enforced|endsimplegroup|endlocalcontrol|endlinechar|endinput|endgroup|endcsname|end|emergencystretch|else|efcode|edefcsname|edef|dump|dp|doublehyphendemerits|divide|displaywidth|displaywidowpenalty|displaywidowpenalties|displaystyle|displaylimits|displayindent|discretionary|directlua|dimexpression|dimexpr|dimensiondef|dimendef|dimen|detokenize|delimitershortfall|delimiterfactor|delimiter|delcode|defcsname|defaultskewchar|defaulthyphenchar|def|deadcycles|day|currentmarks|currentiftype|currentiflevel|currentifbranch|currentgrouptype|currentgrouplevel|csstring|csname|crcr|crampedtextstyle|crampedscriptstyle|crampedscriptscriptstyle|crampeddisplaystyle|cr|countdef|count|copy|clubpenalty|clubpenalties|clearmarks|cleaders|chardef|char|catcodetable|catcode|brokenpenalty|boxyoffset|boxymove|boxxoffset|boxxmove|boxtotal|boxshift|boxorientation|boxmaxdepth|boxdirection|boxattribute|box|boundary|botmarks|botmark|binoppenalty|belowdisplayskip|belowdisplayshortskip|beginsimplegroup|beginlocalcontrol|begingroup|begincsname|batchmode|baselineskip|badness|autoparagraphmode|automigrationmode|automatichyphenpenalty|automaticdiscretionary|attributedef|attribute|atopwithdelims|atop|atendofgrouped|atendofgroup|aligntab|alignmark|aligncontent|aliased|aftergrouped|aftergroup|afterassignment|afterassigned|advance|adjustspacingstretch|adjustspacingstep|adjustspacingshrink|adjustspacing|adjdemerits|accent|abovewithdelims|abovedisplayskip|abovedisplayshortskip|above|XeTeXversion|Uvextensible|Uunderdelimiter|Usuperscript|Usuperprescript|Usubscript|Usubprescript|Ustyle|Ustopmath|Ustopdisplaymath|Ustartmath|Ustartdisplaymath|Ustack|Uskewedwithdelims|Uskewed|Uroot|Uright|Uradical|Uoverwithdelims|Uoverdelimiter|Uover|Unosuperscript|Unosuperprescript|Unosubscript|Unosubprescript|Umiddle|Umathyscale|Umathxscale|Umathvoid|Umathvextensiblevariant|Umathunderlinevariant|Umathunderdelimitervgap|Umathunderdelimitervariant|Umathunderdelimiterbgap|Umathunderbarvgap|Umathunderbarrule|Umathunderbarkern|Umathtopaccentvariant|Umathsupsubbottommax|Umathsupshiftup|Umathsupshiftdrop|Umathsuperscriptvariant|Umathsupbottommin|Umathsubtopmax|Umathsubsupvgap|Umathsubsupshiftdown|Umathsubshiftdrop|Umathsubshiftdown|Umathsubscriptvariant|Umathstackvgap|Umathstackvariant|Umathstacknumup|Umathstackdenomdown|Umathspacingmode|Umathspacebeforescript|Umathspaceafterscript|Umathskewedfractionvgap|Umathskewedfractionhgap|Umathrelrelspacing|Umathrelpunctspacing|Umathrelordspacing|Umathrelopspacing|Umathrelopenspacing|Umathrelinnerspacing|Umathrelclosespacing|Umathrelbinspacing|Umathradicalvgap|Umathradicalvariant|Umathradicalrule|Umathradicalkern|Umathradicaldegreeraise|Umathradicaldegreebefore|Umathradicaldegreeafter|Umathquad|Umathpunctrelspacing|Umathpunctpunctspacing|Umathpunctordspacing|Umathpunctopspacing|Umathpunctopenspacing|Umathpunctinnerspacing|Umathpunctclosespacing|Umathpunctbinspacing|Umathphantom|Umathoverlinevariant|Umathoverlayaccentvariant|Umathoverdelimitervgap|Umathoverdelimitervariant|Umathoverdelimiterbgap|Umathoverbarvgap|Umathoverbarrule|Umathoverbarkern|Umathordrelspacing|Umathordpunctspacing|Umathordordspacing|Umathordopspacing|Umathordopenspacing|Umathordinnerspacing|Umathordclosespacing|Umathordbinspacing|Umathoprelspacing|Umathoppunctspacing|Umathopordspacing|Umathopopspacing|Umathopopenspacing|Umathopinnerspacing|Umathoperatorsize|Umathopenupheight|Umathopenupdepth|Umathopenrelspacing|Umathopenpunctspacing|Umathopenordspacing|Umathopenopspacing|Umathopenopenspacing|Umathopeninnerspacing|Umathopenclosespacing|Umathopenbinspacing|Umathopclosespacing|Umathopbinspacing|Umathnumeratorvariant|Umathnolimitsupfactor|Umathnolimitsubfactor|Umathnolimits|Umathnoaxis|Umathlimits|Umathlimitbelowvgap|Umathlimitbelowkern|Umathlimitbelowbgap|Umathlimitabovevgap|Umathlimitabovekern|Umathlimitabovebgap|Umathinnerrelspacing|Umathinnerpunctspacing|Umathinnerordspacing|Umathinneropspacing|Umathinneropenspacing|Umathinnerinnerspacing|Umathinnerclosespacing|Umathinnerbinspacing|Umathhextensiblevariant|Umathfractionvariant|Umathfractionrule|Umathfractionnumvgap|Umathfractionnumup|Umathfractiondenomvgap|Umathfractiondenomdown|Umathfractiondelsize|Umathextrasupshift|Umathextrasuppreshift|Umathextrasubshift|Umathextrasubpreshift|Umathdenominatorvariant|Umathdelimiterundervariant|Umathdelimiterovervariant|Umathdegreevariant|Umathconnectoroverlapmin|Umathcodenum|Umathcode|Umathcloserelspacing|Umathclosepunctspacing|Umathcloseordspacing|Umathcloseopspacing|Umathcloseopenspacing|Umathcloseinnerspacing|Umathcloseclosespacing|Umathclosebinspacing|Umathclass|Umathcharslot|Umathcharnumdef|Umathcharnum|Umathcharfam|Umathchardef|Umathcharclass|Umathchar|Umathbotaccentvariant|Umathbinrelspacing|Umathbinpunctspacing|Umathbinordspacing|Umathbinopspacing|Umathbinopenspacing|Umathbininnerspacing|Umathbinclosespacing|Umathbinbinspacing|Umathaxis|Umathadapttoright|Umathadapttoleft|Umathaccentvariant|Umathaccentbaseheight|Umathaccent|Uleft|Uhextensible|Udelimiterunder|Udelimiterover|Udelimiter|Udelcodenum|Udelcode|Uchar|Uatopwithdelims|Uatop|Uabovewithdelims|Uabove|UUskewedwithdelims|UUskewed|Omegaversion|Omegarevision|Omegaminorversion|Alephversion|Alephrevision|Alephminorversion| )(?=[^a-zA-Z])", + "match" : "\u005C\u005C(year|xtokspre|xtoksapp|xspaceskip|xleaders|xdefcsname|xdef|wrapuppar|wordboundary|widowpenalty|widowpenalties|wd|vtop|vss|vsplit|vskip|vsize|vrule|vpack|vfuzz|vfilneg|vfill|vfil|vcenter|vbox|vbadness|valign|vadjust|uppercase|unvpack|unvcopy|unvbox|untraced|unskip|unpenalty|unletprotected|unletfrozen|unless|unkern|unhpack|unhcopy|unhbox|unexpandedloop|underline|undent|uchyph|uccode|tracingstats|tracingrestores|tracingparagraphs|tracingpages|tracingoutput|tracingonline|tracingnesting|tracingmath|tracingmarks|tracingmacros|tracinglostchars|tracinglevels|tracinginserts|tracingifs|tracinghyphenation|tracinggroups|tracingfullboxes|tracingfonts|tracingexpressions|tracingcommands|tracingassigns|tracingalignments|tracingadjusts|tpack|toscaled|topskip|topmarks|topmark|tolerant|tolerance|tokspre|toksdef|toksapp|toks|tokenized|tointeger|todimension|time|thinmuskip|thickmuskip|thewithoutunit|the|textstyle|textfont|textdirection|tabskip|tabsize|swapcsvalues|supmarkmode|string|splittopskip|splitmaxdepth|splitfirstmarks|splitfirstmark|splitdiscards|splitbotmarks|splitbotmark|span|spaceskip|spacefactor|snapshotpar|skipdef|skip|skewchar|showtokens|showthe|shownodedetails|showlists|showifs|showgroups|showboxdepth|showboxbreadth|showbox|show|shipout|shapingpenalty|shapingpenaltiesmode|sfcode|setlanguage|setfontid|setbox|semiprotected|semiexpanded|scrollmode|scriptstyle|scriptspace|scriptscriptstyle|scriptscriptfont|scriptfont|scantokens|scantextokens|scaledfontdimen|savingvdiscards|savinghyphcodes|savecatcodetable|rpcode|romannumeral|rightskip|rightmarginkern|righthyphenmin|right|retokenized|relpenalty|relax|raise|radical|quitvmode|quitloop|pxdimen|protrusionboundary|protrudechars|protected|prevgraf|prevdepth|pretolerance|prerelpenalty|prehyphenchar|preexhyphenchar|predisplaysize|predisplaypenalty|predisplaygapfactor|predisplaydirection|prebinoppenalty|posthyphenchar|postexhyphenchar|postdisplaypenalty|permanent|penalty|pdfximage|pdfxformresources|pdfxformname|pdfxformmargin|pdfxformattr|pdfxform|pdfvorigin|pdfuniqueresname|pdfuniformdeviate|pdftrailerid|pdftrailer|pdftracingfonts|pdfthreadmargin|pdfthread|pdftexversion|pdftexrevision|pdftexbanner|pdfsuppressptexinfo|pdfsuppressoptionalinfo|pdfstartthread|pdfstartlink|pdfsetrandomseed|pdfsetmatrix|pdfsavepos|pdfsave|pdfretval|pdfrestore|pdfreplacefont|pdfrefximage|pdfrefxform|pdfrefobj|pdfrecompress|pdfrandomseed|pdfpxdimen|pdfprotrudechars|pdfprimitive|pdfpkresolution|pdfpkmode|pdfpkfixeddpi|pdfpagewidth|pdfpagesattr|pdfpageresources|pdfpageref|pdfpageheight|pdfpagebox|pdfpageattr|pdfoutput|pdfoutline|pdfomitcidset|pdfomitcharset|pdfobjcompresslevel|pdfobj|pdfnormaldeviate|pdfnoligatures|pdfnames|pdfminorversion|pdfmapline|pdfmapfile|pdfmajorversion|pdfliteral|pdflinkmargin|pdflastypos|pdflastxpos|pdflastximagepages|pdflastximage|pdflastxform|pdflastobj|pdflastlink|pdflastlinedepth|pdflastannot|pdfinsertht|pdfinfoomitdate|pdfinfo|pdfinclusionerrorlevel|pdfinclusioncopyfonts|pdfincludechars|pdfimageresolution|pdfimagehicolor|pdfimagegamma|pdfimageapplygamma|pdfimageaddfilename|pdfignoreunknownimages|pdfignoreddimen|pdfhorigin|pdfglyphtounicode|pdfgentounicode|pdfgamma|pdffontsize|pdffontobjnum|pdffontname|pdffontexpand|pdffontattr|pdffirstlineheight|pdfendthread|pdfendlink|pdfeachlineheight|pdfeachlinedepth|pdfdraftmode|pdfdestmargin|pdfdest|pdfdecimaldigits|pdfcreationdate|pdfcopyfont|pdfcompresslevel|pdfcolorstackinit|pdfcolorstack|pdfcatalog|pdfannot|pdfadjustspacing|pausing|patterns|parskip|parshapelength|parshapeindent|parshapedimen|parshape|parindent|parfillskip|pardirection|parattribute|parametermark|parametercount|par|pagevsize|pagetotal|pagestretch|pageshrink|pagegoal|pagefilstretch|pagefillstretch|pagefilllstretch|pagediscards|pagedepth|pageboundary|overwithdelims|overshoot|overloadmode|overloaded|overline|overfullrule|over|outputpenalty|outputbox|output|outer|orunless|orphanpenalty|orphanpenalties|orelse|or|omit|numexpression|numexpr|numericscale|number|nullfont|nulldelimiterspace|novrule|nospaces|normalyear|normalxtokspre|normalxtoksapp|normalxspaceskip|normalxleaders|normalxdefcsname|normalxdef|normalwrapuppar|normalwordboundary|normalwidowpenalty|normalwidowpenalties|normalwd|normalvtop|normalvss|normalvsplit|normalvskip|normalvsize|normalvrule|normalvpack|normalvfuzz|normalvfilneg|normalvfill|normalvfil|normalvcenter|normalvbox|normalvbadness|normalvalign|normalvadjust|normaluppercase|normalunvpack|normalunvcopy|normalunvbox|normaluntraced|normalunskip|normalunpenalty|normalunletprotected|normalunletfrozen|normalunless|normalunkern|normalunhpack|normalunhcopy|normalunhbox|normalunexpandedloop|normalunexpanded|normalunderline|normalundent|normaluchyph|normaluccode|normaltracingstats|normaltracingrestores|normaltracingparagraphs|normaltracingpages|normaltracingoutput|normaltracingonline|normaltracingnesting|normaltracingmath|normaltracingmarks|normaltracingmacros|normaltracinglostchars|normaltracinglevels|normaltracinginserts|normaltracingifs|normaltracinghyphenation|normaltracinggroups|normaltracingfullboxes|normaltracingfonts|normaltracingexpressions|normaltracingcommands|normaltracingassigns|normaltracingalignments|normaltracingadjusts|normaltpack|normaltoscaled|normaltopskip|normaltopmarks|normaltopmark|normaltolerant|normaltolerance|normaltokspre|normaltoksdef|normaltoksapp|normaltoks|normaltokenized|normaltointeger|normaltodimension|normaltime|normalthinmuskip|normalthickmuskip|normalthewithoutunit|normalthe|normaltextstyle|normaltextfont|normaltextdirection|normaltabskip|normaltabsize|normalswapcsvalues|normalsupmarkmode|normalstring|normalsplittopskip|normalsplitmaxdepth|normalsplitfirstmarks|normalsplitfirstmark|normalsplitdiscards|normalsplitbotmarks|normalsplitbotmark|normalspan|normalspaceskip|normalspacefactor|normalsnapshotpar|normalskipdef|normalskip|normalskewchar|normalshowtokens|normalshowthe|normalshownodedetails|normalshowlists|normalshowifs|normalshowgroups|normalshowboxdepth|normalshowboxbreadth|normalshowbox|normalshow|normalshipout|normalshapingpenalty|normalshapingpenaltiesmode|normalsfcode|normalsetlanguage|normalsetfontid|normalsetbox|normalsemiprotected|normalsemiexpanded|normalscrollmode|normalscriptstyle|normalscriptspace|normalscriptscriptstyle|normalscriptscriptfont|normalscriptfont|normalscantokens|normalscantextokens|normalscaledfontdimen|normalsavingvdiscards|normalsavinghyphcodes|normalsavecatcodetable|normalrpcode|normalromannumeral|normalrightskip|normalrightmarginkern|normalrighthyphenmin|normalright|normalretokenized|normalrelpenalty|normalrelax|normalraise|normalradical|normalquitvmode|normalquitloop|normalpxdimen|normalprotrusionboundary|normalprotrudechars|normalprotected|normalprevgraf|normalprevdepth|normalpretolerance|normalprerelpenalty|normalprehyphenchar|normalpreexhyphenchar|normalpredisplaysize|normalpredisplaypenalty|normalpredisplaygapfactor|normalpredisplaydirection|normalprebinoppenalty|normalposthyphenchar|normalpostexhyphenchar|normalpostdisplaypenalty|normalpermanent|normalpenalty|normalpdfximage|normalpdfxformresources|normalpdfxformname|normalpdfxformmargin|normalpdfxformattr|normalpdfxform|normalpdfvorigin|normalpdfuniqueresname|normalpdfuniformdeviate|normalpdftrailerid|normalpdftrailer|normalpdftracingfonts|normalpdfthreadmargin|normalpdfthread|normalpdftexversion|normalpdftexrevision|normalpdftexbanner|normalpdfsuppressptexinfo|normalpdfsuppressoptionalinfo|normalpdfstartthread|normalpdfstartlink|normalpdfsetrandomseed|normalpdfsetmatrix|normalpdfsavepos|normalpdfsave|normalpdfretval|normalpdfrestore|normalpdfreplacefont|normalpdfrefximage|normalpdfrefxform|normalpdfrefobj|normalpdfrecompress|normalpdfrandomseed|normalpdfpxdimen|normalpdfprotrudechars|normalpdfprimitive|normalpdfpkresolution|normalpdfpkmode|normalpdfpkfixeddpi|normalpdfpagewidth|normalpdfpagesattr|normalpdfpageresources|normalpdfpageref|normalpdfpageheight|normalpdfpagebox|normalpdfpageattr|normalpdfoutput|normalpdfoutline|normalpdfomitcidset|normalpdfomitcharset|normalpdfobjcompresslevel|normalpdfobj|normalpdfnormaldeviate|normalpdfnoligatures|normalpdfnames|normalpdfminorversion|normalpdfmapline|normalpdfmapfile|normalpdfmajorversion|normalpdfliteral|normalpdflinkmargin|normalpdflastypos|normalpdflastxpos|normalpdflastximagepages|normalpdflastximage|normalpdflastxform|normalpdflastobj|normalpdflastlink|normalpdflastlinedepth|normalpdflastannot|normalpdfinsertht|normalpdfinfoomitdate|normalpdfinfo|normalpdfinclusionerrorlevel|normalpdfinclusioncopyfonts|normalpdfincludechars|normalpdfimageresolution|normalpdfimagehicolor|normalpdfimagegamma|normalpdfimageapplygamma|normalpdfimageaddfilename|normalpdfignoreunknownimages|normalpdfignoreddimen|normalpdfhorigin|normalpdfglyphtounicode|normalpdfgentounicode|normalpdfgamma|normalpdffontsize|normalpdffontobjnum|normalpdffontname|normalpdffontexpand|normalpdffontattr|normalpdffirstlineheight|normalpdfendthread|normalpdfendlink|normalpdfeachlineheight|normalpdfeachlinedepth|normalpdfdraftmode|normalpdfdestmargin|normalpdfdest|normalpdfdecimaldigits|normalpdfcreationdate|normalpdfcopyfont|normalpdfcompresslevel|normalpdfcolorstackinit|normalpdfcolorstack|normalpdfcatalog|normalpdfannot|normalpdfadjustspacing|normalpausing|normalpatterns|normalparskip|normalparshapelength|normalparshapeindent|normalparshapedimen|normalparshape|normalparindent|normalparfillskip|normalparfillleftskip|normalpardirection|normalparattribute|normalparametermark|normalparametercount|normalpar|normalpagevsize|normalpagetotal|normalpagestretch|normalpageshrink|normalpagegoal|normalpagefilstretch|normalpagefillstretch|normalpagefilllstretch|normalpagediscards|normalpagedepth|normalpageboundary|normaloverwithdelims|normalovershoot|normaloverloadmode|normaloverloaded|normaloverline|normaloverfullrule|normalover|normaloutputpenalty|normaloutputbox|normaloutput|normalouter|normalorunless|normalorphanpenalty|normalorphanpenalties|normalorelse|normalor|normalomit|normalnumexpression|normalnumexpr|normalnumericscale|normalnumber|normalnullfont|normalnulldelimiterspace|normalnovrule|normalnospaces|normalnormalizelinemode|normalnorelax|normalnonstopmode|normalnonscript|normalnolimits|normalnoindent|normalnohrule|normalnoexpand|normalnoboundary|normalnoaligned|normalnoalign|normalnewlinechar|normalmutoglue|normalmutable|normalmuskipdef|normalmuskip|normalmultiply|normalmugluespecdef|normalmuexpr|normalmskip|normalmoveright|normalmoveleft|normalmonth|normalmkern|normalmiddle|normalmessage|normalmedmuskip|normalmeaningless|normalmeaningfull|normalmeaningasis|normalmeaning|normalmaxdepth|normalmaxdeadcycles|normalmathsurroundskip|normalmathsurroundmode|normalmathsurround|normalmathstyle|normalmathscriptsmode|normalmathscriptcharmode|normalmathscriptboxmode|normalmathscale|normalmathrulethicknessmode|normalmathrulesmode|normalmathrulesfam|normalmathrel|normalmathpunct|normalmathpenaltiesmode|normalmathord|normalmathopen|normalmathop|normalmathnolimitsmode|normalmathlimitsmode|normalmathinner|normalmathfontcontrol|normalmathflattenmode|normalmatheqnogapstep|normalmathdisplayskipmode|normalmathdirection|normalmathdelimitersmode|normalmathcontrolmode|normalmathcode|normalmathclose|normalmathchoice|normalmathchardef|normalmathchar|normalmathbin|normalmathaccent|normalmarks|normalmark|normalluatexversion|normalluatexrevision|normalluatexbanner|normalluafunctioncall|normalluafunction|normalluaescapestring|normalluadef|normalluacopyinputnodes|normalluabytecodecall|normalluabytecode|normallpcode|normallowercase|normallower|normallooseness|normallong|normallocalrightboxbox|normallocalrightbox|normallocalmiddleboxbox|normallocalmiddlebox|normallocalleftboxbox|normallocalleftbox|normallocalinterlinepenalty|normallocalcontrolledloop|normallocalcontrolled|normallocalcontrol|normallocalbrokenpenalty|normallineskiplimit|normallineskip|normallinepenalty|normallinedirection|normallimits|normallettonothing|normalletprotected|normalletfrozen|normalletcsname|normalletcharcode|normallet|normalleqno|normalleftskip|normalleftmarginkern|normallefthyphenmin|normalleft|normalleaders|normallccode|normallastskip|normallastpenalty|normallastparcontext|normallastnodetype|normallastnodesubtype|normallastnamedcs|normallastlinefit|normallastkern|normallastchknum|normallastchkdim|normallastbox|normallastarguments|normallanguage|normalkern|normaljobname|normalizelinemode|normalinterlinepenalty|normalinterlinepenalties|normalinteractionmode|normalintegerdef|normalinstance|normalinsertwidth|normalinsertuncopy|normalinsertunbox|normalinsertstoring|normalinsertstorage|normalinsertprogress|normalinsertpenalty|normalinsertpenalties|normalinsertmultiplier|normalinsertmode|normalinsertmaxdepth|normalinsertlimit|normalinsertheights|normalinsertheight|normalinsertdistance|normalinsertdepth|normalinsertcopy|normalinsertbox|normalinsert|normalinputlineno|normalinput|normalinitcatcodetable|normalindent|normalimmutable|normalimmediate|normalignorespaces|normalignorepars|normalignorearguments|normalifx|normalifvoid|normalifvmode|normalifvbox|normaliftrue|normaliftok|normalifrelax|normalifpdfprimitive|normalifpdfabsnum|normalifpdfabsdim|normalifparameters|normalifparameter|normalifodd|normalifnumval|normalifnumexpression|normalifnum|normalifmmode|normalifmathstyle|normalifmathparameter|normalifinsert|normalifinner|normalifincsname|normalifhmode|normalifhbox|normalifhasxtoks|normalifhastoks|normalifhastok|normalifhaschar|normaliffontchar|normalifflags|normaliffalse|normalifempty|normalifdimval|normalifdimexpression|normalifdim|normalifdefined|normalifcstok|normalifcsname|normalifcondition|normalifcmpnum|normalifcmpdim|normalifchknum|normalifchkdim|normalifcat|normalifcase|normalifboolean|normalifarguments|normalifabsnum|normalifabsdim|normalif|normalhyphenpenalty|normalhyphenchar|normalhyphenationmode|normalhyphenationmin|normalhyphenation|normalht|normalhss|normalhskip|normalhsize|normalhrule|normalhpack|normalholdinginserts|normalhjcode|normalhfuzz|normalhfilneg|normalhfill|normalhfil|normalhccode|normalhbox|normalhbadness|normalhangindent|normalhangafter|normalhalign|normalgtokspre|normalgtoksapp|normalglyphyscale|normalglyphyoffset|normalglyphxscale|normalglyphxoffset|normalglyphtextscale|normalglyphstatefield|normalglyphscriptscriptscale|normalglyphscriptscale|normalglyphscriptfield|normalglyphscale|normalglyphoptions|normalglyphdatafield|normalglyph|normalgluetomu|normalgluestretchorder|normalgluestretch|normalgluespecdef|normalglueshrinkorder|normalglueshrink|normalglueexpr|normalglobaldefs|normalglobal|normalglettonothing|normalgletcsname|normalglet|normalgleaders|normalgdefcsname|normalgdef|normalfuturelet|normalfutureexpandisap|normalfutureexpandis|normalfutureexpand|normalfuturedef|normalfuturecsname|normalfrozen|normalformatname|normalfonttextcontrol|normalfontspecyscale|normalfontspecxscale|normalfontspecscale|normalfontspecifiedsize|normalfontspecifiedname|normalfontspecid|normalfontspecdef|normalfontname|normalfontmathcontrol|normalfontid|normalfontdimen|normalfontcharwd|normalfontcharic|normalfontcharht|normalfontchardp|normalfont|normalflushmarks|normalfloatingpenalty|normalfirstvalidlanguage|normalfirstmarks|normalfirstmark|normalfinalhyphendemerits|normalfi|normalfam|normalexplicithyphenpenalty|normalexplicitdiscretionary|normalexpandtoken|normalexpandedloop|normalexpanded|normalexpandcstoken|normalexpandafterspaces|normalexpandafterpars|normalexpandafter|normalexpand|normalexhyphenpenalty|normalexhyphenchar|normalexceptionpenalty|normaleveryvbox|normaleverytab|normaleverypar|normaleverymath|normaleveryjob|normaleveryhbox|normaleveryeof|normaleverydisplay|normaleverycr|normaleverybeforepar|normaletokspre|normaletoksapp|normalescapechar|normalerrorstopmode|normalerrorcontextlines|normalerrmessage|normalerrhelp|normaleqno|normalenforced|normalendsimplegroup|normalendlocalcontrol|normalendlinechar|normalendinput|normalendgroup|normalendcsname|normalend|normalemergencystretch|normalelse|normalefcode|normaledefcsname|normaledef|normaldump|normaldp|normaldoublehyphendemerits|normaldivide|normaldisplaywidth|normaldisplaywidowpenalty|normaldisplaywidowpenalties|normaldisplaystyle|normaldisplaylimits|normaldisplayindent|normaldiscretionary|normaldirectlua|normaldimexpression|normaldimexpr|normaldimensiondef|normaldimendef|normaldimen|normaldetokenize|normaldelimitershortfall|normaldelimiterfactor|normaldelimiter|normaldelcode|normaldefcsname|normaldefaultskewchar|normaldefaulthyphenchar|normaldef|normaldeadcycles|normalday|normalcurrentmarks|normalcurrentloopnesting|normalcurrentloopiterator|normalcurrentiftype|normalcurrentiflevel|normalcurrentifbranch|normalcurrentgrouptype|normalcurrentgrouplevel|normalcsstring|normalcsname|normalcrcr|normalcrampedtextstyle|normalcrampedscriptstyle|normalcrampedscriptscriptstyle|normalcrampeddisplaystyle|normalcr|normalcountdef|normalcount|normalcopy|normalclubpenalty|normalclubpenalties|normalclearmarks|normalcleaders|normalchardef|normalchar|normalcatcodetable|normalcatcode|normalbrokenpenalty|normalboxyoffset|normalboxymove|normalboxxoffset|normalboxxmove|normalboxtotal|normalboxshift|normalboxorientation|normalboxmaxdepth|normalboxdirection|normalboxattribute|normalbox|normalboundary|normalbotmarks|normalbotmark|normalbinoppenalty|normalbelowdisplayskip|normalbelowdisplayshortskip|normalbeginsimplegroup|normalbeginlocalcontrol|normalbegingroup|normalbegincsname|normalbatchmode|normalbaselineskip|normalbadness|normalautoparagraphmode|normalautomigrationmode|normalautomatichyphenpenalty|normalautomaticdiscretionary|normalattributedef|normalattribute|normalatopwithdelims|normalatop|normalatendofgrouped|normalatendofgroup|normalaligntab|normalalignmark|normalaligncontent|normalaliased|normalaftergrouped|normalaftergroup|normalafterassignment|normalafterassigned|normaladvance|normaladjustspacingstretch|normaladjustspacingstep|normaladjustspacingshrink|normaladjustspacing|normaladjdemerits|normalaccent|normalabovewithdelims|normalabovedisplayskip|normalabovedisplayshortskip|normalabove|normalXeTeXversion|normalUvextensible|normalUunderdelimiter|normalUsuperscript|normalUsuperprescript|normalUsubscript|normalUsubprescript|normalUstyle|normalUstopmath|normalUstopdisplaymath|normalUstartmath|normalUstartdisplaymath|normalUstack|normalUskewedwithdelims|normalUskewed|normalUroot|normalUright|normalUradical|normalUoverwithdelims|normalUoverdelimiter|normalUover|normalUnosuperscript|normalUnosuperprescript|normalUnosubscript|normalUnosubprescript|normalUmiddle|normalUmathyscale|normalUmathxscale|normalUmathvoid|normalUmathvextensiblevariant|normalUmathunderlinevariant|normalUmathunderdelimitervgap|normalUmathunderdelimitervariant|normalUmathunderdelimiterbgap|normalUmathunderbarvgap|normalUmathunderbarrule|normalUmathunderbarkern|normalUmathtopaccentvariant|normalUmathsupsubbottommax|normalUmathsupshiftup|normalUmathsupshiftdrop|normalUmathsuperscriptvariant|normalUmathsupbottommin|normalUmathsubtopmax|normalUmathsubsupvgap|normalUmathsubsupshiftdown|normalUmathsubshiftdrop|normalUmathsubshiftdown|normalUmathsubscriptvariant|normalUmathstackvgap|normalUmathstackvariant|normalUmathstacknumup|normalUmathstackdenomdown|normalUmathspacingmode|normalUmathspacebeforescript|normalUmathspaceafterscript|normalUmathskewedfractionvgap|normalUmathskewedfractionhgap|normalUmathrelrelspacing|normalUmathrelpunctspacing|normalUmathrelordspacing|normalUmathrelopspacing|normalUmathrelopenspacing|normalUmathrelinnerspacing|normalUmathrelclosespacing|normalUmathrelbinspacing|normalUmathradicalvgap|normalUmathradicalvariant|normalUmathradicalrule|normalUmathradicalkern|normalUmathradicaldegreeraise|normalUmathradicaldegreebefore|normalUmathradicaldegreeafter|normalUmathquad|normalUmathpunctrelspacing|normalUmathpunctpunctspacing|normalUmathpunctordspacing|normalUmathpunctopspacing|normalUmathpunctopenspacing|normalUmathpunctinnerspacing|normalUmathpunctclosespacing|normalUmathpunctbinspacing|normalUmathphantom|normalUmathoverlinevariant|normalUmathoverlayaccentvariant|normalUmathoverdelimitervgap|normalUmathoverdelimitervariant|normalUmathoverdelimiterbgap|normalUmathoverbarvgap|normalUmathoverbarrule|normalUmathoverbarkern|normalUmathordrelspacing|normalUmathordpunctspacing|normalUmathordordspacing|normalUmathordopspacing|normalUmathordopenspacing|normalUmathordinnerspacing|normalUmathordclosespacing|normalUmathordbinspacing|normalUmathoprelspacing|normalUmathoppunctspacing|normalUmathopordspacing|normalUmathopopspacing|normalUmathopopenspacing|normalUmathopinnerspacing|normalUmathoperatorsize|normalUmathopenupheight|normalUmathopenupdepth|normalUmathopenrelspacing|normalUmathopenpunctspacing|normalUmathopenordspacing|normalUmathopenopspacing|normalUmathopenopenspacing|normalUmathopeninnerspacing|normalUmathopenclosespacing|normalUmathopenbinspacing|normalUmathopclosespacing|normalUmathopbinspacing|normalUmathnumeratorvariant|normalUmathnolimitsupfactor|normalUmathnolimitsubfactor|normalUmathnolimits|normalUmathnoaxis|normalUmathlimits|normalUmathlimitbelowvgap|normalUmathlimitbelowkern|normalUmathlimitbelowbgap|normalUmathlimitabovevgap|normalUmathlimitabovekern|normalUmathlimitabovebgap|normalUmathinnerrelspacing|normalUmathinnerpunctspacing|normalUmathinnerordspacing|normalUmathinneropspacing|normalUmathinneropenspacing|normalUmathinnerinnerspacing|normalUmathinnerclosespacing|normalUmathinnerbinspacing|normalUmathhextensiblevariant|normalUmathfractionvariant|normalUmathfractionrule|normalUmathfractionnumvgap|normalUmathfractionnumup|normalUmathfractiondenomvgap|normalUmathfractiondenomdown|normalUmathfractiondelsize|normalUmathextrasupshift|normalUmathextrasuppreshift|normalUmathextrasubshift|normalUmathextrasubpreshift|normalUmathdenominatorvariant|normalUmathdelimiterundervariant|normalUmathdelimiterovervariant|normalUmathdegreevariant|normalUmathconnectoroverlapmin|normalUmathcodenum|normalUmathcode|normalUmathcloserelspacing|normalUmathclosepunctspacing|normalUmathcloseordspacing|normalUmathcloseopspacing|normalUmathcloseopenspacing|normalUmathcloseinnerspacing|normalUmathcloseclosespacing|normalUmathclosebinspacing|normalUmathclass|normalUmathcharslot|normalUmathcharnumdef|normalUmathcharnum|normalUmathcharfam|normalUmathchardef|normalUmathcharclass|normalUmathchar|normalUmathbotaccentvariant|normalUmathbinrelspacing|normalUmathbinpunctspacing|normalUmathbinordspacing|normalUmathbinopspacing|normalUmathbinopenspacing|normalUmathbininnerspacing|normalUmathbinclosespacing|normalUmathbinbinspacing|normalUmathaxis|normalUmathadapttoright|normalUmathadapttoleft|normalUmathaccentvariant|normalUmathaccentbaseheight|normalUmathaccent|normalUleft|normalUhextensible|normalUdelimiterunder|normalUdelimiterover|normalUdelimiter|normalUdelcodenum|normalUdelcode|normalUchar|normalUatopwithdelims|normalUatop|normalUabovewithdelims|normalUabove|normalUUskewedwithdelims|normalUUskewed|normalOmegaversion|normalOmegarevision|normalOmegaminorversion|normalAlephversion|normalAlephrevision|normalAlephminorversion|normal |norelax|nonstopmode|nonscript|nolimits|noindent|nohrule|noexpand|noboundary|noaligned|noalign|newlinechar|mutoglue|mutable|muskipdef|muskip|multiply|mugluespecdef|muexpr|mskip|moveright|moveleft|month|mkern|middle|message|medmuskip|meaningless|meaningfull|meaningasis|meaning|maxdepth|maxdeadcycles|mathsurroundskip|mathsurroundmode|mathsurround|mathstyle|mathscriptsmode|mathscriptcharmode|mathscriptboxmode|mathscale|mathrulethicknessmode|mathrulesmode|mathrulesfam|mathrel|mathpunct|mathpenaltiesmode|mathord|mathopen|mathop|mathnolimitsmode|mathlimitsmode|mathinner|mathfontcontrol|mathflattenmode|matheqnogapstep|mathdisplayskipmode|mathdirection|mathdelimitersmode|mathcontrolmode|mathcode|mathclose|mathchoice|mathchardef|mathchar|mathbin|mathaccent|marks|mark|luatexversion|luatexrevision|luatexbanner|luafunctioncall|luafunction|luaescapestring|luadef|luacopyinputnodes|luabytecodecall|luabytecode|lpcode|lowercase|lower|looseness|long|localrightboxbox|localrightbox|localmiddleboxbox|localmiddlebox|localleftboxbox|localleftbox|localinterlinepenalty|localcontrolledloop|localcontrolled|localcontrol|localbrokenpenalty|lineskiplimit|lineskip|linepenalty|linedirection|limits|lettonothing|letprotected|letfrozen|letcsname|letcharcode|let|leqno|leftskip|leftmarginkern|lefthyphenmin|left|leaders|lccode|lastskip|lastpenalty|lastparcontext|lastnodetype|lastnodesubtype|lastnamedcs|lastlinefit|lastkern|lastchknum|lastchkdim|lastbox|lastarguments|language|kern|jobname|interlinepenalty|interlinepenalties|interactionmode|integerdef|instance|insertwidth|insertuncopy|insertunbox|insertstoring|insertstorage|insertprogress|insertpenalty|insertpenalties|insertmultiplier|insertmode|insertmaxdepth|insertlimit|insertheights|insertheight|insertdistance|insertdepth|insertcopy|insertbox|insert|inputlineno|input|initcatcodetable|indent|immutable|immediate|ignorespaces|ignorepars|ignorearguments|ifx|ifvoid|ifvmode|ifvbox|iftrue|iftok|ifrelax|ifpdfprimitive|ifpdfabsnum|ifpdfabsdim|ifparameters|ifparameter|ifodd|ifnumval|ifnumexpression|ifnum|ifmmode|ifmathstyle|ifmathparameter|ifinsert|ifinner|ifincsname|ifhmode|ifhbox|ifhasxtoks|ifhastoks|ifhastok|ifhaschar|iffontchar|ifflags|iffalse|ifempty|ifdimval|ifdimexpression|ifdim|ifdefined|ifcstok|ifcsname|ifcondition|ifcmpnum|ifcmpdim|ifchknum|ifchkdim|ifcat|ifcase|ifboolean|ifarguments|ifabsnum|ifabsdim|if|hyphenpenalty|hyphenchar|hyphenationmode|hyphenationmin|hyphenation|ht|hss|hskip|hsize|hrule|hpack|holdinginserts|hjcode|hfuzz|hfilneg|hfill|hfil|hccode|hbox|hbadness|hangindent|hangafter|halign|gtokspre|gtoksapp|glyphyscale|glyphyoffset|glyphxscale|glyphxoffset|glyphtextscale|glyphstatefield|glyphscriptscriptscale|glyphscriptscale|glyphscriptfield|glyphscale|glyphoptions|glyphdatafield|glyph|gluetomu|gluestretchorder|gluestretch|gluespecdef|glueshrinkorder|glueshrink|glueexpr|globaldefs|global|glettonothing|gletcsname|glet|gleaders|gdefcsname|gdef|futurelet|futureexpandisap|futureexpandis|futureexpand|futuredef|futurecsname|frozen|formatname|fonttextcontrol|fontspecyscale|fontspecxscale|fontspecscale|fontspecifiedsize|fontspecifiedname|fontspecid|fontspecdef|fontname|fontmathcontrol|fontid|fontdimen|fontcharwd|fontcharic|fontcharht|fontchardp|font|flushmarks|floatingpenalty|firstvalidlanguage|firstmarks|firstmark|finalhyphendemerits|fi|fam|explicithyphenpenalty|explicitdiscretionary|expandtoken|expandedloop|expandcstoken|expandafterspaces|expandafterpars|expandafter|expand|exhyphenpenalty|exhyphenchar|exceptionpenalty|everyvbox|everytab|everypar|everymath|everyjob|everyhbox|everyeof|everydisplay|everycr|everybeforepar|etokspre|etoksapp|escapechar|errorstopmode|errorcontextlines|errmessage|errhelp|eqno|enforced|endsimplegroup|endlocalcontrol|endlinechar|endinput|endgroup|endcsname|end|emergencystretch|else|efcode|edefcsname|edef|dump|dp|doublehyphendemerits|divide|displaywidth|displaywidowpenalty|displaywidowpenalties|displaystyle|displaylimits|displayindent|discretionary|directlua|dimexpression|dimexpr|dimensiondef|dimendef|dimen|detokenize|delimitershortfall|delimiterfactor|delimiter|delcode|defcsname|defaultskewchar|defaulthyphenchar|def|deadcycles|day|currentmarks|currentloopnesting|currentloopiterator|currentiftype|currentiflevel|currentifbranch|currentgrouptype|currentgrouplevel|csstring|csname|crcr|crampedtextstyle|crampedscriptstyle|crampedscriptscriptstyle|crampeddisplaystyle|cr|countdef|count|copy|clubpenalty|clubpenalties|clearmarks|cleaders|chardef|char|catcodetable|catcode|brokenpenalty|boxyoffset|boxymove|boxxoffset|boxxmove|boxtotal|boxshift|boxorientation|boxmaxdepth|boxdirection|boxattribute|box|boundary|botmarks|botmark|binoppenalty|belowdisplayskip|belowdisplayshortskip|beginsimplegroup|beginlocalcontrol|begingroup|begincsname|batchmode|baselineskip|badness|autoparagraphmode|automigrationmode|automatichyphenpenalty|automaticdiscretionary|attributedef|attribute|atopwithdelims|atop|atendofgrouped|atendofgroup|aligntab|alignmark|aligncontent|aliased|aftergrouped|aftergroup|afterassignment|afterassigned|advance|adjustspacingstretch|adjustspacingstep|adjustspacingshrink|adjustspacing|adjdemerits|accent|abovewithdelims|abovedisplayskip|abovedisplayshortskip|above|XeTeXversion|Uvextensible|Uunderdelimiter|Usuperscript|Usuperprescript|Usubscript|Usubprescript|Ustyle|Ustopmath|Ustopdisplaymath|Ustartmath|Ustartdisplaymath|Ustack|Uskewedwithdelims|Uskewed|Uroot|Uright|Uradical|Uoverwithdelims|Uoverdelimiter|Uover|Unosuperscript|Unosuperprescript|Unosubscript|Unosubprescript|Umiddle|Umathyscale|Umathxscale|Umathvoid|Umathvextensiblevariant|Umathunderlinevariant|Umathunderdelimitervgap|Umathunderdelimitervariant|Umathunderdelimiterbgap|Umathunderbarvgap|Umathunderbarrule|Umathunderbarkern|Umathtopaccentvariant|Umathsupsubbottommax|Umathsupshiftup|Umathsupshiftdrop|Umathsuperscriptvariant|Umathsupbottommin|Umathsubtopmax|Umathsubsupvgap|Umathsubsupshiftdown|Umathsubshiftdrop|Umathsubshiftdown|Umathsubscriptvariant|Umathstackvgap|Umathstackvariant|Umathstacknumup|Umathstackdenomdown|Umathspacingmode|Umathspacebeforescript|Umathspaceafterscript|Umathskewedfractionvgap|Umathskewedfractionhgap|Umathrelrelspacing|Umathrelpunctspacing|Umathrelordspacing|Umathrelopspacing|Umathrelopenspacing|Umathrelinnerspacing|Umathrelclosespacing|Umathrelbinspacing|Umathradicalvgap|Umathradicalvariant|Umathradicalrule|Umathradicalkern|Umathradicaldegreeraise|Umathradicaldegreebefore|Umathradicaldegreeafter|Umathquad|Umathpunctrelspacing|Umathpunctpunctspacing|Umathpunctordspacing|Umathpunctopspacing|Umathpunctopenspacing|Umathpunctinnerspacing|Umathpunctclosespacing|Umathpunctbinspacing|Umathphantom|Umathoverlinevariant|Umathoverlayaccentvariant|Umathoverdelimitervgap|Umathoverdelimitervariant|Umathoverdelimiterbgap|Umathoverbarvgap|Umathoverbarrule|Umathoverbarkern|Umathordrelspacing|Umathordpunctspacing|Umathordordspacing|Umathordopspacing|Umathordopenspacing|Umathordinnerspacing|Umathordclosespacing|Umathordbinspacing|Umathoprelspacing|Umathoppunctspacing|Umathopordspacing|Umathopopspacing|Umathopopenspacing|Umathopinnerspacing|Umathoperatorsize|Umathopenupheight|Umathopenupdepth|Umathopenrelspacing|Umathopenpunctspacing|Umathopenordspacing|Umathopenopspacing|Umathopenopenspacing|Umathopeninnerspacing|Umathopenclosespacing|Umathopenbinspacing|Umathopclosespacing|Umathopbinspacing|Umathnumeratorvariant|Umathnolimitsupfactor|Umathnolimitsubfactor|Umathnolimits|Umathnoaxis|Umathlimits|Umathlimitbelowvgap|Umathlimitbelowkern|Umathlimitbelowbgap|Umathlimitabovevgap|Umathlimitabovekern|Umathlimitabovebgap|Umathinnerrelspacing|Umathinnerpunctspacing|Umathinnerordspacing|Umathinneropspacing|Umathinneropenspacing|Umathinnerinnerspacing|Umathinnerclosespacing|Umathinnerbinspacing|Umathhextensiblevariant|Umathfractionvariant|Umathfractionrule|Umathfractionnumvgap|Umathfractionnumup|Umathfractiondenomvgap|Umathfractiondenomdown|Umathfractiondelsize|Umathextrasupshift|Umathextrasuppreshift|Umathextrasubshift|Umathextrasubpreshift|Umathdenominatorvariant|Umathdelimiterundervariant|Umathdelimiterovervariant|Umathdegreevariant|Umathconnectoroverlapmin|Umathcodenum|Umathcode|Umathcloserelspacing|Umathclosepunctspacing|Umathcloseordspacing|Umathcloseopspacing|Umathcloseopenspacing|Umathcloseinnerspacing|Umathcloseclosespacing|Umathclosebinspacing|Umathclass|Umathcharslot|Umathcharnumdef|Umathcharnum|Umathcharfam|Umathchardef|Umathcharclass|Umathchar|Umathbotaccentvariant|Umathbinrelspacing|Umathbinpunctspacing|Umathbinordspacing|Umathbinopspacing|Umathbinopenspacing|Umathbininnerspacing|Umathbinclosespacing|Umathbinbinspacing|Umathaxis|Umathadapttoright|Umathadapttoleft|Umathaccentvariant|Umathaccentbaseheight|Umathaccent|Uleft|Uhextensible|Udelimiterunder|Udelimiterover|Udelimiter|Udelcodenum|Udelcode|Uchar|Uatopwithdelims|Uatop|Uabovewithdelims|Uabove|UUskewedwithdelims|UUskewed|Omegaversion|Omegarevision|Omegaminorversion|Alephversion|Alephrevision|Alephminorversion| )(?=[^a-zA-Z])", "name" : "context.primitive.commands.primitive.tex" }, "reserved" : { diff --git a/doc/context/documents/general/manuals/lowlevel-localboxes.pdf b/doc/context/documents/general/manuals/lowlevel-localboxes.pdf Binary files differdeleted file mode 100644 index 66de25c6a..000000000 --- a/doc/context/documents/general/manuals/lowlevel-localboxes.pdf +++ /dev/null diff --git a/doc/context/documents/general/manuals/lowlevel-loops.pdf b/doc/context/documents/general/manuals/lowlevel-loops.pdf Binary files differnew file mode 100644 index 000000000..e47919f75 --- /dev/null +++ b/doc/context/documents/general/manuals/lowlevel-loops.pdf diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf Binary files differindex 49347ca50..123c3f000 100644 --- a/doc/context/documents/general/manuals/luametatex.pdf +++ b/doc/context/documents/general/manuals/luametatex.pdf diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex new file mode 100644 index 000000000..e4dfd7667 --- /dev/null +++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex @@ -0,0 +1,327 @@ +% language=us runpath=texruns:manuals/lowlevel + +\environment lowlevel-style + +\startdocument + [title=loops, + color=middleyellow] + +\startsectionlevel[title=Introduction] + +I have hesitated long before I finally decided to implement native loops in +\LUAMETATEX. Among the reasons against such a feature is that one can define +macros that do loops (preferably using tail recursion). When you don't need an +expandable loop, counters can be used, otherwise there are dirty and obscure +tricks that can be of help. This is often the area where tex programmers can show +off but the fact remains that we're using side effects of the expansion machinery +and specific primitives like \type {\romannumeral} magic. In \LUAMETATEX\ it is +actually possible to use the local control mechanism to hide loop counter advance +and checking but that comes with at a performance hit. And, no matter what tricks +one used, tracing becomes pretty much cluttered. + +In the next sections we describe the new native loop primitives in \LUAMETATEX\ as +well as the more traditional \CONTEXT\ loop helpers. + +\stopsectionlevel + +\startsectionlevel[title=Primitives] + +Because \METAPOST, which is also a macro language, has native loops, it makes +sense to also have native loops in \TEX\ and in \LUAMETATEX\ it was not that hard +to add it. One variant uses the local control mechanism which is reflected in its +name and two others collect expanded bodies. In the local loop content gets +injected as we go, so this one doesn't work well in for instance an \type +{\edef}. The macro takes the usual three loop numbers as well as a token list: + +\starttyping[option=TEX] +\localcontrolledloop 1 100000 1 {% + % body +} +\stoptyping + +Here is an example of usage: + +\startbuffer +\localcontrolledloop 1 5 1 {% + [\number\currentloopiterator] + \localcontrolledloop 1 10 1 {% + (\number\currentloopiterator) + }% + [\number\currentloopiterator] + \par +} +\stopbuffer + +\typebuffer[option=TEX] + +The \type {\currentloopiterator} is a numeric token so you need to explicitly +serialize it with \type {\number} or \type {\the} if you want it to be typeset: + +\startpacked \getbuffer \stoppacked + +Here is another exmaple. This time we also show the current nesting: + +\startbuffer +\localcontrolledloop 1 100 1 {% + \ifnum\currentloopiterator>6\relax + \quitloop + \else + [\number\currentloopnesting:\number\currentloopiterator] + \localcontrolledloop 1 8 1 {% + (\number\currentloopnesting:\number\currentloopiterator) + }\par + \fi +} +\stopbuffer + +\typebuffer[option=TEX] + +Watch the \type {\quitloop}: it will end the loop at the {\em next} iteration so +any content after it will show up. Normally this one will be issued in a +condition and we want to end that properly. + +\startpacked \getbuffer \stoppacked + +The three loop variants all perform differently: + +\startbuffer +l:\testfeatureonce {1000} {\localcontrolledloop 1 2000 1 {\relax}} % + \elapsedtime +e:\testfeatureonce {1000} {\expandedloop 1 2000 1 {\relax}} % + \elapsedtime +u:\testfeatureonce {1000} {\unexpandedloop 1 2000 1 {\relax}} % + \elapsedtime +\stopbuffer + +\typebuffer[option=TEX] + +An unexpanded loop is (of course) the fastest because it only collects and then +feeds back the lot. In an expanded loop each cycle does an expansion of the body +and collects the result which is then injected afterwards, and the controlled +loop just expands the body each iteration. + +\startlines\tttf \getbuffer \stoplines + +The different behavior is best illustrated with the following example: + +\startbuffer[definition] +\edef\TestA{\localcontrolledloop 1 5 1 {A}} % out of order +\edef\TestB{\expandedloop 1 5 1 {B}} +\edef\TestC{\unexpandedloop 1 5 1 {C\relax}} +\stopbuffer + +\typebuffer[definition][option=TEX] + +We can show the effective definition: + +\startbuffer[example] +\meaningasis\TestA +\meaningasis\TestB +\meaningasis\TestC + +A: \TestA +B: \TestB +C: \TestC +\stopbuffer + +\typebuffer[example][option=TEX] + +Watch how the first test pushes the content in the main input stream: + +\startlines\tttf \getbuffer[definition,example]\stoplines + +Here are some examples that show what gets expanded and what not: + +\startbuffer +\edef\whatever + {\expandedloop 1 10 1 + {(\number\currentloopiterator) + \scratchcounter=\number\currentloopiterator\relax}} + +\meaningasis\whatever +\stopbuffer + +\typebuffer[option=TEX] + +\startpacked \veryraggedright \tt\tfx \getbuffer \stoppacked + +A local control encapsulation hides the assignment: + +\startbuffer +\edef\whatever + {\expandedloop 1 10 1 + {(\number\currentloopiterator) + \beginlocalcontrol + \scratchcounter=\number\currentloopiterator\relax + \endlocalcontrol}} + +\meaningasis\whatever +\stopbuffer + +\typebuffer[option=TEX] + +\blank \start \veryraggedright \tt\tfx \getbuffer \stop \blank + +Here we see the assignment being retained but with changing values: + +\startbuffer +\edef\whatever + {\unexpandedloop 1 10 1 + {\scratchcounter=1\relax}} + +\meaningasis\whatever +\stopbuffer + +\typebuffer[option=TEX] + +\blank \start \veryraggedright \tt\tfx \getbuffer \stop \blank + +We get no expansion at all: + +\startbuffer +\edef\whatever + {\unexpandedloop 1 10 1 + {\scratchcounter=\the\currentloopiterator\relax}} + +\meaningasis\whatever +\stopbuffer + +\typebuffer[option=TEX] + +\blank \start \veryraggedright \tt\tfx \getbuffer \stop \blank + +And here we have a mix: + +\startbuffer +\edef\whatever + {\expandedloop 1 10 1 + {\scratchcounter=\the\currentloopiterator\relax}} + +\meaningasis\whatever +\stopbuffer + +\typebuffer[option=TEX] + +\blank \start \veryraggedright \tt\tfx \getbuffer \stop \blank + +There is one feature worth noting. When you feed three numbers in a row, like here, +there is a danger of them being seen as one: + +\starttyping +\expandedloop + \number\dimexpr1pt + \number\dimexpr2pt + \number\dimexpr1pt + {} +\stoptyping + +This gives an error because a too large number is seen. Therefore, these loops +permit leading equal signs, as in assigments (we could support keywords but +it doesn't make much sense): + +\starttyping +\expandedloop =\number\dimexpr1pt =\number\dimexpr2pt =\number\dimexpr1pt{} +\stoptyping + +\stopsectionlevel + +\startsectionlevel[title=Wrappers] + +We always had loop helpers in \CONTEXT\ and the question is: \quotation {What we +will gain when we replace the definitions with ones using the above?}. The answer +is: \quotation {We have little performance but not as much as one expects!}. This +has to do with the fact that we support \type {#1} as iterator and \type {#2} as +(verbose) nesting values and that comes with some overhead. It is also the reason +why these loop macros are protected (unexpandable). However, using the primitives +might look somewhat more natural in low level \TEX\ code. + +Also, replacing their definitions can have side effects because the primitives are +(and will be) still experimental so it's typically a patch that I will run on my +machine for a while. + +Here is an example of two loops. The inner state variables have one hash, the outer +one extra: + +\startbuffer +\dorecurse{2}{ + \dostepwiserecurse{1}{10}{2}{ + (#1:#2) [##1:##2] + }\par +} +\stopbuffer + +\typebuffer[option=TEX] + +We get this: + +\startpacked \getbuffer \stoppacked + +We can also use two state macro but here we would have to store the outer ones: + +\startbuffer +\dorecurse {2} { + /\recursedepth:\recurselevel/ + \dostepwiserecurse {1} {10} {2} { + <\recursedepth:\recurselevel> + }\par +} +\stopbuffer + +\typebuffer[option=TEX] + +That gives us: + +\startpacked \getbuffer \stoppacked + +An endless loop works as follows: + +\startbuffer +\doloop { + ... + \ifsomeconditionismet + ... + \exitloop + \else + ... + \fi + % \exitloopnow + ... +} +\stopbuffer + +\typebuffer[option=TEX] + +Because of the way we quit there will not be a new implementation in terms of +the loop primitives. You need to make sure that you don't leave in the middle +of an ongoing condition. The second exit is immediate. + +We also have a (simple) expanded variant: + +\startbuffer +\edef\TestX{\doexpandedrecurse{10}{!}} \meaningasis\TestX +\stopbuffer + +\typebuffer[option=TEX] + +This helper can be implemented in terms of the loop primitives which makes them a +bit faster, but these are not critical: + +\startpacked \getbuffer \stoppacked + +A variant that supports \type {#1} is the following: + +\startbuffer +\edef\TestX{\doexpandedrecursed{10}{#1}} \meaningasis\TestX +\stopbuffer + +\typebuffer[option=TEX] + +So: + +\startpacked \getbuffer \stoppacked + +% private: \dofastloopcs{#1}\cs with % \fastloopindex and \fastloopfinal + +\stopsectionlevel + +\stopdocument diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel.tex index 14242e3a9..10057b999 100644 --- a/doc/context/sources/general/manuals/lowlevel/lowlevel.tex +++ b/doc/context/sources/general/manuals/lowlevel/lowlevel.tex @@ -34,6 +34,7 @@ \startsectionlevel[title=Marks] \component [lowlevel-marks] \stopsectionlevel \startsectionlevel[title=Inserts] \component [lowlevel-inserts] \stopsectionlevel \startsectionlevel[title=Localboxes] \component [lowlevel-localboxes] \stopsectionlevel + \startsectionlevel[title=Loops] \component [lowlevel-loops] \stopsectionlevel \stoptext diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex index 121ffe216..caf4dc55a 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex @@ -68,7 +68,7 @@ still going for this new engine are: \startitemize[packed] \startitem some new primitives make for less tracing and tracing has become rather - verbose over years (just try \prm {tracingall}); examples are the new macro + verbose over years (just try \type {tracingall}); examples are the new macro argument handling and some new hooks \stopitem \startitem @@ -318,16 +318,18 @@ marks is limited. The size of some tables can be limited by configuration settings, so they can start out small and grow till configured maximum which is smaller than the absolute maximum. -The following table shows all kind of defaults as reported by \typ -{status.getconstants()}. - -\startluacode - context.starttabulate { "|T|r|" } - for k, v in table.sortedhash(status.getconstants()) do - context.NC() context(k) context.NC() context(v) context.NC() context.NR() - end - context.stoptabulate() -\stopluacode +% % We show this later on so not here. +% +% The following table shows all kind of defaults as reported by \typ +% {status.getconstants()}. +% +% \startluacode +% context.starttabulate { "|T|r|" } +% for k, v in table.sortedhash(status.getconstants()) do +% context.NC() context(k) context.NC() context(v) context.NC() context.NR() +% end +% context.stoptabulate() +% \stopluacode Because we have additional ways to store integers, dimensions and glue, we might actually decide to decrease the maximum of the registers: if 64K is not enough, diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex b/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex index b12ebdcb3..62c9d211f 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex @@ -8,14 +8,15 @@ \startsection[title={Introduction}] -Only traditional font support is built in, anything more needs to be implemented -in \LUA. This conforms to the \LUATEX\ philosophy. When you pass a font to the -frontend only the dimensions matter, as these are used in typesetting, and -optionally ligatures and kerns when you rely on the built|-|in font handler. For -math some extra data is needed, like information about extensibles and next in -size glyphs. You can of course put more information in your \LUA\ tables because -when such a table is passed to \TEX\ only that what is needed is filtered from -it. +The traditional \TEX\ ligature and kerning routines are build in but anything +more (like \OPENTYPE\ rendering) has to be implemented in \LUA. In \CONTEXT\ we +call the former base mode and the later node mode (we have some more modes). This +conforms to the \LUATEX\ philosophy. When you pass a font to the frontend only +the dimensions matter, as these are used in typesetting, and optionally ligatures +and kerns when you rely on the built|-|in font handler. For math some extra data +is needed, like information about extensibles and next in size glyphs. You can of +course put more information in your \LUA\ tables because when such a table is +passed to \TEX\ only that what is needed is filtered from it. Because there is no built|-|in backend, virtual font information is not used. If you want to be compatible you'd better make sure that your tables are okay, and @@ -81,13 +82,13 @@ The names and their internal remapping are: \starttabulate[|l|c|] \DB name \BC remapping \NC \NR \TB -\NC \type {slant} \NC 1 \NC \NR -\NC \type {space} \NC 2 \NC \NR -\NC \type {space_stretch} \NC 3 \NC \NR -\NC \type {space_shrink} \NC 4 \NC \NR -\NC \type {x_height} \NC 5 \NC \NR -\NC \type {quad} \NC 6 \NC \NR -\NC \type {extra_space} \NC 7 \NC \NR +\NC \type {slant} \NC 1 \NC \NR +\NC \type {space} \NC 2 \NC \NR +\NC \type {spacestretch} \NC 3 \NC \NR +\NC \type {spaceshrink} \NC 4 \NC \NR +\NC \type {xheight} \NC 5 \NC \NR +\NC \type {quad} \NC 6 \NC \NR +\NC \type {extraspace} \NC 7 \NC \NR \LL \stoptabulate @@ -107,25 +108,25 @@ that uses the engine, and node mode that uses \LUA. A monospaced font normally has no ligatures and kerns and is normally not processed at all. \starttabulate[|l|l|pl|] -\DB key \BC type \BC description \NC\NR +\DB key \BC type \BC description \NC\NR \TB -\NC \type {width} \NC number \NC width in sp (default 0) \NC\NR -\NC \type {height} \NC number \NC height in sp (default 0) \NC\NR -\NC \type {depth} \NC number \NC depth in sp (default 0) \NC\NR -\NC \type {italic} \NC number \NC italic correction in sp (default 0) \NC\NR -\NC \type {top_accent} \NC number \NC top accent alignment place in sp (default zero) \NC\NR -\NC \type {bot_accent} \NC number \NC bottom accent alignment place, in sp (default zero) \NC\NR -\NC \type {left_protruding} \NC number \NC left protruding factor (\prm {lpcode}) \NC\NR -\NC \type {right_protruding} \NC number \NC right protruding factor (\prm {rpcode}) \NC\NR -\NC \type {expansion_factor} \NC number \NC expansion factor (\prm {efcode}) \NC\NR -\NC \type {next} \NC number \NC \quote {next larger} character index \NC\NR -\NC \type {extensible} \NC table \NC constituent parts of an extensible recipe \NC\NR -\NC \type {vert_variants} \NC table \NC constituent parts of a vertical variant set \NC \NR -\NC \type {horiz_variants} \NC table \NC constituent parts of a horizontal variant set \NC \NR -\NC \type {kerns} \NC table \NC kerning information \NC\NR -\NC \type {ligatures} \NC table \NC ligaturing information \NC\NR -\NC \type {mathkern} \NC table \NC math cut-in specifications \NC\NR -\NC \type {smaller} \NC number \NC the next smaller math size character \NC\NR +\NC \type {width} \NC number \NC width in sp (default 0) \NC\NR +\NC \type {height} \NC number \NC height in sp (default 0) \NC\NR +\NC \type {depth} \NC number \NC depth in sp (default 0) \NC\NR +\NC \type {italic} \NC number \NC italic correction in sp (default 0) \NC\NR +\NC \type {topaccent} \NC number \NC top accent alignment place in sp (default zero) \NC\NR +\NC \type {botaccent} \NC number \NC bottom accent alignment place, in sp (default zero) \NC\NR +\NC \type {leftprotruding} \NC number \NC left protruding factor (\prm {lpcode}) \NC\NR +\NC \type {rightprotruding} \NC number \NC right protruding factor (\prm {rpcode}) \NC\NR +\NC \type {expansion} \NC number \NC expansion factor (\prm {efcode}) \NC\NR +\NC \type {next} \NC number \NC \quote {next larger} character index \NC\NR +\NC \type {extensible} \NC table \NC constituent parts of an extensible recipe \NC\NR +\NC \type {vvariants} \NC table \NC constituent parts of a vertical variant set \NC \NR +\NC \type {hvariants} \NC table \NC constituent parts of a horizontal variant set \NC \NR +\NC \type {kerns} \NC table \NC kerning information \NC\NR +\NC \type {ligatures} \NC table \NC ligaturing information \NC\NR +\NC \type {mathkern} \NC table \NC math cut-in specifications \NC\NR +\NC \type {smaller} \NC number \NC the next smaller math size character \NC\NR \LL \stoptabulate @@ -153,23 +154,23 @@ For example, here is the character \quote {f} (decimal 102) in the font \type } \stoptyping -Two very special string indexes can be used also: \type {left_boundary} is a +Two very special string indexes can be used also: \type {leftboundary} is a virtual character whose ligatures and kerns are used to handle word boundary -processing. \type {right_boundary} is similar but not actually used for anything +processing. \type {rightboundary} is similar but not actually used for anything (yet). -The values of \type {top_accent}, \type {bot_accent} and \type {mathkern} are -used only for math accent and superscript placement, see \at {page} [math] in -this manual for details. The values of \type {left_protruding} and \type -{right_protruding} are used only when \prm {protrudechars} is non-zero. Whether -or not \type {expansion_factor} is used depends on the font's global expansion -settings, as well as on the value of \prm {adjustspacing}. +The values of \type {topaccent}, \type {botaccent} and \type {mathkern} are used +only for math accent and superscript placement, see \at {page} [math] in this +manual for details. The values of \type {leftprotrusion} and \type +{rightprotrusion} are used only when \prm {protrudechars} is non-zero. Whether or +not \type {expansion} is used depends on the font's global expansion settings, as +well as on the value of \prm {adjustspacing}. A math character can have a \type {next} field that points to a next larger shape. However, the presence of \type {extensible} will overrule \type {next}, if that is also present. The \type {extensible} field in turn can be overruled by -\type {vert_variants}, the \OPENTYPE\ version. The \type {extensible} table is -very simple: +\type {vvariants}, the \OPENTYPE\ version. The \type {extensible} table is very +simple: \starttabulate[|l|l|p|] \DB key \BC type \BC description \NC\NR @@ -181,8 +182,8 @@ very simple: \LL \stoptabulate -The \type {horiz_variants} and \type {vert_variants} are arrays of components. -Each of those components is itself a hash of up to five keys: +The \type {hvariants} and \type {vvariants} are arrays of components. Each of +those components is itself a hash of up to five keys: \starttabulate[|l|l|p|] \DB key \BC type \BC explanation \NC \NR @@ -199,12 +200,12 @@ Each of those components is itself a hash of up to five keys: The \type {kerns} table is a hash indexed by character index (and \quote {character index} is defined as either a non|-|negative integer or the string -value \type {right_boundary}), with the values of the kerning to be applied, in +value \type {rightboundary}), with the values of the kerning to be applied, in scaled points. The \type {ligatures} table is a hash indexed by character index (and \quote {character index} is defined as either a non|-|negative integer or the string -value \type {right_boundary}), with the values being yet another small hash, with +value \type {rightboundary}), with the values being yet another small hash, with two fields: \starttabulate[|l|l|p|] @@ -366,7 +367,7 @@ ever seen in the engine. \NC \type{lua} \NC 1 \NC string, function \NC execute a \LUA\ script when the glyph is embedded; in case of a function it gets the font id and character code passed \NC \NR -\NC \type{image} \NC 1 \NC image \NC output an image (the argument can be either an \type {<image>} variable or an \type {image_spec} table) \NC \NR +\NC \type{image} \NC 1 \NC image \NC depends on the backend \NC \NR \NC \type{comment} \NC any \NC any \NC the arguments of this command are ignored \NC \NR \LL \stoptabulate diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex b/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex index a063de703..e282649fb 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex @@ -86,22 +86,22 @@ horizontal lists while others are unique for vertical lists. The possible fields are \showfields {hlist}. \starttabulate[|l|l|p|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC \showsubtypes{list} \NC \NR -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{width} \NC number \NC the width of the box \NC \NR -\NC \type{height} \NC number \NC the height of the box \NC \NR -\NC \type{depth} \NC number \NC the depth of the box \NC \NR -\NC \type{direction} \NC number \NC the direction of this box, see~\in [dirnodes] \NC \NR -\NC \type{shift} \NC number \NC a displacement perpendicular to the character +\NC \type{subtype} \NC number \NC \showsubtypes{list} \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{width} \NC number \NC the width of the box \NC \NR +\NC \type{height} \NC number \NC the height of the box \NC \NR +\NC \type{depth} \NC number \NC the depth of the box \NC \NR +\NC \type{direction} \NC number \NC the direction of this box, see~\in [dirnodes] \NC \NR +\NC \type{shift} \NC number \NC a displacement perpendicular to the character (hlist) or line (vlist) progression direction \NC \NR -\NC \type{glue_order} \NC number \NC a number in the range $[0,4]$, indicating the +\NC \type{glueorder} \NC number \NC a number in the range $[0,4]$, indicating the glue order \NC \NR -\NC \type{glue_set} \NC number \NC the calculated glue ratio \NC \NR -\NC \type{glue_sign} \NC number \NC 0 = \type {normal}, 1 = \type {stretching}, 2 = - \type {shrinking} \NC \NR -\NC \type{list} \NC node \NC the first node of the body of this list \NC \NR +\NC \type{glueset} \NC number \NC the calculated glue ratio \NC \NR +\NC \type{gluesign} \NC number \NC 0 = \type {normal}, 1 = \type {stretching}, 2 = + \type {shrinking} \NC \NR +\NC \type{list} \NC node \NC the first node of the body of this list \NC \NR \LL \stoptabulate @@ -187,7 +187,7 @@ This node relates to the \prm {insert} primitive and support the fields: \showfi \stoptabulate There is a set of extra fields that concern the associated glue: \type {width}, -\type {stretch}, \type {stretch_order}, \type {shrink} and \type {shrink_order}. +\type {stretch}, \type {stretchorder}, \type {shrink} and \type {shrinkorder}. These are all numbers. A warning: never assign a node list to the \type {head} field unless you are sure @@ -296,14 +296,14 @@ Math nodes represent the boundaries of a math formula, normally wrapped into \starttabulate[|l|l|p|] \DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC \showsubtypes{math} \NC \NR -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{surround} \NC number \NC width of the \prm {mathsurround} kern \NC \NR -\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR -\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR -\NC \type{stretch_order} \NC number \NC factor applied to stretch amount \NC \NR -\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR -\NC \type{shrink_order} \NC number \NC factor applied to shrink amount \NC \NR +\NC \type{subtype} \NC number \NC \showsubtypes{math} \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{surround} \NC number \NC width of the \prm {mathsurround} kern \NC \NR +\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR +\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR +\NC \type{stretchorder} \NC number \NC factor applied to stretch amount \NC \NR +\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR +\NC \type{shrinkorder} \NC number \NC factor applied to shrink amount \NC \NR \LL \stoptabulate @@ -324,16 +324,16 @@ don't use the spec itself but just its values. A glue node has the fields: \showfields {glue}. \starttabulate[|l|l|pA{flushleft,tolerant}|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC \showsubtypes{glue} \NC \NR -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{leader} \NC node \NC pointer to a box or rule for leaders \NC \NR -\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR -\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR -\NC \type{stretch_order} \NC number \NC factor applied to stretch amount \NC \NR -\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR -\NC \type{shrink_order} \NC number \NC factor applied to shrink amount \NC \NR +\NC \type{subtype} \NC number \NC \showsubtypes{glue} \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{leader} \NC node \NC pointer to a box or rule for leaders \NC \NR +\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR +\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR +\NC \type{stretchorder} \NC number \NC factor applied to stretch amount \NC \NR +\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR +\NC \type{shrinkorder} \NC number \NC factor applied to shrink amount \NC \NR \LL \stoptabulate @@ -370,13 +370,13 @@ resolve these quantities immediately and we put the current values in the glue nodes. \starttabulate[|l|l|pA{flushleft,tolerant}|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR -\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR -\NC \type{stretch_order} \NC number \NC factor applied to stretch amount \NC \NR -\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR -\NC \type{shrink_order} \NC number \NC factor applied to shrink amount \NC \NR +\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR +\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR +\NC \type{stretchorder} \NC number \NC factor applied to stretch amount \NC \NR +\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR +\NC \type{shrinkorder} \NC number \NC factor applied to shrink amount \NC \NR \LL \stoptabulate @@ -396,12 +396,12 @@ The \prm {kern} command creates such nodes but for instance the font and math machinery can also add them. There are not that many fields: \showfields {kern}. \starttabulate[|l|l|p|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC \showsubtypes{kern} \NC \NR -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{kern} \NC number \NC fixed horizontal or vertical advance \NC \NR -\NC \type{expansion_factor} \NC number \NC multiplier related to hz for font kerns \NC \NR +\NC \type{subtype} \NC number \NC \showsubtypes{kern} \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{kern} \NC number \NC fixed horizontal or vertical advance \NC \NR +\NC \type{expansion} \NC number \NC multiplier related to hz for font kerns \NC \NR \LL \stoptabulate @@ -442,30 +442,30 @@ it considers some input to be text. Glyph nodes are relatively large and have ma fields: \showfields {glyph}. \starttabulate[|l|l|p|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC bit field \NC \NR -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{char} \NC number \NC the character index in the font \NC \NR -\NC \type{font} \NC number \NC the font identifier \NC \NR -\NC \type{language} \NC number \NC the language identifier \NC \NR -\NC \type{left} \NC number \NC the frozen \type {\lefthyphenmnin} value \NC \NR -\NC \type{right} \NC number \NC the frozen \type {\righthyphenmnin} value \NC \NR -\NC \type{uchyph} \NC boolean \NC the frozen \prm {uchyph} value \NC \NR -\NC \type{state} \NC number \NC a user field (replaces the component list) \NC \NR -\NC \type{xoffset} \NC number \NC a virtual displacement in horizontal direction \NC \NR -\NC \type{yoffset} \NC number \NC a virtual displacement in vertical direction \NC \NR -\NC \type{width} \NC number \NC the (original) width of the character \NC \NR -\NC \type{height} \NC number \NC the (original) height of the character\NC \NR -\NC \type{depth} \NC number \NC the (original) depth of the character\NC \NR -\NC \type{expansion_factor} \NC number \NC the to be applied expansion_factor \NC \NR -\NC \type{data} \NC number \NC a general purpose field for users (we had room for it) \NC \NR +\NC \type{subtype} \NC number \NC bit field \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{char} \NC number \NC the character index in the font \NC \NR +\NC \type{font} \NC number \NC the font identifier \NC \NR +\NC \type{language} \NC number \NC the language identifier \NC \NR +\NC \type{left} \NC number \NC the frozen \type {\lefthyphenmnin} value \NC \NR +\NC \type{right} \NC number \NC the frozen \type {\righthyphenmnin} value \NC \NR +\NC \type{uchyph} \NC boolean \NC the frozen \prm {uchyph} value \NC \NR +\NC \type{state} \NC number \NC a user field (replaces the component list) \NC \NR +\NC \type{xoffset} \NC number \NC a virtual displacement in horizontal direction \NC \NR +\NC \type{yoffset} \NC number \NC a virtual displacement in vertical direction \NC \NR +\NC \type{width} \NC number \NC the (original) width of the character \NC \NR +\NC \type{height} \NC number \NC the (original) height of the character\NC \NR +\NC \type{depth} \NC number \NC the (original) depth of the character\NC \NR +\NC \type{expansion} \NC number \NC the to be applied expansion factor \NC \NR +\NC \type{data} \NC number \NC a general purpose field for users (we had room for it) \NC \NR \LL \stoptabulate The \type {width}, \type {height} and \type {depth} values are read|-|only. The -\type {expansion_factor} is assigned in the par builder and used in the backend. -Valid bits for the \type {subtype} field are: +\type {expansion} is assigned in the par builder and used in the backend. Valid +bits for the \type {subtype} field are: \starttabulate[|c|l|] \DB bit \BC meaning \NC \NR @@ -478,8 +478,8 @@ Valid bits for the \type {subtype} field are: \LL \stoptabulate -The \type {expansion_factor} has been introduced as part of the separation -between front- and backend. It is the result of extensive experiments with a more +The \type {expansion} has been introduced as part of the separation between +front- and backend. It is the result of extensive experiments with a more efficient implementation of expansion. Early versions of \LUATEX\ already replaced multiple instances of fonts in the backend by scaling but contrary to \PDFTEX\ in \LUATEX\ we now also got rid of font copies in the frontend and @@ -487,15 +487,15 @@ replaced them by expansion factors that travel with glyph nodes. Apart from a cleaner approach this is also a step towards a better separation between front- and backend. -The \type {is_char} function checks if a node is a glyph node with a subtype still +The \type {ischar} function checks if a node is a glyph node with a subtype still less than 256. This function can be used to determine if applying font logic to a glyph node makes sense. The value \type {nil} gets returned when the node is not a glyph, a character number is returned if the node is still tagged as character and \type {false} gets returned otherwise. When nil is returned, the id is also -returned. The \type {is_glyph} variant doesn't check for a subtype being less +returned. The \type {isglyph} variant doesn't check for a subtype being less than 256, so it returns either the character value or nil plus the id. These helpers are not always faster than separate calls but they sometimes permit -making more readable tests. The \type {uses_font} helpers takes a node +making more readable tests. The \type {usesfont} helpers takes a node and font id and returns true when a glyph or disc node references that font. \stopsubsection @@ -529,22 +529,22 @@ This node is inserted at the start of a paragraph. You should not mess too much with this one. Valid fields are: \showfields {par}. \starttabulate[|l|l|p|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{pen_inter} \NC number \NC local interline penalty (from \prm {localinterlinepenalty}) \NC \NR -\NC \type{pen_broken} \NC number \NC local broken penalty (from \prm {localbrokenpenalty}) \NC \NR -\NC \type{dir} \NC string \NC the direction of this par. see~\in [dirnodes] \NC \NR -\NC \type{box_left} \NC node \NC the \prm {localleftbox} \NC \NR -\NC \type{box_left_width} \NC number \NC width of the \prm {localleftbox} \NC \NR -\NC \type{box_right} \NC node \NC the \prm {localrightbox} \NC \NR -\NC \type{box_right_width} \NC number \NC width of the \prm {localrightbox} \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{interlinepenalty} \NC number \NC local interline penalty (from \prm {localinterlinepenalty}) \NC \NR +\NC \type{brokenpenalty} \NC number \NC local broken penalty (from \prm {localbrokenpenalty}) \NC \NR +\NC \type{dir} \NC string \NC the direction of this par. see~\in [dirnodes] \NC \NR +\NC \type{leftbox} \NC node \NC the \prm {localleftbox} \NC \NR +\NC \type{leftboxwidth} \NC number \NC width of the \prm {localleftbox} \NC \NR +\NC \type{rightbox} \NC node \NC the \prm {localrightbox} \NC \NR +\NC \type{rightboxwidth} \NC number \NC width of the \prm {localrightbox} \NC \NR +\NC \type{middlebox} \NC node \NC the \prm {localmiddlebox} (zero width) \NC \NR \LL \stoptabulate -A warning: never assign a node list to the \type {box_left} or \type {box_right} -field unless you are sure its internal link structure is correct, otherwise an -error may result. +A warning: never assign a node list to one of the box fields unless you are sure +its internal link structure is correct, otherwise an error may result. \stopsubsection @@ -681,19 +681,19 @@ before, the \type {next} and \type {prev} fields are unused, but we do have: \showfields {delimiter}. \starttabulate[|l|l|p|] -\DB field \BC type \BC explanation \NC \NR +\DB field \BC type \BC explanation \NC \NR \TB -\NC \type{attr} \NC node \NC list of attributes \NC \NR -\NC \type{small_char} \NC number \NC character index of base character \NC \NR -\NC \type{small_fam} \NC number \NC family number of base character \NC \NR -\NC \type{large_char} \NC number \NC character index of next larger character \NC \NR -\NC \type{large_fam} \NC number \NC family number of next larger character \NC \NR +\NC \type{attr} \NC node \NC list of attributes \NC \NR +\NC \type{smallchar} \NC number \NC character index of base character \NC \NR +\NC \type{smallfamily} \NC number \NC family number of base character \NC \NR +\NC \type{largechar} \NC number \NC character index of next larger character \NC \NR +\NC \type{largefamily} \NC number \NC family number of next larger character \NC \NR \LL \stoptabulate -The fields \type {large_char} and \type {large_fam} can be zero, in that case the -font that is set for the \type {small_fam} is expected to provide the large -version as an extension to the \type {small_char}. +The fields \type {largechar} and \type {largefamily} can be zero, in that case +the font that is set for the \type {smallfamily} is expected to provide the large +version as an extension to the \type {smallchar}. \stopsubsubsection @@ -724,13 +724,13 @@ Accent nodes deal with stuff on top or below a math constructs. They support: \starttabulate[|l|l|p|] \DB field \BC type \BC explanation \NC \NR \TB -\NC \type{subtype} \NC number \NC \showsubtypes{accent} \NC \NR -\NC \type{nucleus} \NC kernel node \NC base \NC \NR -\NC \type{sub} \NC kernel node \NC subscript \NC \NR -\NC \type{sup} \NC kernel node \NC superscript \NC \NR -\NC \type{accent} \NC kernel node \NC top accent \NC \NR -\NC \type{bot_accent} \NC kernel node \NC bottom accent \NC \NR -\NC \type{fraction} \NC number \NC larger step criterium (divided by 1000) \NC \NR +\NC \type{subtype} \NC number \NC \showsubtypes{accent} \NC \NR +\NC \type{nucleus} \NC kernel node \NC base \NC \NR +\NC \type{sub} \NC kernel node \NC subscript \NC \NR +\NC \type{sup} \NC kernel node \NC superscript \NC \NR +\NC \type{topaccent} \NC kernel node \NC top accent \NC \NR +\NC \type{botaccent} \NC kernel node \NC bottom accent \NC \NR +\NC \type{fraction} \NC number \NC larger step criterium (divided by 1000) \NC \NR \LL \stoptabulate @@ -1048,14 +1048,14 @@ This function probably is not that useful but some nodes don't have a \type \stopsubsubsection -\startsubsubsection[title={\type {is_node}}] +\startsubsubsection[title={\type {isnode}}] \topicindex {nodes+functions} -\libindex {is_node} +\libindex {isnode} \startfunctioncall -<boolean|integer> t = node.is_node(<any> item) +<boolean|integer> t = node.isnode(<any> item) \stopfunctioncall This function returns a number (the internal index of the node) if the argument @@ -1336,12 +1336,12 @@ If the above is unclear to you, see the section \quote {For Statement} in the \stopsubsubsection -\startsubsubsection[title={\type {traverse_id}}] +\startsubsubsection[title={\type {traverseid}}] -\libindex {traverse_id} +\libindex {traverseid} \startfunctioncall -<node> t, subtype = node.traverse_id(<number> id, <node> n) +<node> t, subtype = node.traverseid(<number> id, <node> n) \stopfunctioncall This is an iterator that loops over all the nodes in the list that starts at @@ -1367,37 +1367,37 @@ See the previous section for details. The change is in the local function \type \stopsubsubsection -\startsubsubsection[title={\type {traverse_char} and \type {traverse_glyph}}] +\startsubsubsection[title={\type {traversechar} and \type {traverseglyph}}] -\libindex {traverse_char} -\libindex {traverse_glyph} +\libindex {traversechar} +\libindex {traverseglyph} -The \type{traverse_char} iterator loops over the \nod {glyph} nodes in a list. +The \type {traversechar} iterator loops over the \nod {glyph} nodes in a list. Only nodes with a subtype less than 256 are seen. \startfunctioncall -<direct> n, font, char = node.direct.traverse_char(<direct> n) +<direct> n, font, char = node.direct.traversechar(<direct> n) \stopfunctioncall -The \type{traverse_glyph} iterator loops over a list and returns the list and +The \type{traverseglyph} iterator loops over a list and returns the list and filters all glyphs: \startfunctioncall -<direct> n, font, char = node.traverse_glyph(<direct> n) +<direct> n, font, char = node.traverseglyph(<direct> n) \stopfunctioncall These functions are only available for direct nodes. \stopsubsubsection -\startsubsubsection[title={\type {traverse_list}}] +\startsubsubsection[title={\type {traverselist}}] -\libindex {traverse_list} +\libindex {traverselist} This iterator loops over the \nod {hlist} and \nod {vlist} nodes in a list. \startfunctioncall -<direct> n, id, subtype, list = node.traverse_list(<direct> n) +<direct> n, id, subtype, list = node.traverselist(<direct> n) \stopfunctioncall The four return values can save some time compared to fetching these fields but @@ -1406,15 +1406,15 @@ nodes. \stopsubsubsection -\startsubsubsection[title={\type {traverse_content}}] +\startsubsubsection[title={\type {traversecontent}}] -\libindex {traverse_content} +\libindex {traversecontent} This iterator loops over nodes that have content: \nod {hlist}, \nod {vlist}, \nod {glue} with leaders, \nod {glyphs}, \nod {disc} and \nod {rules} nodes. \startfunctioncall -<direct> n, id, subtype[, list|leader] = node.traverse_list(<direct> n) +<direct> n, id, subtype[, list|leader] = node.traverselist(<direct> n) \stopfunctioncall The four return values can save some time compared to fetching these fields but @@ -1442,13 +1442,13 @@ end for n in node.traverse(l,true,true) do print("3>",n) end -for n in node.traverse_id(nodes.nodecodes.glyph,l) do +for n in node.traverseid(nodes.nodecodes.glyph,l) do print("4>",n) end -for n in node.traverse_id(nodes.nodecodes.glyph,l,true) do +for n in node.traverseid(nodes.nodecodes.glyph,l,true) do print("5>",n) end -for n in node.traverse_id(nodes.nodecodes.glyph,l,true,true) do +for n in node.traverseid(nodes.nodecodes.glyph,l,true,true) do print("6>",n) end \stoptyping @@ -1491,15 +1491,15 @@ been processed by the font handlers): \stopsubsection -\startsubsubsection[title={\type {find_node}}] +\startsubsubsection[title={\type {findnode}}] -\libindex {find_node} +\libindex {findnode} This helper returns the location of the first match at or after node \type {n}: \startfunctioncall -<node> n = node.find_node(<node> n, <integer> subtype) -<node> n, subtype = node.find_node(<node> n) +<node> n = node.findnode(<node> n, <integer> subtype) +<node> n, subtype = node.findnode(<node> n) \stopfunctioncall \stopsubsubsection @@ -1518,7 +1518,7 @@ passed the property becomes zero. \startfunctioncall node.setglue(<node> n) -node.setglue(<node> n,width,stretch,shrink,stretch_order,shrink_order) +node.setglue(<node> n,width,stretch,shrink,stretchorder,shrinkorder) \stopfunctioncall When you pass values, only arguments that are numbers are assigned so @@ -1540,8 +1540,8 @@ When a list node is passed, you set the glue, order and sign instead. The next call will return 5 values or nothing when no glue is passed. \startfunctioncall -<integer> width, <integer> stretch, <integer> shrink, <integer> stretch_order, - <integer> shrink_order = node.getglue(<node> n) +<integer> width, <integer> stretch, <integer> shrink, <integer> stretchorder, + <integer> shrinkorder = node.getglue(<node> n) \stopfunctioncall When the second argument is false, only the width is returned (this is consistent @@ -1750,17 +1750,17 @@ end of the list. \stopsubsubsection -\startsubsubsection[title={\type {is_char} and \type {is_glyph}}] +\startsubsubsection[title={\type {ischar} and \type {isglyph}}] -\libindex {is_char} -\libindex {is_glyph} +\libindex {ischar} +\libindex {isglyph} The subtype of a glyph node signals if the glyph is already turned into a character reference or not. \startfunctioncall -<boolean> b = node.is_char(<node> n) -<boolean> b = node.is_glyph(<node> n) +<boolean> b = node.ischar(<node> n) +<boolean> b = node.isglyph(<node> n) \stopfunctioncall \stopsubsubsection @@ -1947,21 +1947,6 @@ of \type {hpack} for a few memory allocation caveats. \stopsubsubsection -\startsubsubsection[title={\type {prepend_prevdepth}}] - -\libindex {prepend_prevdepth} - -This function is somewhat special in the sense that it is an experimental helper -that adds the interlinespace to a line keeping the baselineskip and lineskip into -account. - -\startfunctioncall -<node> n, <number> delta = - node.prepend_prevdepth(<node> n,<number> prevdepth) -\stopfunctioncall - -\stopsubsubsection - \startsubsubsection[title={\type {dimensions}, \type {rangedimensions}, \type {naturalwidth}}] \libindex{dimensions} @@ -1982,10 +1967,10 @@ is also possible: \startfunctioncall <number> w, <number> h, <number> d = - node.dimensions(<number> glue_set, <number> glue_sign, <number> glue_order, + node.dimensions(<number> glueset, <number> gluesign, <number> glueorder, <node> n) <number> w, <number> h, <number> d = - node.dimensions(<number> glue_set, <number> glue_sign, <number> glue_order, + node.dimensions(<number> glueset, <number> gluesign, <number> glueorder, <node> n, <node> t) \stopfunctioncall @@ -1998,9 +1983,9 @@ example in code like this, which prints the width of the space in between the \setbox0 = \hbox to 20pt {a b} \directlua{print (node.dimensions( - tex.box[0].glue_set, - tex.box[0].glue_sign, - tex.box[0].glue_order, + tex.box[0].glueset, + tex.box[0].gluesign, + tex.box[0].glueorder, tex.box[0].head.next, node.tail(tex.box[0].head) )) } @@ -2048,12 +2033,12 @@ as for the callback \cbk {mlisttohlist}. \stopsubsubsection -\startsubsubsection[title={\type {end_of_math}}] +\startsubsubsection[title={\type {endofmath}}] -\libindex {end_of_math} +\libindex {endofmath} \startfunctioncall -<node> t = node.end_of_math(<node> start) +<node> t = node.endofmath(<node> start) \stopfunctioncall Looks for and returns the next \type {math_node} following the \type {start}. If @@ -2302,7 +2287,6 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility. \supported {mlisttohlist} \nop \yes \yes \supported {naturalwidth} \nop \yes \yes \supported {new} \yes \yes \relax -%supported {prepend_prevdepth} \nop \yes \yes \supported {protectglyphs} \nop \yes \yes \supported {protectglyph} \nop \yes \yes \supported {protrusionskippable} \nop \yes \yes @@ -2366,11 +2350,11 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility. \supported {tostring} \yes \nop \relax \supported {total} \nop \yes \relax \supported {tovaliddirect} \nop \yes \relax -\supported {traverse_char} \yes \yes \relax -\supported {traverse_content} \yes \yes \relax -\supported {traverse_glyph} \yes \yes \relax -\supported {traverse_id} \yes \yes \relax -\supported {traverse_list} \yes \yes \relax +\supported {traversechar} \yes \yes \relax +\supported {traversecontent} \yes \yes \relax +\supported {traverseglyph} \yes \yes \relax +\supported {traverseid} \yes \yes \relax +\supported {traverselist} \yes \yes \relax \supported {traverse} \yes \yes \relax \supported {type} \yes \nop \relax \supported {unprotectglyphs} \nop \yes \yes @@ -2406,13 +2390,6 @@ true for the \type {width}, \type {height} and \type {depth} of glue nodes. Thes actually access the spec node properties, and here we can set as well as get the values. -In some places \LUATEX\ can do a bit of extra checking for valid node lists and -you can enable that with: - -\startfunctioncall -node.fix_node_lists(<boolean> b) -\stopfunctioncall - You can set and query the \SYNCTEX\ fields, a file number aka tag and a line number, for a glue, kern, hlist, vlist, rule and math nodes as well as glyph nodes (although this last one is not used in native \SYNCTEX). @@ -2595,13 +2572,9 @@ to do that at the lua end e.g.\ using a metatable \type {__index} method. That way it is under macro package control. When deleting a node, we could keep the slot (e.g. setting it to false) but it could make memory consumption raise unneeded when we have temporary large node lists and after that only small lists. -Both are not done. - -So in the end this is what happens now: when a node is copied, and it has a table -as property, the new node will share that table. If the second argument of \typ -{set_properties_mode} is \type {true} then a metatable approach is chosen: the -copy gets its own table with the original table as metatable. If you use the -generic font loader the mode is enabled that way. +Both are not done because in the end this is what happens now: when a node is +copied, and it has a table as property, the new node will share that table. The +copy gets its own table with the original table as metatable. A few more experiments were done. For instance: copy attributes to the properties so that we have fast access at the \LUA\ end. In the end the overhead is not diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex index b7b150560..089a8202d 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex @@ -860,18 +860,20 @@ The virtual table \type {tex.lists} contains the set of internal registers that keep track of building page lists. \starttabulate[|l|p|] -\DB field \BC explanation \NC \NR +\DB field \BC explanation \NC \NR \TB -\NC \type{page_ins_head} \NC circular list of pending insertions \NC \NR -\NC \type{contribute_head} \NC the recent contributions \NC \NR -\NC \type{page_head} \NC the current page content \NC \NR -%NC \type{temp_head} \NC \NC \NR -\NC \type{hold_head} \NC used for held-over items for next page \NC \NR -\NC \type{adjust_head} \NC head of the current \prm {vadjust} list \NC \NR -\NC \type{pre_adjust_head} \NC head of the current \type {\vadjust pre} list \NC \NR -%NC \type{align_head} \NC \NC \NR -\NC \type{page_discards_head} \NC head of the discarded items of a page break \NC \NR -\NC \type{split_discards_head} \NC head of the discarded items in a vsplit \NC \NR +\NC \type{pageinserthead} \NC circular list of pending insertions \NC \NR +\NC \type{contributehead} \NC the recent contributions \NC \NR +\NC \type{pagehead} \NC the current page content \NC \NR +%NC \type{temphead} \NC \NC \NR +\NC \type{holdhead} \NC used for held-over items for next page \NC \NR +\NC \type{postadjusthead} \NC head of the (pending) post adjustments \NC \NR +\NC \type{preadjusthead} \NC head of the (pending) pre adjustments \NC \NR +\NC \type{postmigratehead} \NC head of the (pending) post migrations \NC \NR +\NC \type{premigratehead} \NC head of the (pending) pre migrations \NC \NR +%NC \type{alignhead} \NC \NC \NR +\NC \type{pagediscardshead} \NC head of the discarded items of a page break \NC \NR +\NC \type{splitdiscardshead} \NC head of the discarded items in a vsplit \NC \NR \LL \stoptabulate @@ -925,7 +927,7 @@ The known fields are: \NC \type{direction} \NC node \NC hmode \NC stack used for temporary storage by the line break algorithm \NC \NR \NC \type{noad} \NC node \NC mmode \NC used for temporary storage of a pending fraction numerator, for \prm {over} etc. \NC \NR -\NC \type{delimptr} \NC node \NC mmode \NC used for temporary storage of the previous math delimiter, +\NC \type{delimiter} \NC node \NC mmode \NC used for temporary storage of the previous math delimiter, for \prm {middle} \NC \NR \NC \type{mathdir} \NC boolean \NC mmode \NC true when during math processing the \prm {mathdirection} is not the same as the surrounding \prm {textdirection} \NC \NR @@ -1714,6 +1716,10 @@ which is a side effect of a more granular and dynamic memory management. \ML \NC \type{formatname} \NC string \NC \NC \NC \NR \NC \type{jobname} \NC string \NC \NC \NC \NR +\ML +\NC \type{starttime} \NC number \NC \NC for testing only \NC \NR +\NC \type{useutctime} \NC number \NC \NC for testing only \NC \NR +\NC \type{permitloadlib} \NC number \NC \NC for testing only \NC \NR \LL \stoptabulate diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 5536dd894..876eacdfc 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.11.30 19:43} +\newcontextversion{2021.12.03 15:17} %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 9f51621bf..48af7f8e3 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.11.30 19:43} +\edef\contextversion{2021.12.03 15:17} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 410fa7590..290da95f2 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -1282,6 +1282,7 @@ \setinterfaceconstant{tab}{تب} \setinterfaceconstant{text}{متن} \setinterfaceconstant{textalign}{textalign} +\setinterfaceconstant{textalternative}{textalternative} \setinterfaceconstant{textcolor}{رنگمتن} \setinterfaceconstant{textcommand}{فرمانمتن} \setinterfaceconstant{textdistance}{فاصلهمتن} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 529d7448d..92172d354 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.11.30 19:43} +\newcontextversion{2021.12.03 15:17} %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 956425aa6..fa300cafd 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -49,7 +49,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2021.11.30 19:43} +\edef\contextversion{2021.12.03 15:17} %D Kind of special: diff --git a/tex/context/base/mkiv/font-imp-properties.lua b/tex/context/base/mkiv/font-imp-properties.lua index 21b55aeb2..5405737a5 100644 --- a/tex/context/base/mkiv/font-imp-properties.lua +++ b/tex/context/base/mkiv/font-imp-properties.lua @@ -72,10 +72,10 @@ do extra = amount end end - parameters.space = amount * emwidth - parameters.space_stretch = stretch * emwidth - parameters.space_shrink = shrink * emwidth - parameters.extra_space = extra * emwidth + parameters.space = amount * emwidth + parameters.spacestretch = stretch * emwidth + parameters.spaceshrink = shrink * emwidth + parameters.extraspace = extra * emwidth end end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index 1098ef8fa..07e9c8df8 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -1410,7 +1410,8 @@ do return timestamp end - lpdf.settime(tonumber(resolvers.variable("start_time")) or tonumber(resolvers.variable("SOURCE_DATE_EPOCH"))) -- bah + -- lpdf.settime(tonumber(resolvers.variable("starttime")) or tonumber(resolvers.variable("SOURCE_DATE_EPOCH"))) -- bah + lpdf.settime(tonumber(resolvers.variable("starttime"))) function lpdf.pdftimestamp(str) local t = type(str) diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 2c0d9d41b..87c52de04 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -301,6 +301,8 @@ return { "crampedscriptstyle", "crampedtextstyle", "csstring", + "currentloopiterator", + "currentloopnesting", "currentmarks", "defcsname", "dimensiondef", @@ -320,6 +322,7 @@ return { "expandafterspaces", "expandcstoken", "expanded", + "expandedloop", "expandtoken", "explicitdiscretionary", "explicithyphenpenalty", @@ -434,6 +437,7 @@ return { "localbrokenpenalty", "localcontrol", "localcontrolled", + "localcontrolledloop", "localinterlinepenalty", "localleftbox", "localleftboxbox", @@ -507,6 +511,7 @@ return { "protrudechars", "protrusionboundary", "pxdimen", + "quitloop", "quitvmode", "retokenized", "rightmarginkern", @@ -539,6 +544,7 @@ return { "tracingmarks", "tracingmath", "undent", + "unexpandedloop", "unletfrozen", "unletprotected", "untraced", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 2cd4adcf2..41707d50a 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 9c5a72289..40471b66f 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkxl/blob-ini.mkxl b/tex/context/base/mkxl/blob-ini.mkxl index 1dcd55972..2e27ab20e 100644 --- a/tex/context/base/mkxl/blob-ini.mkxl +++ b/tex/context/base/mkxl/blob-ini.mkxl @@ -18,7 +18,7 @@ %D down the road (close to version 1.00 of \LUATEX). Typesetting in %D pure \LUA\ sometimes makes sense. -\registerctxluafile{node-typ}{} % experimental +\registerctxluafile{node-typ}{autosuffix} % experimental \registerctxluafile{blob-ini}{autosuffix} \unprotect diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 3bfffe608..95430abf6 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.11.30 19:43} +\newcontextversion{2021.12.03 15:17} %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 854c65e98..914f4bfd9 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.11.30 19:43} +\immutable\edef\contextversion{2021.12.03 15:17} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/font-chk.lmt b/tex/context/base/mkxl/font-chk.lmt index 967431423..008b9bb41 100644 --- a/tex/context/base/mkxl/font-chk.lmt +++ b/tex/context/base/mkxl/font-chk.lmt @@ -379,13 +379,13 @@ local function expandglyph(characters,index,done) if n then d.next = expandglyph(characters,n,done) end - local h = d.horiz_variants + local h = d.hvariants if h then for i=1,#h do h[i].glyph = expandglyph(characters,h[i].glyph,done) end end - local v = d.vert_variants + local v = d.vvariants if v then for i=1,#v do v[i].glyph = expandglyph(characters,v[i].glyph,done) diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt index b452f5a12..3310242a8 100644 --- a/tex/context/base/mkxl/font-con.lmt +++ b/tex/context/base/mkxl/font-con.lmt @@ -161,17 +161,17 @@ function constructors.trytosharefont(target,tfmdata) end local synonyms = { - exheight = "x_height", - xheight = "x_height", - ex = "x_height", + exheight = "xheight", + xheight = "xheight", + ex = "xheight", emwidth = "quad", em = "quad", - spacestretch = "space_stretch", - stretch = "space_stretch", - spaceshrink = "space_shrink", - shrink = "space_shrink", - extraspace = "extra_space", - xspace = "extra_space", + spacestretch = "spacestretch", + stretch = "spacestretch", + spaceshrink = "spaceshrink", + shrink = "spaceshrink", + extraspace = "extraspace", + xspace = "extraspace", slantperpoint = "slant", } @@ -188,9 +188,9 @@ function constructors.enhanceparameters(parameters) if k == "spacing" then return { width = t.space, - stretch = t.space_stretch, - shrink = t.space_shrink, - extra = t.extra_space, + stretch = t.spacestretch, + shrink = t.spaceshrink, + extra = t.extraspace, } end return mt and mt[k] or nil @@ -205,9 +205,9 @@ function constructors.enhanceparameters(parameters) elseif k == "spacing" then if type(v) == "table" then rawset(t,"space",v.width or 0) - rawset(t,"space_stretch",v.stretch or 0) - rawset(t,"space_shrink",v.shrink or 0) - rawset(t,"extra_space",v.extra or 0) + rawset(t,"spacestretch",v.stretch or 0) + rawset(t,"spaceshrink",v.shrink or 0) + rawset(t,"extraspace",v.extra or 0) end else rawset(t,k,v) @@ -437,21 +437,21 @@ function constructors.scale(tfmdata,specification) -- target.postprocessors = tfmdata.postprocessors -- - local targetslant = (parameters.slant or parameters[1] or 0) * factors.pt -- per point - local targetspace = (parameters.space or parameters[2] or 0) * hdelta - local targetspace_stretch = (parameters.space_stretch or parameters[3] or 0) * hdelta - local targetspace_shrink = (parameters.space_shrink or parameters[4] or 0) * hdelta - local targetx_height = (parameters.x_height or parameters[5] or 0) * vdelta - local targetquad = (parameters.quad or parameters[6] or 0) * hdelta - local targetextra_space = (parameters.extra_space or parameters[7] or 0) * hdelta - -- - targetparameters.slant = targetslant -- slantperpoint - targetparameters.space = targetspace - targetparameters.space_stretch = targetspace_stretch - targetparameters.space_shrink = targetspace_shrink - targetparameters.x_height = targetx_height - targetparameters.quad = targetquad - targetparameters.extra_space = targetextra_space + local targetslant = (parameters.slant or parameters[1] or 0) * factors.pt -- per point + local targetspace = (parameters.space or parameters[2] or 0) * hdelta + local targetspacestretch = (parameters.spacestretch or parameters[3] or 0) * hdelta + local targetspaceshrink = (parameters.spaceshrink or parameters[4] or 0) * hdelta + local targetxheight = (parameters.xheight or parameters[5] or 0) * vdelta + local targetquad = (parameters.quad or parameters[6] or 0) * hdelta + local targetextraspace = (parameters.extraspace or parameters[7] or 0) * hdelta + -- + targetparameters.slant = targetslant -- slantperpoint + targetparameters.space = targetspace + targetparameters.spacestretch = targetspacestretch + targetparameters.spaceshrink = targetspaceshrink + targetparameters.xheight = targetxheight + targetparameters.quad = targetquad + targetparameters.extraspace = targetextraspace -- local hshift = parameters.hshift if hshift then @@ -653,17 +653,17 @@ function constructors.scale(tfmdata,specification) end if hasquality then -- we could move these calculations elsewhere (saves calculations) - local ve = character.expansion_factor + local ve = character.expansion if ve then - chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere + chr.expansion = ve*1000 -- expansionfactor, hm, can happen elsewhere end - local vl = character.left_protruding + local vl = character.leftprotrusion if vl then - chr.left_protruding = width*vl + chr.leftprotrusion = width*vl end - local vr = character.right_protruding + local vr = character.rightprotrusion if vr then - chr.right_protruding = width*vr + chr.rightprotrusion = width*vr end end -- @@ -674,7 +674,7 @@ function constructors.scale(tfmdata,specification) if vn then chr.next = vn else - local vv = character.vert_variants + local vv = character.vvariants if vv then local t = { } for i=1,#vv do @@ -690,9 +690,9 @@ function constructors.scale(tfmdata,specification) ["glyph"] = vvi["glyph"], } end - chr.vert_variants = t + chr.vvariants = t else - local hv = character.horiz_variants + local hv = character.hvariants if hv then local t = { } for i=1,#hv do @@ -708,18 +708,18 @@ function constructors.scale(tfmdata,specification) ["glyph"] = hvi["glyph"], } end - chr.horiz_variants = t + chr.hvariants = t end end -- todo also check mathitalics (or that one can go away) end - local vi = character.vert_italic + local vi = character.vitalic if vi and vi ~= 0 then - chr.vert_italic = vi*hdelta + chr.vitalic = vi*hdelta end local va = character.accent if va then - chr.top_accent = vdelta*va + chr.topaccent = vdelta*va end if stackmath then local mk = character.mathkerns @@ -729,10 +729,10 @@ function constructors.scale(tfmdata,specification) local br = mk.bottomright local bl = mk.bottomleft chr.mathkern = { -- singular -> should be patched in luatex ! - top_right = tr and mathkerns(tr,vdelta) or nil, - top_left = tl and mathkerns(tl,vdelta) or nil, - bottom_right = br and mathkerns(br,vdelta) or nil, - bottom_left = bl and mathkerns(bl,vdelta) or nil, + topright = tr and mathkerns(tr,vdelta) or nil, + topleft = tl and mathkerns(tl,vdelta) or nil, + bottomright = br and mathkerns(br,vdelta) or nil, + bottomleft = bl and mathkerns(bl,vdelta) or nil, } end end diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt index ed8c22f58..05cad84f0 100644 --- a/tex/context/base/mkxl/font-ctx.lmt +++ b/tex/context/base/mkxl/font-ctx.lmt @@ -303,14 +303,14 @@ function definers.resetnullfont() -- resetting is needed because tikz misuses nullfont local parameters = fonts.nulldata.parameters -- - parameters.slant = 0 -- 1 - parameters.space = 0 -- 2 - parameters.space_stretch = 0 -- 3 - parameters.space_shrink = 0 -- 4 - parameters.x_height = 0 -- 5 - parameters.quad = 0 -- 6 - parameters.extra_space = 0 -- 7 - parameters.designsize = 655360 + parameters.slant = 0 -- 1 + parameters.space = 0 -- 2 + parameters.spacestretch = 0 -- 3 + parameters.spaceshrink = 0 -- 4 + parameters.xheight = 0 -- 5 + parameters.quad = 0 -- 6 + parameters.extraspace = 0 -- 7 + parameters.designsize = 655360 -- constructors.enhanceparameters(parameters) -- official copies for us -- diff --git a/tex/context/base/mkxl/font-hsh.lmt b/tex/context/base/mkxl/font-hsh.lmt new file mode 100644 index 000000000..594f47332 --- /dev/null +++ b/tex/context/base/mkxl/font-hsh.lmt @@ -0,0 +1,397 @@ +if not modules then modules = { } end modules ['font-hsh'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local rawget = rawget + +local setmetatableindex = table.setmetatableindex +local currentfont = font and font.current -- used in the web service +local allocate = utilities.storage.allocate + +local fonts = fonts +local hashes = fonts.hashes or allocate() +fonts.hashes = hashes + +-- todo: autoallocate ... just create on the fly .. use constructors.keys (problem: plurals) + +local identifiers = hashes.identifiers or allocate() +local characters = hashes.characters or allocate() -- chardata +local descriptions = hashes.descriptions or allocate() +local parameters = hashes.parameters or allocate() +local mathparameters = hashes.mathparameters or allocate() +local properties = hashes.properties or allocate() +local resources = hashes.resources or allocate() +local spacings = hashes.spacings or allocate() +local spaces = hashes.spaces or allocate() +local quads = hashes.quads or allocate() -- maybe also spacedata +local xheights = hashes.xheights or allocate() +local csnames = hashes.csnames or allocate() -- namedata +local features = hashes.features or allocate() +local marks = hashes.marks or allocate() +local classes = hashes.classes or allocate() +local italics = hashes.italics or allocate() +local lastmathids = hashes.lastmathids or allocate() +local dynamics = hashes.dynamics or allocate() +local unicodes = hashes.unicodes or allocate() +local unislots = hashes.unislots or allocate() +local originals = hashes.originals or allocate() +local modes = hashes.modes or allocate() +local variants = hashes.variants or allocate() + +hashes.characters = characters +hashes.descriptions = descriptions +hashes.parameters = parameters +hashes.mathparameters = mathparameters +hashes.properties = properties +hashes.resources = resources +hashes.spacings = spacings +hashes.spaces = spaces +hashes.quads = quads hashes.emwidths = quads +hashes.xheights = xheights hashes.exheights = xheights +hashes.csnames = csnames +hashes.features = features +hashes.marks = marks +hashes.classes = classes +hashes.italics = italics +hashes.lastmathids = lastmathids +hashes.dynamics = dynamics +hashes.unicodes = unicodes +hashes.unislots = unislots +hashes.originals = originals +hashes.modes = modes +hashes.variants = variants + +local nodepool = nodes and nodes.pool +local dummyglyph = nodepool and nodepool.register(nodepool.glyph()) + +local nulldata = allocate { + name = "nullfont", + characters = { }, + descriptions = { }, + properties = { + designsize = 786432, -- really ? maybe move to 655360 instead + }, + parameters = { -- lmromanregular @ 12pt + slantperpoint = 0, + spacing = { + width = 256377, + stretch = 128188, + shrink = 85459, + extra = 85459, + }, + quad = 786432, + size = 786432, + slant = 0, -- 1 + space = 256377, -- 2 + spacestretch = 128188, -- 3 + spaceshrink = 85459, -- 4 + xheight = 338952, -- 5 + quad = 786432, -- 6 + extraspace = 85459, -- 7 + }, +} + +fonts.nulldata = nulldata + +fonts.constructors.enhanceparameters(nulldata.parameters) -- official copies for us + +setmetatableindex(identifiers, function(t,k) + return k == true and identifiers[currentfont()] or nulldata +end) + +if font then + + -- to be used + + local define = font.define + local setfont = font.setfont + local frozen = font.frozen + + function fonts.reserveid(fontdata) + return define(fontdata or nulldata) + end + + function fonts.enhanceid(id,fontdata) + if not frozen(id) then + setfont(id,fontdata) + end + end + +end + +setmetatableindex(characters, function(t,k) + if k == true then + return characters[currentfont()] + else + local characters = identifiers[k].characters + t[k] = characters + return characters + end +end) + +setmetatableindex(descriptions, function(t,k) + if k == true then + return descriptions[currentfont()] + else + local descriptions = identifiers[k].descriptions + t[k] = descriptions + return descriptions + end +end) + +setmetatableindex(parameters, function(t,k) + if k == true then + return parameters[currentfont()] + else + local parameters = identifiers[k].parameters + t[k] = parameters + return parameters + end +end) + +setmetatableindex(mathparameters, function(t,k) + if k == true then + return mathparameters[currentfont()] + else + local mathparameters = identifiers[k].mathparameters + t[k] = mathparameters + return mathparameters + end +end) + +setmetatableindex(properties, function(t,k) + if k == true then + return properties[currentfont()] + else + local properties = identifiers[k].properties + t[k] = properties + return properties + end +end) + +setmetatableindex(resources, function(t,k) + if k == true then + return resources[currentfont()] + else + local shared = identifiers[k].shared + local rawdata = shared and shared.rawdata + local resources = rawdata and rawdata.resources + t[k] = resources or false -- better than resolving each time + return resources + end +end) + +setmetatableindex(features, function(t,k) + if k == true then + return features[currentfont()] + else + local shared = identifiers[k].shared + local features = shared and shared.features or { } + t[k] = features + return features + end +end) + +local nospacing = { + width = 0, + stretch = 0, + shrink = 0, + extra = 0, +} + +setmetatableindex(spacings, function(t,k) + if k == true then + return spacings[currentfont()] + else + local parameters = parameters[k] + local spacing = parameters and parameters.spacing or nospacing + t[k] = spacing + return spacing + end +end) + +setmetatableindex(spaces, function(t,k) + if k == true then + return spaces[currentfont()] + else + local space = spacings[k].width + t[k] = space + return space + end +end) + +setmetatableindex(marks, function(t,k) + if k == true then + return marks[currentfont()] + else + local resources = identifiers[k].resources or { } + local marks = resources.marks or { } + t[k] = marks + return marks + end +end) + +setmetatableindex(classes, function(t,k) + if k == true then + return classes[currentfont()] + else + local resources = identifiers[k].resources or { } + local classes = resources.classes or { } + t[k] = classes + return classes + end +end) + +setmetatableindex(quads, function(t,k) + if k == true then + return quads[currentfont()] + else + local parameters = rawget(parameters,k) + local quad + if parameters then + quad = parameters.quad + elseif dummyglyph then + dummyglyph.font = k + dummyglyph.char = 0x2014 -- emdash + quad = dummyglyph.width -- dirty trick + end + if not quad or quad == 0 then + quad = 655360 -- lm 10pt + end + t[k] = quad + return quad + end +end) + +setmetatableindex(xheights, function(t,k) + if k == true then + return xheights[currentfont()] + else + local parameters = rawget(parameters,k) + local xheight + if parameters then + xheight = parameters.xheight + elseif dummyglyph then + dummyglyph.font = k + dummyglyph.char = 0x78 -- x + xheight = dummyglyph.height -- dirty trick + end + if not xheight or xheight == 0 then + xheight = 282460 -- lm 10pt + end + t[k] = xheight + return xheight + end +end) + +setmetatableindex(italics, function(t,k) -- is test ! + if k == true then + return italics[currentfont()] + else + local properties = identifiers[k].properties + local hasitalics = properties and properties.hasitalics + if hasitalics then + hasitalics = characters[k] -- convenient return + else + hasitalics = false + end + t[k] = hasitalics + return hasitalics + end +end) + +setmetatableindex(dynamics, function(t,k) + if k == true then + return dynamics[currentfont()] + else + local shared = identifiers[k].shared + local dynamics = shared and shared.dynamics or false + t[k] = dynamics + return dynamics + end +end) + +setmetatableindex(unicodes, function(t,k) -- always a unicode + if k == true then + return unicodes[currentfont()] + else + local resources = resources[k] + local unicodes = resources and resources.unicodes or { } + t[k] = unicodes + return unicodes + end +end) + +setmetatableindex(originals, function(t,k) -- always a unicode + if k == true then + return originals[currentfont()] + else + local resolved = { } + setmetatableindex(resolved,function(t,name) + local u = unicodes[k][name] + local d = u and descriptions[k][u] + local v = d and d.unicode or u or 0 -- so we return notdef (at least for the moment) + t[name] = u + return v + end) + t[k] = resolved + return resolved + end +end) + +setmetatableindex(unislots, function(t,k) + if k == true then + return unislots[currentfont()] + else + local characters = identifiers[k].characters + local resolved = setmetatableindex(function(t,k) + local c = characters[k] + local v = c and c.unicode or 0xFFFD + t[k] = v + return v -- can be a table ! + end) + t[k] = resolved + return resolved + end +end) + +setmetatableindex(modes, function(t,k) + if k == true then + return modes[currentfont()] + else + local mode = properties[k].mode or "base" + t[k] = mode + return mode + end +end) + +setmetatableindex(variants, function(t,k) + if k == true then + return variants[currentfont()] + else + local resources = resources[k] + if resources then + local variants = resources.variants + if variants and next(variants) then + t[k] = variants + return variants + end + end + t[k] = false + return false + end +end) + +if font then + + function font.getfont(id) + return identifiers[id] + end + +end + +-- font.setfont = currentfont -- bah, no native 'setfont' as name diff --git a/tex/context/base/mkxl/font-imp-quality.lmt b/tex/context/base/mkxl/font-imp-quality.lmt new file mode 100644 index 000000000..93ec1b653 --- /dev/null +++ b/tex/context/base/mkxl/font-imp-quality.lmt @@ -0,0 +1,583 @@ +if not modules then modules = { } end modules ['font-imp-quality'] = { + 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" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber + +local fonts = fonts +local utilities = utilities + +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local allocate = utilities.storage.allocate +local getparameters = utilities.parsers.getparameters + +local implement = interfaces and interfaces.implement + +local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) +local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) + +local report_expansions = logs.reporter("fonts","expansions") +local report_protrusions = logs.reporter("fonts","protrusions") + +-- -- -- -- -- -- +-- shared +-- -- -- -- -- -- + +local function get_class_and_vector(tfmdata,value,where) -- "expansions" + local g_where = tfmdata.goodies and tfmdata.goodies[where] + local f_where = fonts[where] + local g_classes = g_where and g_where.classes + local f_classes = f_where and f_where.classes + local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) + if class then + local class_vector = class.vector + local g_vectors = g_where and g_where.vectors + local f_vectors = f_where and f_where.vectors + local vector = (g_vectors and g_vectors[class_vector]) or (f_vectors and f_vectors[class_vector]) + return class, vector + end +end + +-- -- -- -- -- -- +-- expansion (hz) +-- -- -- -- -- -- + +local expansions = fonts.expansions or allocate() + +fonts.expansions = expansions + +local classes = expansions.classes or allocate() +local vectors = expansions.vectors or allocate() + +expansions.classes = classes +expansions.vectors = vectors + +classes.preset = { + stretch = 2, + shrink = 2, + step = .5, + factor = 1, +} + +classes['quality'] = { + stretch = 2, + shrink = 2, + step = .5, + vector = 'default', + factor = 1, +} + +vectors['default'] = { + [0x0041] = 0.5, -- A + [0x0042] = 0.7, -- B + [0x0043] = 0.7, -- C + [0x0044] = 0.5, -- D + [0x0045] = 0.7, -- E + [0x0046] = 0.7, -- F + [0x0047] = 0.5, -- G + [0x0048] = 0.7, -- H + [0x004B] = 0.7, -- K + [0x004D] = 0.7, -- M + [0x004E] = 0.7, -- N + [0x004F] = 0.5, -- O + [0x0050] = 0.7, -- P + [0x0051] = 0.5, -- Q + [0x0052] = 0.7, -- R + [0x0053] = 0.7, -- S + [0x0055] = 0.7, -- U + [0x0057] = 0.7, -- W + [0x005A] = 0.7, -- Z + [0x0061] = 0.7, -- a + [0x0062] = 0.7, -- b + [0x0063] = 0.7, -- c + [0x0064] = 0.7, -- d + [0x0065] = 0.7, -- e + [0x0067] = 0.7, -- g + [0x0068] = 0.7, -- h + [0x006B] = 0.7, -- k + [0x006D] = 0.7, -- m + [0x006E] = 0.7, -- n + [0x006F] = 0.7, -- o + [0x0070] = 0.7, -- p + [0x0071] = 0.7, -- q + [0x0073] = 0.7, -- s + [0x0075] = 0.7, -- u + [0x0077] = 0.7, -- w + [0x007A] = 0.7, -- z + [0x0032] = 0.7, -- 2 + [0x0033] = 0.7, -- 3 + [0x0036] = 0.7, -- 6 + [0x0038] = 0.7, -- 8 + [0x0039] = 0.7, -- 9 +} + +vectors['quality'] = vectors['default'] -- metatable ? + +local function initialize(tfmdata,value) + if value then + local class, vector = get_class_and_vector(tfmdata,value,"expansions") + if class then + if vector then + local stretch = class.stretch or 0 + local shrink = class.shrink or 0 + local step = class.step or 0 + local factor = class.factor or 1 + if trace_expansion then + report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", + value,class.vector,factor,stretch,shrink,step) + end + tfmdata.parameters.expansion = { + stretch = 10 * stretch, + shrink = 10 * shrink, + step = 10 * step, + factor = factor, + } + local data = characters and characters.data + for i, chr in next, tfmdata.characters do + local v = vector[i] + if data and not v then -- we could move the data test outside (needed for plain) + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 + else + v = vector[s] or 0 + end + end + end + if v and v ~= 0 then + chr.expansion = v*factor + else -- can be option + chr.expansion = factor + end + end + elseif trace_expansion then + report_expansions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_expansion then + report_expansions("unknown class %a",value) + end + end +end + +local specification = { + name = "expansion", + description = "apply hz optimization", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) + +implement { + name = "setupfontexpansion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end +} + +-- -- -- -- -- -- +-- protrusion +-- -- -- -- -- -- + +fonts.protrusions = allocate() +local protrusions = fonts.protrusions + +protrusions.classes = allocate() +protrusions.vectors = allocate() + +local classes = protrusions.classes +local vectors = protrusions.vectors + +-- the values need to be revisioned + +classes.preset = { + factor = 1, + left = 1, + right = 1, +} + +classes['pure'] = { vector = 'pure', factor = 1 } +classes['punctuation'] = { vector = 'punctuation', factor = 1 } +classes['alpha'] = { vector = 'alpha', factor = 1 } +classes['quality'] = { vector = 'quality', factor = 1 } + +vectors['pure'] = { + + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x00AD] = { 0, 1 }, -- also hyphen + [0x2013] = { 0, 0.50 }, -- endash + [0x2014] = { 0, 0.33 }, -- emdash + [0x3001] = { 0, 1 }, -- ideographic comma 、 + [0x3002] = { 0, 1 }, -- ideographic full stop 。 + [0x060C] = { 0, 1 }, -- arabic comma ، + [0x061B] = { 0, 1 }, -- arabic semicolon ؛ + [0x06D4] = { 0, 1 }, -- arabic full stop ۔ + +} + +vectors['punctuation'] = { + + [0x003F] = { 0, 0.20 }, -- ? + [0x00BF] = { 0.20, 0 }, -- ¿ + [0x0021] = { 0, 0.20 }, -- ! + [0x00A1] = { 0.20, 0, }, -- ¡ + [0x0028] = { 0.05, 0 }, -- ( + [0x0029] = { 0, 0.05 }, -- ) + [0x005B] = { 0.05, 0 }, -- [ + [0x005D] = { 0, 0.05 }, -- ] + [0x002C] = { 0, 0.70 }, -- comma + [0x002E] = { 0, 0.70 }, -- period + [0x003A] = { 0, 0.50 }, -- colon + [0x003B] = { 0, 0.50 }, -- semicolon + [0x002D] = { 0, 0.70 }, -- hyphen + [0x00AD] = { 0, 0.70 }, -- also hyphen + [0x2013] = { 0, 0.30 }, -- endash + [0x2014] = { 0, 0.20 }, -- emdash + [0x060C] = { 0, 0.70 }, -- arabic comma + [0x061B] = { 0, 0.50 }, -- arabic semicolon + [0x06D4] = { 0, 0.70 }, -- arabic full stop + [0x061F] = { 0, 0.20 }, -- ؟ + + -- todo: left and right quotes: .5 double, .7 single + + [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ + [0x203A] = { 0.70, 0.70 }, -- right single guillemet › + [0x00AB] = { 0.50, 0.50 }, -- left guillemet « + [0x00BB] = { 0.50, 0.50 }, -- right guillemet » + + [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ + [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ + [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , + [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ + [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ + [0x201D] = { 0, 0.50 }, -- right double quotation mark ” + [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ + [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ + +} + +vectors['alpha'] = { + + [0x0041] = { .05, .05 }, -- A + [0x0046] = { 0, .05 }, -- F + [0x004A] = { .05, 0 }, -- J + [0x004B] = { 0, .05 }, -- K + [0x004C] = { 0, .05 }, -- L + [0x0054] = { .05, .05 }, -- T + [0x0056] = { .05, .05 }, -- V + [0x0057] = { .05, .05 }, -- W + [0x0058] = { .05, .05 }, -- X + [0x0059] = { .05, .05 }, -- Y + + [0x006B] = { 0, .05 }, -- k + [0x0072] = { 0, .05 }, -- r + [0x0074] = { 0, .05 }, -- t + [0x0076] = { .05, .05 }, -- v + [0x0077] = { .05, .05 }, -- w + [0x0078] = { .05, .05 }, -- x + [0x0079] = { .05, .05 }, -- y + +} + +vectors['quality'] = table.merged( + vectors['punctuation'], + vectors['alpha'] +) + +-- As this is experimental code, users should not depend on it. The implications are still +-- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the +-- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The +-- double trick should not be needed it proper hanging punctuation is used in which case +-- values < 1 can be used. +-- +-- preferred (in context, usine vectors): +-- +-- \definefontfeature[whatever][default][mode=node,protrusion=quality] +-- +-- using lfbd and rtbd, with possibibility to enable only one side : +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] +-- +-- idem, using multiplier +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] +-- +-- idem, using named feature file (less frozen): +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] + +classes['double'] = { -- for testing opbd + factor = 2, + left = 1, + right = 1, +} + +local function map_opbd_onto_protrusion(tfmdata,value,opbd) + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local resources = tfmdata.resources + local rawdata = tfmdata.shared.rawdata + local lookuphash = rawdata.lookuphash + local lookuptags = resources.lookuptags + local script = properties.script + local language = properties.language + local units = parameters.units + local done, factor, left, right = false, 1, 1, 1 + local class = classes[value] + if class then + factor = class.factor or 1 + left = class.left or 1 + right = class.right or 1 + else + factor = tonumber(value) or 1 + end + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + if opbd ~= "right" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"lfbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting left using lfbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[1] + if w == 0 or d == 0 then + -- ignored + else + local p = lfactor * d/units + characters[k].leftprotrusion = p + if trace_protrusion then + report_protrusions("lfbd -> %0.3F %C",p,k) + end + end + end + end + end + end + done = true + end + end + end + end + if opbd ~= "left" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"rtbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting right using rtbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[3] + if w == 0 or d == 0 then + -- ignored + else + local p = rfactor * d/units + characters[k].rightprotrusion = p + if trace_protrusion then + report_protrusions("rtbd -> %0.3F %C",p,k) + end + end + end + end + end + end + end + done = true + end + end + end +end + +-- The opbd test is just there because it was discussed on the context development list. However, +-- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported +-- till we have a proper test font. + +local function initialize(tfmdata,value) + if value then + local opbd = tfmdata.shared.features.opbd + if opbd then + -- possible values: left right both yes no (experimental) + map_opbd_onto_protrusion(tfmdata,value,opbd) + else + local class, vector = get_class_and_vector(tfmdata,value,"protrusions") + if class then + if vector then + local factor = class.factor or 1 + local left = class.left or 1 + local right = class.right or 1 + if trace_protrusion then + report_protrusions("setting class %a, vector %a, factor %a, left %a, right %a", + value,class.vector,factor,left,right) + end + local data = characters.data + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + for i, chr in next, tfmdata.characters do + local v = vector[i] + local pl = nil + local pr = nil + if v then + pl = v[1] + pr = v[2] + else + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + local vl = vector[s[1]] + local vr = vector[s[#s]] + if vl then pl = vl[1] end + if vr then pr = vr[2] end + else + v = vector[s] + if v then + pl = v[1] + pr = v[2] + end + end + end + end + if pl and pl ~= 0 then + local p = pl * lfactor + chr.leftprotrusion = p + if trace_protrusion then + report_protrusions("left -> %0.3F %C ",p,i) + end + end + if pr and pr ~= 0 then + local p = pr * rfactor + chr.rightprotrusion = p + if trace_protrusion then + report_protrusions("right -> %0.3F %C",p,i) + end + end + end + elseif trace_protrusion then + report_protrusions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_protrusion then + report_protrusions("unknown class %a",value) + end + end + end +end + +local specification = { + name = "protrusion", + description = "l/r margin character protrusion", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) + +implement { + name = "setupfontprotrusion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end +} + +local function initialize(tfmdata,value) + local properties = tfmdata.properties + local parameters = tfmdata.parameters + if properties then + value = tonumber(value) + if value then + if value < 0 then + value = 0 + elseif value > 10 then + report_expansions("threshold for %a @ %p limited to 10 pct",properties.fontname,parameters.size) + value = 10 + end + if value > 5 then + report_expansions("threshold for %a @ %p exceeds 5 pct",properties.fontname,parameters.size) + end + end + properties.threshold = value or nil -- nil enforces default + end +end + +local specification = { + name = "threshold", + description = "threshold for quality features", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) diff --git a/tex/context/base/mkxl/font-imp-tracing.lmt b/tex/context/base/mkxl/font-imp-tracing.lmt index 9f842b522..2187b9497 100644 --- a/tex/context/base/mkxl/font-imp-tracing.lmt +++ b/tex/context/base/mkxl/font-imp-tracing.lmt @@ -186,7 +186,7 @@ local function initialize(tfmdata,key,value) 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 + local italic = character.vitalic or character.italic if mathkern or (italic and italic ~= 0) then local width = character.width or 0 local height = character.height or 0 @@ -202,10 +202,10 @@ local function initialize(tfmdata,key,value) 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 + local br = mathkern.bottomright + local tr = mathkern.topright + local bl = mathkern.bottomleft + local tl = mathkern.topleft if br then local done = false for i=1,#br do diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx index db90bc79c..6a926bcbd 100644 --- a/tex/context/base/mkxl/font-ini.mklx +++ b/tex/context/base/mkxl/font-ini.mklx @@ -703,6 +703,8 @@ \mutable\let\lastrawfontcall \relax \mutable\let\lastglobalrawfontcall\relax +\immutable\dimensiondef\d_font_default_size 10pt + \protected\def\font_helpers_low_level_define {\ifconditional\c_font_compact \expandafter\font_helpers_low_level_define_compact @@ -733,8 +735,10 @@ \fi % \ifcase\scaledfontmode\relax - % none, avoid the designsize if possible - \d_font_scaled_font_size-\plusthousand\scaledpoint + % mkiv, fails with glyphscale: + % \d_font_scaled_font_size-\plusthousand\scaledpoint + % so we just assume + \d_font_scaled_font_size\d_font_default_size \or % at \d_font_scaled_font_size\somefontsize @@ -830,8 +834,10 @@ \fi % \ifcase\scaledfontmode\relax - % none, avoid the designsize if possible - \d_font_scaled_font_size-\plusthousand\scaledpoint + % mkiv, fails with glyphscale: + % \d_font_scaled_font_size-\plusthousand\scaledpoint + % so we just assume + \d_font_scaled_font_size\d_font_default_size \or % at \d_font_scaled_font_size\somefontsize diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx index e8c5ad246..2f20214e7 100644 --- a/tex/context/base/mkxl/font-lib.mklx +++ b/tex/context/base/mkxl/font-lib.mklx @@ -21,30 +21,30 @@ %registerctxluafile{font-cft}{} \registerctxluafile{font-enc}{} \registerctxluafile{font-fmp}{autosuffix} -\registerctxluafile{font-agl}{} % if needed we can comment this and delay loading -\registerctxluafile{font-cid}{} % cid maps +\registerctxluafile{font-agl}{} % if needed we can comment this and delay loading +\registerctxluafile{font-cid}{} % cid maps \registerctxluafile{font-map}{optimize} % helpers -\registerctxluafile{font-otr}{optimize} % opentype fontloader -\registerctxluafile{font-web}{} % opentype fontloader -\registerctxluafile{font-cff}{optimize} % quadratic outlines -\registerctxluafile{font-ttf}{optimize} % cubic outlines -\registerctxluafile{font-dsp}{optimize} % ... for this one -\registerctxluafile{font-hsh}{} % hashes used by context +\registerctxluafile{font-otr}{optimize} % opentype fontloader +\registerctxluafile{font-web}{} % opentype fontloader +\registerctxluafile{font-cff}{optimize} % quadratic outlines +\registerctxluafile{font-ttf}{optimize} % cubic outlines +\registerctxluafile{font-dsp}{optimize} % ... for this one +\registerctxluafile{font-hsh}{autosuffix} % hashes used by context \registerctxluafile{font-vir}{} \registerctxluafile{font-vfc}{autosuffix} -\registerctxluafile{font-prv}{} % needs hashes +\registerctxluafile{font-prv}{} % needs hashes \registerctxluafile{font-nod}{optimize} -\registerctxluafile{font-oti}{} % otf initialization -\registerctxluafile{font-ott}{} % otf tables (first) -\registerctxluafile{font-otl}{} +\registerctxluafile{font-oti}{} % otf initialization +\registerctxluafile{font-ott}{} % otf tables (first) +\registerctxluafile{font-otl}{autosuffix} \registerctxluafile{font-oto}{} \registerctxluafile{font-otj}{autosuffix,optimize} \registerctxluafile{font-oup}{} \registerctxluafile{font-ota}{autosuffix} -% \registerctxluafile{font-ots-pre-scale}{autosuffix,optimize} +%registerctxluafile{font-ots-pre-scale}{autosuffix,optimize} \registerctxluafile{font-ots}{autosuffix,optimize} \registerctxluafile{font-otd}{autosuffix,optimize} \registerctxluafile{font-otc}{} @@ -56,15 +56,15 @@ % we use otf code for type one \registerctxluafile{font-onr}{optimize} -\registerctxluafile{font-one}{optimize} +\registerctxluafile{font-one}{autosuffix,optimize} \registerctxluafile{font-afk}{} \registerctxluafile{font-txt}{autosuffix} % tfm -\registerctxluafile{font-tpk}{optimize} -\registerctxluafile{font-tfm}{} +\registerctxluafile{font-tpk}{autosuffix,optimize} +\registerctxluafile{font-tfm}{autosuffix} % name database @@ -100,13 +100,13 @@ \registerctxluafile{font-imp-ligatures}{} \registerctxluafile{font-imp-tex}{} \registerctxluafile{font-imp-reorder}{} -\registerctxluafile{font-imp-properties}{} +\registerctxluafile{font-imp-properties}{autosuffix} \registerctxluafile{font-imp-unicode}{} \registerctxluafile{font-imp-text}{autosuffix} \registerctxluafile{font-imp-math}{autosuffix} \registerctxluafile{font-imp-notused}{} \registerctxluafile{font-imp-effects}{autosuffix} -\registerctxluafile{font-imp-quality}{} +\registerctxluafile{font-imp-quality}{autosuffix} \registerctxluafile{font-imp-italics}{} \registerctxluafile{font-imp-dimensions}{} \registerctxluafile{font-imp-spacekerns}{} diff --git a/tex/context/base/mkxl/font-one.lmt b/tex/context/base/mkxl/font-one.lmt new file mode 100644 index 000000000..453f61192 --- /dev/null +++ b/tex/context/base/mkxl/font-one.lmt @@ -0,0 +1,847 @@ +if not modules then modules = { } end modules ['font-one'] = { + version = 1.001, + optimize = true, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>Some code may look a bit obscure but this has to do with the fact that we also use +this code for testing and much code evolved in the transition from <l n='tfm'/> to +<l n='afm'/> to <l n='otf'/>.</p> + +<p>The following code still has traces of intermediate font support where we handles +font encodings. Eventually font encoding went away but we kept some code around in +other modules.</p> + +<p>This version implements a node mode approach so that users can also more easily +add features.</p> +--ldx]]-- + +local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers + +local next, type, tonumber, rawget = next, type, tonumber, rawget +local match, gsub = string.match, string.gsub +local abs = math.abs +local P, S, R, Cmt, C, Ct, Cs, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg +local lpegmatch, patterns = lpeg.match, lpeg.patterns +local sortedhash = table.sortedhash + +local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) +local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) +local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +local report_afm = logs.reporter("fonts","afm loading") + +local setmetatableindex = table.setmetatableindex +local derivetable = table.derive + +local findbinfile = resolvers.findbinfile + +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF + +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors + +local afm = constructors.handlers.afm +local pfb = constructors.handlers.pfb +local otf = fonts.handlers.otf + +local otfreaders = otf.readers +local otfenhancers = otf.enhancers + +local afmfeatures = constructors.features.afm +local registerafmfeature = afmfeatures.register + +local afmenhancers = constructors.enhancers.afm +local registerafmenhancer = afmenhancers.register + +afm.version = 1.513 -- incrementing this number one up will force a re-cache +afm.cache = containers.define("fonts", "one", afm.version, true) +afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) + +afm.helpdata = { } -- set later on so no local for this +afm.syncspace = true -- when true, nicer stretch values + +local overloads = fonts.mappings.overloads + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes + +--[[ldx-- +<p>We cache files. Caching is taken care of in the loader. We cheat a bit by adding +ligatures and kern information to the afm derived data. That way we can set them faster +when defining a font.</p> + +<p>We still keep the loading two phased: first we load the data in a traditional +fashion and later we transform it to sequences. Then we apply some methods also +used in opentype fonts (like <t>tlig</t>).</p> +--ldx]]-- + +function afm.load(filename) + filename = resolvers.findfile(filename,'afm') or "" + if filename ~= "" and not fonts.names.ignoredfile(filename) then + local name = file.removesuffix(file.basename(filename)) + local data = containers.read(afm.cache,name) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + -- + local pfbfile = file.replacesuffix(name,"pfb") + local pfbname = resolvers.findfile(pfbfile,"pfb") or "" + if pfbname == "" then + pfbname = resolvers.findfile(file.basename(pfbfile),"pfb") or "" + end + local pfbsize = 0 + local pfbtime = 0 + if pfbname ~= "" then + local attr = lfs.attributes(pfbname) + pfbsize = attr.size or 0 + pfbtime = attr.modification or 0 + end + if not data or data.size ~= size or data.time ~= time or data.pfbsize ~= pfbsize or data.pfbtime ~= pfbtime then + report_afm("reading %a",filename) + data = afm.readers.loadfont(filename,pfbname) + if data then + afmenhancers.apply(data,filename) + -- otfreaders.addunicodetable(data) -- only when not done yet + fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) + -- otfreaders.extend(data) + otfreaders.pack(data) + data.size = size + data.time = time + data.pfbsize = pfbsize + data.pfbtime = pfbtime + report_afm("saving %a in cache",name) + -- data.resources.unicodes = nil -- consistent with otf but here we save not much + data = containers.write(afm.cache, name, data) + data = containers.read(afm.cache,name) + end + end + if data then + -- constructors.addcoreunicodes(unicodes) + otfreaders.unpack(data) + otfreaders.expand(data) -- inline tables + otfreaders.addunicodetable(data) -- only when not done yet + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + end + return data + end +end + +-- we run a more advanced analyzer later on anyway + +local uparser = fonts.mappings.makenameparser() -- each time + +local function enhance_unify_names(data, filename) + local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context + local unicodes = { } + local names = { } + local private = data.private or privateoffset + local descriptions = data.descriptions + for name, blob in sortedhash(data.characters) do -- sorting is nicer for privates + local code = unicodevector[name] -- or characters.name_to_unicode[name] + if not code then + code = lpegmatch(uparser,name) + if type(code) ~= "number" then + code = private + private = private + 1 + report_afm("assigning private slot %U for unknown glyph name %a",code,name) + end + end + local index = blob.index + unicodes[name] = code + names[name] = index + blob.name = name + descriptions[code] = { + boundingbox = blob.boundingbox, + width = blob.width, + kerns = blob.kerns, + index = index, + name = name, + } + end + for unicode, description in next, descriptions do + local kerns = description.kerns + if kerns then + local krn = { } + for name, kern in next, kerns do + local unicode = unicodes[name] + if unicode then + krn[unicode] = kern + else + -- print(unicode,name) + end + end + description.kerns = krn + end + end + data.characters = nil + data.private = private + local resources = data.resources + local filename = resources.filename or file.removesuffix(file.basename(filename)) + resources.filename = resolvers.unresolve(filename) -- no shortcut + resources.unicodes = unicodes -- name to unicode + resources.marks = { } -- todo + -- resources.names = names -- name to index +end + +local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } +local noflags = { false, false, false, false } + +local function enhance_normalize_features(data) + local ligatures = setmetatableindex("table") + local kerns = setmetatableindex("table") + local extrakerns = setmetatableindex("table") + for u, c in next, data.descriptions do + local l = c.ligatures + local k = c.kerns + local e = c.extrakerns + if l then + ligatures[u] = l + for u, v in next, l do + l[u] = { ligature = v } + end + c.ligatures = nil + end + if k then + kerns[u] = k + for u, v in next, k do + k[u] = v -- { v, 0 } + end + c.kerns = nil + end + if e then + extrakerns[u] = e + for u, v in next, e do + e[u] = v -- { v, 0 } + end + c.extrakerns = nil + end + end + local features = { + gpos = { }, + gsub = { }, + } + local sequences = { + -- only filled ones + } + if next(ligatures) then + features.gsub.liga = everywhere + data.properties.hasligatures = true + sequences[#sequences+1] = { + features = { + liga = everywhere, + }, + flags = noflags, + name = "s_s_0", + nofsteps = 1, + order = { "liga" }, + type = "gsub_ligature", + steps = { + { + coverage = ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern = everywhere + data.properties.haskerns = true + sequences[#sequences+1] = { + features = { + kern = everywhere, + }, + flags = noflags, + name = "p_s_0", + nofsteps = 1, + order = { "kern" }, + type = "gpos_pair", + steps = { + { + format = "kern", + coverage = kerns, + }, + }, + } + end + if next(extrakerns) then + features.gpos.extrakerns = everywhere + data.properties.haskerns = true + sequences[#sequences+1] = { + features = { + extrakerns = everywhere, + }, + flags = noflags, + name = "p_s_1", + nofsteps = 1, + order = { "extrakerns" }, + type = "gpos_pair", + steps = { + { + format = "kern", + coverage = extrakerns, + }, + }, + } + end + -- todo: compress kerns + data.resources.features = features + data.resources.sequences = sequences +end + +local function enhance_fix_names(data) + for k, v in next, data.descriptions do + local n = v.name + local r = overloads[n] + if r then + local name = r.name + if trace_indexing then + report_afm("renaming characters %a to %a",n,name) + end + v.name = name + v.unicode = r.unicode + end + end +end + +--[[ldx-- +<p>These helpers extend the basic table with extra ligatures, texligatures +and extra kerns. This saves quite some lookups later.</p> +--ldx]]-- + +local addthem = function(rawdata,ligatures) + if ligatures then + local descriptions = rawdata.descriptions + local resources = rawdata.resources + local unicodes = resources.unicodes + -- local names = resources.names + for ligname, ligdata in next, ligatures do + local one = descriptions[unicodes[ligname]] + if one then + for _, pair in next, ligdata do + local two = unicodes[pair[1]] + local three = unicodes[pair[2]] + if two and three then + local ol = one.ligatures + if ol then + if not ol[two] then + ol[two] = three + end + else + one.ligatures = { [two] = three } + end + end + end + end + end + end +end + +local function enhance_add_ligatures(rawdata) + addthem(rawdata,afm.helpdata.ligatures) +end + +--[[ldx-- +<p>We keep the extra kerns in separate kerning tables so that we can use +them selectively.</p> +--ldx]]-- + +-- This is rather old code (from the beginning when we had only tfm). If +-- we unify the afm data (now we have names all over the place) then +-- we can use shcodes but there will be many more looping then. But we +-- could get rid of the tables in char-cmp then. Als, in the generic version +-- we don't use the character database. (Ok, we can have a context specific +-- variant). + +local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust here + local descriptions = rawdata.descriptions + local resources = rawdata.resources + local unicodes = resources.unicodes + local function do_it_left(what) + if what then + for unicode, description in next, descriptions do + local kerns = description.kerns + if kerns then + local extrakerns + for complex, simple in next, what do + complex = unicodes[complex] + simple = unicodes[simple] + if complex and simple then + local ks = kerns[simple] + if ks and not kerns[complex] then + if extrakerns then + extrakerns[complex] = ks + else + extrakerns = { [complex] = ks } + end + end + end + end + if extrakerns then + description.extrakerns = extrakerns + end + end + end + end + end + local function do_it_copy(what) + if what then + for complex, simple in next, what do + complex = unicodes[complex] + simple = unicodes[simple] + if complex and simple then + local complexdescription = descriptions[complex] + if complexdescription then -- optional + local simpledescription = descriptions[complex] + if simpledescription then + local extrakerns + local kerns = simpledescription.kerns + if kerns then + for unicode, kern in next, kerns do + if extrakerns then + extrakerns[unicode] = kern + else + extrakerns = { [unicode] = kern } + end + end + end + local extrakerns = simpledescription.extrakerns + if extrakerns then + for unicode, kern in next, extrakerns do + if extrakerns then + extrakerns[unicode] = kern + else + extrakerns = { [unicode] = kern } + end + end + end + if extrakerns then + complexdescription.extrakerns = extrakerns + end + end + end + end + end + end + end + -- add complex with values of simplified when present + do_it_left(afm.helpdata.leftkerned) + do_it_left(afm.helpdata.bothkerned) + -- copy kerns from simple char to complex char unless set + do_it_copy(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.rightkerned) +end + +--[[ldx-- +<p>The copying routine looks messy (and is indeed a bit messy).</p> +--ldx]]-- + +local function adddimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name + if data then + for unicode, description in next, data.descriptions do + local bb = description.boundingbox + if bb then + local ht = bb[4] + local dp = -bb[2] + if ht == 0 or ht < 0 then + -- no need to set it and no negative heights, nil == 0 + else + description.height = ht + end + if dp == 0 or dp < 0 then + -- no negative depths and no negative depths, nil == 0 + else + description.depth = dp + end + end + end + end +end + +local function copytotfm(data) + if data and data.descriptions then + local metadata = data.metadata + local resources = data.resources + local properties = derivetable(data.properties) + local descriptions = derivetable(data.descriptions) + local goodies = derivetable(data.goodies) + local characters = { } + local parameters = { } + local unicodes = resources.unicodes + -- + for unicode, description in next, data.descriptions do -- use parent table + characters[unicode] = { } + end + -- + local filename = constructors.checkedfilename(resources) + local fontname = metadata.fontname or metadata.fullname + local fullname = metadata.fullname or metadata.fontname + local endash = 0x2013 + local emdash = 0x2014 + local space = 0x0020 -- space + local spacer = "space" + local spaceunits = 500 + -- + local monospaced = metadata.monospaced + local charwidth = metadata.charwidth + local italicangle = metadata.italicangle + local charxheight = metadata.xheight and metadata.xheight > 0 and metadata.xheight + properties.monospaced = monospaced + parameters.italicangle = italicangle + parameters.charwidth = charwidth + parameters.charxheight = charxheight + -- nearly the same as otf, catches + local d_endash = descriptions[endash] + local d_emdash = descriptions[emdash] + local d_space = descriptions[space] + if not d_space or d_space == 0 then + d_space = d_endash + end + if d_space then + spaceunits, spacer = d_space.width or 0, "space" + end + if properties.monospaced then + if spaceunits == 0 and d_emdash then + spaceunits, spacer = d_emdash.width or 0, "emdash" + end + else + if spaceunits == 0 and d_endash then + spaceunits, spacer = d_emdash.width or 0, "endash" + end + end + if spaceunits == 0 and charwidth then + spaceunits, spacer = charwidth or 0, "charwidth" + end + if spaceunits == 0 then + spaceunits = tonumber(spaceunits) or 500 + end + if spaceunits == 0 then + spaceunits = 500 + end + -- + parameters.slant = 0 + parameters.space = spaceunits + parameters.spacestretch = 500 + parameters.spaceshrink = 333 + parameters.xheight = 400 + parameters.quad = 1000 + -- + if italicangle and italicangle ~= 0 then + parameters.italicangle = italicangle + parameters.italicfactor = math.cos(math.rad(90+italicangle)) + parameters.slant = - math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.spacestretch = 0 + parameters.spaceshrink = 0 + elseif afm.syncspace then + parameters.spacestretch = spaceunits/2 + parameters.spaceshrink = spaceunits/3 + end + parameters.extraspace = parameters.spaceshrink + if charxheight then + parameters.xheight = charxheight + else + -- same as otf + local x = 0x0078 -- x + if x then + local x = descriptions[x] + if x then + parameters.xheight = x.height + end + end + -- + end + -- + if metadata.sup then + local dummy = { 0, 0, 0 } + parameters[ 1] = metadata.designsize or 0 + parameters[ 2] = metadata.checksum or 0 + parameters[ 3], + parameters[ 4], + parameters[ 5] = unpack(metadata.space or dummy) + parameters[ 6] = metadata.quad or 0 + parameters[ 7] = metadata.extraspace or 0 + parameters[ 8], + parameters[ 9], + parameters[10] = unpack(metadata.num or dummy) + parameters[11], + parameters[12] = unpack(metadata.denom or dummy) + parameters[13], + parameters[14], + parameters[15] = unpack(metadata.sup or dummy) + parameters[16], + parameters[17] = unpack(metadata.sub or dummy) + parameters[18] = metadata.supdrop or 0 + parameters[19] = metadata.subdrop or 0 + parameters[20], + parameters[21] = unpack(metadata.delim or dummy) + parameters[22] = metadata.axisheight or 0 + end + -- + parameters.designsize = (metadata.designsize or 10)*65536 + parameters.ascender = abs(metadata.ascender or 0) + parameters.descender = abs(metadata.descender or 0) + parameters.units = 1000 + -- + properties.spacer = spacer + properties.format = fonts.formats[filename] or "type1" + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = fullname + properties.name = filename or fullname or fontname + properties.private = properties.private or data.private or privateoffset + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then + properties.encodingbytes = 2 +end + -- + if next(characters) then + return { + characters = characters, + descriptions = descriptions, + parameters = parameters, + resources = resources, + properties = properties, + goodies = goodies, + } + end + end + return nil +end + +--[[ldx-- +<p>Originally we had features kind of hard coded for <l n='afm'/> files but since I +expect to support more font formats, I decided to treat this fontformat like any +other and handle features in a more configurable way.</p> +--ldx]]-- + +function afm.setfeatures(tfmdata,features) + local okay = constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) + if okay then + return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) + else + return { } -- will become false + end +end + +local function addtables(data) + local resources = data.resources + local lookuptags = resources.lookuptags + local unicodes = resources.unicodes + if not lookuptags then + lookuptags = { } + resources.lookuptags = lookuptags + end + setmetatableindex(lookuptags,function(t,k) + local v = type(k) == "number" and ("lookup " .. k) or k + t[k] = v + return v + end) + if not unicodes then + unicodes = { } + resources.unicodes = unicodes + setmetatableindex(unicodes,function(t,k) + setmetatableindex(unicodes,nil) + for u, d in next, data.descriptions do + local n = d.name + if n then + t[n] = u + end + end + return rawget(t,k) + end) + end + constructors.addcoreunicodes(unicodes) -- do we really need this? +end + +local function afmtotfm(specification) + local afmname = specification.filename or specification.name + if specification.forced == "afm" or specification.format == "afm" then -- move this one up + if trace_loading then + report_afm("forcing afm format for %a",afmname) + end + else + local tfmname = findbinfile(afmname,"ofm") or "" + if tfmname ~= "" then + if trace_loading then + report_afm("fallback from afm to tfm for %a",afmname) + end + return -- just that + end + end + if afmname ~= "" then + -- weird, isn't this already done then? + local features = constructors.checkedfeatures("afm",specification.features.normal) + specification.features.normal = features + constructors.hashinstance(specification,true) -- also weird here + -- + specification = definers.resolve(specification) -- new, was forgotten + local cache_id = specification.hash + local tfmdata = containers.read(constructors.cache, cache_id) -- cache with features applied + if not tfmdata then + local rawdata = afm.load(afmname) + if rawdata and next(rawdata) then + addtables(rawdata) + adddimensions(rawdata) + tfmdata = copytotfm(rawdata) + if tfmdata and next(tfmdata) then + local shared = tfmdata.shared + if not shared then + shared = { } + tfmdata.shared = shared + end + shared.rawdata = rawdata + shared.dynamics = { } + tfmdata.changed = { } + shared.features = features + shared.processes = afm.setfeatures(tfmdata,features) + end + elseif trace_loading then + report_afm("no (valid) afm file found with name %a",afmname) + end + tfmdata = containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata + end +end + +--[[ldx-- +<p>As soon as we could intercept the <l n='tfm'/> reader, I implemented an +<l n='afm'/> reader. Since traditional <l n='pdftex'/> could use <l n='opentype'/> +fonts with <l n='afm'/> companions, the following method also could handle +those cases, but now that we can handle <l n='opentype'/> directly we no longer +need this features.</p> +--ldx]]-- + +local function read_from_afm(specification) + local tfmdata = afmtotfm(specification) + if tfmdata then + tfmdata.properties.name = specification.name + tfmdata.properties.id = specification.id + tfmdata = constructors.scale(tfmdata, specification) + local allfeatures = tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) + fonts.loggers.register(tfmdata,'afm',specification) + end + return tfmdata +end + +--[[ldx-- +<p>We have the usual two modes and related features initializers and processors.</p> +--ldx]]-- + +registerafmfeature { + name = "mode", + description = "mode", + initializers = { + base = otf.modeinitializer, + node = otf.modeinitializer, + } +} + +registerafmfeature { + name = "features", + description = "features", + default = true, + initializers = { + node = otf.nodemodeinitializer, + base = otf.basemodeinitializer, + }, + processors = { + node = otf.featuresprocessor, + } +} + +-- readers + +fonts.formats.afm = "type1" +fonts.formats.pfb = "type1" + +local function check_afm(specification,fullname) + local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"afm") or "" + end + if fullname and foundname == "" and afm.autoprefixed then + local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* + if encoding and shortname and fonts.encodings.known[encoding] then + shortname = findbinfile(shortname,'afm') or "" -- just to be sure + if shortname ~= "" then + foundname = shortname + if trace_defining then + report_afm("stripping encoding prefix from filename %a",afmname) + end + end + end + end + if foundname ~= "" then + specification.filename = foundname + specification.format = "afm" + return read_from_afm(specification) + end +end + +function readers.afm(specification,method) + local fullname = specification.filename or "" + local tfmdata = nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmdata = check_afm(specification,specification.name .. "." .. forced) + end + if not tfmdata then + local check_tfm = readers.check_tfm + method = (check_tfm and (method or definers.method or "afm or tfm")) or "afm" + if method == "tfm" then + tfmdata = check_tfm(specification,specification.name) + elseif method == "afm" then + tfmdata = check_afm(specification,specification.name) + elseif method == "tfm or afm" then + tfmdata = check_tfm(specification,specification.name) or check_afm(specification,specification.name) + else -- method == "afm or tfm" or method == "" then + tfmdata = check_afm(specification,specification.name) or check_tfm(specification,specification.name) + end + end + else + tfmdata = check_afm(specification,fullname) + end + return tfmdata +end + +function readers.pfb(specification,method) -- only called when forced + local original = specification.specification + if trace_defining then + report_afm("using afm reader for %a",original) + end + specification.forced = "afm" + local function swap(name) + local value = specification[swap] + if value then + specification[swap] = gsub("%.pfb",".afm",1) + end + end + swap("filename") + swap("fullname") + swap("forcedname") + swap("specification") + return readers.afm(specification,method) +end + +-- now we register them + +registerafmenhancer("unify names", enhance_unify_names) +registerafmenhancer("add ligatures", enhance_add_ligatures) +registerafmenhancer("add extra kerns", enhance_add_extra_kerns) +registerafmenhancer("normalize features", enhance_normalize_features) +registerafmenhancer("check extra features", otfenhancers.enhance) +registerafmenhancer("fix names", enhance_fix_names) diff --git a/tex/context/base/mkxl/font-otl.lmt b/tex/context/base/mkxl/font-otl.lmt new file mode 100644 index 000000000..f493bc327 --- /dev/null +++ b/tex/context/base/mkxl/font-otl.lmt @@ -0,0 +1,889 @@ +if not modules then modules = { } end modules ['font-otl'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- After some experimenting with an alternative loader (one that is needed for +-- getting outlines in mp) I decided not to be compatible with the old (built-in) +-- one. The approach used in font-otn is as follows: we load the font in a compact +-- format but still very compatible with the ff data structures. From there we +-- create hashes to access the data efficiently. The implementation of feature +-- processing is mostly based on looking at the data as organized in the glyphs and +-- lookups as well as the specification. Keeping the lookup data in the glyphs is +-- very instructive and handy for tracing. On the other hand hashing is what brings +-- speed. So, the in the new approach (the old one will stay around too) we no +-- longer keep data in the glyphs which saves us a (what in retrospect looks a bit +-- like) a reconstruction step. It also means that the data format of the cached +-- files changes. What method is used depends on that format. There is no fundamental +-- change in processing, and not even in data organation. Most has to do with +-- loading and storage. + +-- todo: less tounicodes + +local lower = string.lower +local type, next, tonumber, tostring, unpack = type, next, tonumber, tostring, unpack +local abs = math.abs +local derivetable, sortedhash = table.derive, table.sortedhash +local formatters = string.formatters + +local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local registertracker = trackers.register +local registerdirective = directives.register +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local elapsedtime = statistics.elapsedtime +local findbinfile = resolvers.findbinfile + +----- trace_private = false registertracker("otf.private", function(v) trace_private = v end) +----- trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) +local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) +local trace_features = false registertracker("otf.features", function(v) trace_features = v end) +----- trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) +----- trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) +----- trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) +local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) + +local report_otf = logs.reporter("fonts","otf loading") + +local fonts = fonts +local otf = fonts.handlers.otf + +otf.version = 3.119 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.svgcache = containers.define("fonts", "svg", otf.version, true) +otf.pngcache = containers.define("fonts", "png", otf.version, true) +otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.mpscache = containers.define("fonts", "mps", otf.version, true) + +otf.svgenabled = false +otf.pngenabled = false + +local otfreaders = otf.readers + +local hashes = fonts.hashes +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors + +local otffeatures = constructors.features.otf +local registerotffeature = otffeatures.register + +local otfenhancers = constructors.enhancers.otf +local registerotfenhancer = otfenhancers.register + +local forceload = false +local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) +local syncspace = true +local forcenotdef = false + +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes + +local wildcard = "*" +local default = "dflt" + +local formats = fonts.formats + +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" + +registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) +registerdirective("fonts.otf.loader.force", function(v) forceload = v end) +registerdirective("fonts.otf.loader.syncspace", function(v) syncspace = v end) +registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = v end) + +-- otfenhancers.patch("before","migrate metadata","cambria",function() end) + +registerotfenhancer("check extra features", function() end) -- placeholder + +-- Kai has memory problems on osx so here is an experiment (I only tested on windows as +-- my test mac is old and gets no updates and is therefore rather useless.): + +local checkmemory = utilities.lua and utilities.lua.checkmemory +local threshold = 100 -- MB +local tracememory = false + +registertracker("fonts.otf.loader.memory",function(v) tracememory = v end) + +if not checkmemory then -- we need a generic plug (this code might move): + + local collectgarbage = collectgarbage + + checkmemory = function(previous,threshold) -- threshold in MB + local current = collectgarbage("count") + if previous then + local checked = (threshold or 64)*1024 + if current - previous > checked then + collectgarbage("collect") + current = collectgarbage("count") + end + end + return current + end + +end + +function otf.load(filename,sub,instance) + local base = file.basename(file.removesuffix(filename)) + local name = file.removesuffix(base) -- already no suffix + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + -- sub can be number of string + if sub == "" then + sub = false + end + local hash = name + if sub then + hash = hash .. "-" .. sub + end + if instance then + hash = hash .. "-" .. instance + end + hash = containers.cleanname(hash) + local data = containers.read(otf.cache,hash) + local reload = not data or data.size ~= size or data.time ~= time or data.tableversion ~= otfreaders.tableversion + if forceload then + report_otf("forced reload of %a due to hard coded flag",filename) + reload = true + end + if reload then + report_otf("loading %a, hash %a",filename,hash) + -- + starttiming(otfreaders,true) + data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search) + if data then + -- todo: make this a plugin + local used = checkmemory() + local resources = data.resources + local svgshapes = resources.svgshapes + local pngshapes = resources.pngshapes + if cleanup == 0 then + checkmemory(used,threshold,tracememory) + end + if svgshapes then + resources.svgshapes = nil + if otf.svgenabled then + local timestamp = os.date() + -- work in progress ... a bit boring to do + containers.write(otf.svgcache,hash, { + svgshapes = svgshapes, + timestamp = timestamp, + }) + data.properties.svg = { + hash = hash, + timestamp = timestamp, + } + end + if cleanup > 1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + if pngshapes then + resources.pngshapes = nil + if otf.pngenabled then + local timestamp = os.date() + -- work in progress ... a bit boring to do + containers.write(otf.pngcache,hash, { + pngshapes = pngshapes, + timestamp = timestamp, + }) + data.properties.png = { + hash = hash, + timestamp = timestamp, + } + end + if cleanup > 1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + -- + otfreaders.compact(data) + if cleanup == 0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.rehash(data,"unicodes") + otfreaders.addunicodetable(data) + otfreaders.extend(data) + if cleanup == 0 then + checkmemory(used,threshold,tracememory) + end + if context then + otfreaders.condense(data) + end + otfreaders.pack(data) + report_otf("loading done") + report_otf("saving %a in cache",filename) + data = containers.write(otf.cache, hash, data) + if cleanup > 1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + stoptiming(otfreaders) + if elapsedtime then + report_otf("loading, optimizing, packing and caching time %s", elapsedtime(otfreaders)) + end + if cleanup > 3 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + data = containers.read(otf.cache,hash) -- this frees the old table and load the sparse one + if cleanup > 2 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + else + stoptiming(otfreaders) + data = nil + report_otf("loading failed due to read error") + end + end + if data then + if trace_defining then + report_otf("loading from cache using hash %a",hash) + end + -- + otfreaders.unpack(data) + otfreaders.expand(data) -- inline tables + otfreaders.addunicodetable(data) -- only when not done yet + -- + otfenhancers.apply(data,filename,data) -- in context one can also use treatments + -- + -- constructors.addcoreunicodes(data.resources.unicodes) -- still needed ? + -- + if applyruntimefixes then + applyruntimefixes(filename,data) -- e.g. see treatments.lfg + end + -- + data.metadata.math = data.resources.mathconstants + -- + -- delayed tables (experiment) + -- + local classes = data.resources.classes + if not classes then + local descriptions = data.descriptions + classes = setmetatableindex(function(t,k) + local d = descriptions[k] + local v = (d and d.class or "base") or false + t[k] = v + return v + end) + data.resources.classes = classes + end + -- + end + + return data +end + +-- modes: node, base, none + +function otf.setfeatures(tfmdata,features) + local okay = constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) + if okay then + return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) + else + return { } -- will become false + end +end + +-- the first version made a top/mid/not extensible table, now we just +-- pass on the variants data and deal with it in the tfm scaler (there +-- is no longer an extensible table anyway) +-- +-- we cannot share descriptions as virtual fonts might extend them (ok, +-- we could use a cache with a hash +-- +-- we already assign an empty table to characters as we can add for +-- instance protruding info and loop over characters; one is not supposed +-- to change descriptions and if one does so one should make a copy! + +local function copytotfm(data,cache_id) + if data then + local metadata = data.metadata + local properties = derivetable(data.properties) + local descriptions = derivetable(data.descriptions) + local goodies = derivetable(data.goodies) + local characters = { } -- newtable if we knwo how many + local parameters = { } + local mathparameters = { } + -- + local resources = data.resources + local unicodes = resources.unicodes + local spaceunits = 500 + local spacer = "space" + local designsize = metadata.designsize or 100 + local minsize = metadata.minsize or designsize + local maxsize = metadata.maxsize or designsize + local mathspecs = metadata.math + -- + if designsize == 0 then + designsize = 100 + minsize = 100 + maxsize = 100 + end + if mathspecs then + for name, value in next, mathspecs do + mathparameters[name] = value + end + end + for unicode in next, data.descriptions do -- use parent table + characters[unicode] = { } + end + if mathspecs then + for unicode, character in next, characters do + local d = descriptions[unicode] -- we could use parent table here + local m = d.math + if m then + -- watch out: luatex uses hvariants for the parts + -- + local italic = m.italic + local vitalic = m.vitalic + -- + local variants = m.hvariants + local parts = m.hparts + if variants then + local c = character + for i=1,#variants do + -- local un = variants[i].glyph + local un = variants[i] + c.next = un + c = characters[un] + end -- c is now last in chain + c.hvariants = parts + elseif parts then + character.hvariants = parts + italic = m.hitalic + end + -- + local variants = m.vvariants + local parts = m.vparts + if variants then + local c = character + for i=1,#variants do + -- local un = variants[i].glyph + local un = variants[i] + c.next = un + c = characters[un] + end -- c is now last in chain + c.vvariants = parts + elseif parts then + character.vvariants = parts + end + -- + if italic and italic ~= 0 then + character.italic = italic + end + -- + if vitalic and vitalic ~= 0 then + character.vitalic = vitalic + end + -- + local accent = m.accent -- taccent? + if accent then + character.accent = accent + end + -- + local kerns = m.kerns + if kerns then + character.mathkerns = kerns + end + end + end + end + -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't + -- we use the basename then?) + local filename = constructors.checkedfilename(resources) + local fontname = metadata.fontname + local fullname = metadata.fullname or fontname + local psname = fontname or fullname + local subfont = metadata.subfontindex + local units = metadata.units or 1000 + -- + if units == 0 then -- catch bugs in fonts + units = 1000 -- maybe 2000 when ttf + metadata.units = 1000 + report_otf("changing %a units to %a",0,units) + end + -- + local monospaced = metadata.monospaced + local charwidth = metadata.averagewidth -- or unset + local charxheight = metadata.xheight -- or unset + local italicangle = metadata.italicangle + local hasitalics = metadata.hasitalics + properties.monospaced = monospaced + properties.hasitalics = hasitalics + parameters.italicangle = italicangle + parameters.charwidth = charwidth + parameters.charxheight = charxheight + -- + local space = 0x0020 + local emdash = 0x2014 + if monospaced then + if descriptions[space] then + spaceunits, spacer = descriptions[space].width, "space" + end + if not spaceunits and descriptions[emdash] then + spaceunits, spacer = descriptions[emdash].width, "emdash" + end + if not spaceunits and charwidth then + spaceunits, spacer = charwidth, "charwidth" + end + else + if descriptions[space] then + spaceunits, spacer = descriptions[space].width, "space" + end + if not spaceunits and descriptions[emdash] then + spaceunits, spacer = descriptions[emdash].width/2, "emdash/2" + end + if not spaceunits and charwidth then + spaceunits, spacer = charwidth, "charwidth" + end + end + spaceunits = tonumber(spaceunits) or units/2 + -- + parameters.slant = 0 + parameters.space = spaceunits -- 3.333 (cmr10) + parameters.spacestretch = 1*units/2 -- 500 -- 1.666 (cmr10) + parameters.spaceshrink = 1*units/3 -- 333 -- 1.111 (cmr10) + parameters.xheight = 2*units/5 -- 400 + parameters.quad = units -- 1000 + if spaceunits < 2*units/5 then + -- todo: warning + end + if italicangle and italicangle ~= 0 then + parameters.italicangle = italicangle + parameters.italicfactor = math.cos(math.rad(90+italicangle)) + parameters.slant = - math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.spacestretch = 0 + parameters.spaceshrink = 0 + elseif syncspace then -- + parameters.spacestretch = spaceunits/2 + parameters.spaceshrink = spaceunits/3 + end + parameters.extraspace = parameters.spaceshrink -- 1.111 (cmr10) + if charxheight then + parameters.xheight = charxheight + else + local x = 0x0078 + if x then + local x = descriptions[x] + if x then + parameters.xheight = x.height + end + end + end + -- + parameters.designsize = (designsize/10)*65536 + parameters.minsize = (minsize /10)*65536 + parameters.maxsize = (maxsize /10)*65536 + parameters.ascender = abs(metadata.ascender or 0) + parameters.descender = abs(metadata.descender or 0) + parameters.units = units + parameters.vheight = metadata.defaultvheight + -- + properties.space = spacer + properties.format = data.format or formats.otf + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = psname + properties.name = filename or fullname + properties.subfont = subfont + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then + -- + properties.encodingbytes = 2 +elseif CONTEXTLMTXMODE then + local duplicates = resources and resources.duplicates + if duplicates then + local maxindex = data.nofglyphs or metadata.nofglyphs + if maxindex then + for u, d in sortedhash(duplicates) do + local du = descriptions[u] + if du then + for uu in sortedhash(d) do + maxindex = maxindex + 1 + descriptions[uu].dupindex = du.index + descriptions[uu].index = maxindex + end + else + -- report_otf("no %U in font %a, duplicates ignored",u,filename) + end + end + end + end + -- +end + -- + -- properties.name = specification.name + -- properties.sub = specification.sub + -- + properties.private = properties.private or data.private or privateoffset + -- + return { + characters = characters, + descriptions = descriptions, + parameters = parameters, + mathparameters = mathparameters, + resources = resources, + properties = properties, + goodies = goodies, + } + end +end + +-- These woff files are a kind of joke in a tex environment because one can simply convert +-- them to ttf/otf and use them as such (after all, we cache them too). The successor format +-- woff2 is more complex so there we can as well call an external converter which in the end +-- makes this code kind of obsolete before it's even used. Although ... it might become a +-- more general conversion plug in. + +local converters = { + woff = { + cachename = "webfonts", + action = otf.readers.woff2otf, + } +} + +-- We can get differences between daylight saving etc ... but it makes no sense to +-- mess with trickery .. so be it when you use a different binary. + +local function checkconversion(specification) + local filename = specification.filename + local converter = converters[lower(file.suffix(filename))] + if converter then + local base = file.basename(filename) + local name = file.removesuffix(base) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + if size > 0 then + local cleanname = containers.cleanname(name) + local cachename = caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time ~= lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) -- todo infoonly + lfs.touch(cachename,time,time) + end + specification.filename = cachename + end + end +end + +local function otftotfm(specification) + local cache_id = specification.hash + local tfmdata = containers.read(constructors.cache,cache_id) + if not tfmdata then + + checkconversion(specification) -- for the moment here + + local name = specification.name + local sub = specification.sub + local subindex = specification.subindex + local filename = specification.filename + local features = specification.features.normal + local instance = specification.instance or (features and features.axis) + local rawdata = otf.load(filename,sub,instance) + if rawdata and next(rawdata) then + local descriptions = rawdata.descriptions + rawdata.lookuphash = { } -- to be done + tfmdata = copytotfm(rawdata,cache_id) + if tfmdata and next(tfmdata) then + -- at this moment no characters are assigned yet, only empty slots + local features = constructors.checkedfeatures("otf",features) + local shared = tfmdata.shared + if not shared then + shared = { } + tfmdata.shared = shared + end + shared.rawdata = rawdata + -- shared.features = features -- default + shared.dynamics = { } + -- shared.processes = { } + tfmdata.changed = { } + shared.features = features + shared.processes = otf.setfeatures(tfmdata,features) + end + end + containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata +end + +local function read_from_otf(specification) + local tfmdata = otftotfm(specification) + if tfmdata then + -- this late ? .. needs checking + tfmdata.properties.name = specification.name + tfmdata.properties.sub = specification.sub + tfmdata.properties.id = specification.id + -- + tfmdata = constructors.scale(tfmdata,specification) + local allfeatures = tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) + constructors.setname(tfmdata,specification) -- only otf? + fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) + end + return tfmdata +end + +local function checkmathsize(tfmdata,mathsize) + local mathdata = tfmdata.shared.rawdata.metadata.math + local mathsize = tonumber(mathsize) + if mathdata then -- we cannot use mathparameters as luatex will complain + local parameters = tfmdata.parameters + parameters.scriptpercentage = mathdata.ScriptPercentScaleDown + parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown + parameters.mathsize = mathsize -- only when a number ! + end +end + +registerotffeature { + name = "mathsize", + description = "apply mathsize specified in the font", + initializers = { + base = checkmathsize, + node = checkmathsize, + } +} + +-- readers + +function otf.collectlookups(rawdata,kind,script,language) + if not kind then + return + end + if not script then + script = default + end + if not language then + language = default + end + local lookupcache = rawdata.lookupcache + if not lookupcache then + lookupcache = { } + rawdata.lookupcache = lookupcache + end + local kindlookup = lookupcache[kind] + if not kindlookup then + kindlookup = { } + lookupcache[kind] = kindlookup + end + local scriptlookup = kindlookup[script] + if not scriptlookup then + scriptlookup = { } + kindlookup[script] = scriptlookup + end + local languagelookup = scriptlookup[language] + if not languagelookup then + local sequences = rawdata.resources.sequences + local featuremap = { } + local featurelist = { } + if sequences then + for s=1,#sequences do + local sequence = sequences[s] + local features = sequence.features + if features then + features = features[kind] + if features then + -- features = features[script] or features[default] or features[wildcard] + features = features[script] or features[wildcard] + if features then + -- features = features[language] or features[default] or features[wildcard] + features = features[language] or features[wildcard] + if features then + if not featuremap[sequence] then + featuremap[sequence] = true + featurelist[#featurelist+1] = sequence + end + end + end + end + end + end + if #featurelist == 0 then + featuremap, featurelist = false, false + end + else + featuremap, featurelist = false, false + end + languagelookup = { featuremap, featurelist } + scriptlookup[language] = languagelookup + end + return unpack(languagelookup) +end + +-- moved from font-oth.lua, todo: also afm + +local function getgsub(tfmdata,k,kind,value) + local shared = tfmdata.shared + local rawdata = shared and shared.rawdata + if rawdata then + local sequences = rawdata.resources.sequences + if sequences then + local properties = tfmdata.properties + local validlookups, lookuplist = otf.collectlookups(rawdata,kind,properties.script,properties.language) + if validlookups then + -- local choice = tonumber(value) or 1 -- no random here (yet) + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + local nofsteps = lookup.nofsteps + for i=1,nofsteps do + local coverage = steps[i].coverage + if coverage then + local found = coverage[k] + if found then + return found, lookup.type + end + end + end + end + end + end + end +end + +otf.getgsub = getgsub -- returns value, gsub_kind + +function otf.getsubstitution(tfmdata,k,kind,value) + local found, kind = getgsub(tfmdata,k,kind,value) + if not found then + -- + elseif kind == "gsub_single" then + return found + elseif kind == "gsub_alternate" then + local choice = tonumber(value) or 1 -- no random here (yet) + return found[choice] or found[1] or k + end + return k +end + +otf.getalternate = otf.getsubstitution + +function otf.getmultiple(tfmdata,k,kind) + local found, kind = getgsub(tfmdata,k,kind) + if found and kind == "gsub_multiple" then + return found + end + return { k } +end + +function otf.getkern(tfmdata,left,right,kind) + local kerns = getgsub(tfmdata,left,kind or "kern",true) -- for now we use getsub + if kerns then + local found = kerns[right] + local kind = type(found) + if kind == "table" then + found = found[1][3] -- can be more clever + elseif kind ~= "number" then + found = false + end + if found then + return found * tfmdata.parameters.factor + end + end + return 0 +end + +local function check_otf(forced,specification,suffix) + local name = specification.name + if forced then + name = specification.forcedname -- messy + end + local fullname = findbinfile(name,suffix) or "" + if fullname == "" then + fullname = fonts.names.getfilename(name,suffix) or "" + end + if fullname ~= "" and not fonts.names.ignoredfile(fullname) then + specification.filename = fullname + return read_from_otf(specification) + end +end + +local function opentypereader(specification,suffix) + local forced = specification.forced or "" + if formats[forced] then + return check_otf(true,specification,forced) + else + return check_otf(false,specification,suffix) + end +end + +readers.opentype = opentypereader -- kind of useless and obsolete + +function readers.otf(specification) return opentypereader(specification,"otf") end +function readers.ttf(specification) return opentypereader(specification,"ttf") end +function readers.ttc(specification) return opentypereader(specification,"ttf") end + +function readers.woff(specification) + checkconversion(specification) + opentypereader(specification,"") +end + +-- this will be overloaded + +function otf.scriptandlanguage(tfmdata,attr) + local properties = tfmdata.properties + return properties.script or "dflt", properties.language or "dflt" +end + +-- a little bit of abstraction + +local function justset(coverage,unicode,replacement) + coverage[unicode] = replacement +end + +otf.coverup = { + stepkey = "steps", + actions = { + chainsubstitution = justset, + chainposition = justset, + substitution = justset, + alternate = justset, + multiple = justset, + kern = justset, + pair = justset, + single = justset, + ligature = function(coverage,unicode,ligature) + local first = ligature[1] + local tree = coverage[first] + if not tree then + tree = { } + coverage[first] = tree + end + for i=2,#ligature do + local l = ligature[i] + local t = tree[l] + if not t then + t = { } + tree[l] = t + end + tree = t + end + tree.ligature = unicode + end, + }, + register = function(coverage,featuretype,format) + return { + format = format, + coverage = coverage, + } + end +} diff --git a/tex/context/base/mkxl/font-tfm.lmt b/tex/context/base/mkxl/font-tfm.lmt new file mode 100644 index 000000000..dcb76ba80 --- /dev/null +++ b/tex/context/base/mkxl/font-tfm.lmt @@ -0,0 +1,666 @@ +if not modules then modules = { } end modules ['font-tfm'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end -- use luatex-fonts-tfm.lua instead + +local next, type = next, type +local match, format = string.match, string.format +local concat, sortedhash = table.concat, table.sortedhash +local idiv = number.idiv + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_features = false trackers.register("tfm.features", function(v) trace_features = v end) + +local report_defining = logs.reporter("fonts","defining") +local report_tfm = logs.reporter("fonts","tfm loading") + +local findbinfile = resolvers.findbinfile +local setmetatableindex = table.setmetatableindex + +local fonts = fonts +local handlers = fonts.handlers +local helpers = fonts.helpers +local readers = fonts.readers +local constructors = fonts.constructors +local encodings = fonts.encodings + +local tfm = constructors.handlers.tfm +tfm.version = 1.000 +tfm.maxnestingdepth = 5 +tfm.maxnestingsize = 65536*1024 + +local otf = fonts.handlers.otf +local otfenhancers = otf.enhancers + +local tfmfeatures = constructors.features.tfm +local registertfmfeature = tfmfeatures.register + +local tfmenhancers = constructors.enhancers.tfm +local registertfmenhancer = tfmenhancers.register + +local charcommand = helpers.commands.char + +constructors.resolvevirtualtoo = false -- wil be set in font-ctx.lua + +fonts.formats.tfm = "type1" -- we need to have at least a value here +fonts.formats.ofm = "type1" -- we need to have at least a value here + +--[[ldx-- +<p>The next function encapsulates the standard <l n='tfm'/> loader as +supplied by <l n='luatex'/>.</p> +--ldx]]-- + +-- this might change: not scaling and then apply features and do scaling in the +-- usual way with dummy descriptions but on the other hand .. we no longer use +-- tfm so why bother + +-- ofm directive blocks local path search unless set; btw, in context we +-- don't support ofm files anyway as this format is obsolete + +-- we need to deal with nested virtual fonts, but because we load in the +-- frontend we also need to make sure we don't nest too deep (esp when sizes +-- get large) +-- +-- (VTITLE Example of a recursion) +-- (MAPFONT D 0 (FONTNAME recurse)(FONTAT D 2)) +-- (CHARACTER C A (CHARWD D 1)(CHARHT D 1)(MAP (SETRULE D 1 D 1))) +-- (CHARACTER C B (CHARWD D 2)(CHARHT D 2)(MAP (SETCHAR C A))) +-- (CHARACTER C C (CHARWD D 4)(CHARHT D 4)(MAP (SETCHAR C B))) +-- +-- we added the same checks as below to the luatex engine + +function tfm.setfeatures(tfmdata,features) + local okay = constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) + if okay then + return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) + else + return { } -- will become false + end +end + +local depth = { } -- table.setmetatableindex("number") + +-- Normally we just load the tfm data and go on. However there was some demand for +-- loading good old tfm /pfb files where afm files were lacking and even enc files +-- of dubious quality so we now support loading such (often messy) setups too. +-- +-- Because such fonts also use (ugly) tweaks achieve some purpose (like swapping +-- accents) we need to delay the unicoding actions till after the features have been +-- applied. +-- +-- It must be noted that in ConTeXt we don't expect this to be used at all. Here is +-- example: +-- +-- tfm metrics + pfb vector for index + pfb file for shapes +-- +-- \font\foo=file:csr10.tfm:reencode=auto;mode=node;liga=yes;kern=yes +-- +-- tfm metrics + pfb vector for index + enc file for tfm mapping + pfb file for shapes +-- +-- \font\foo=file:csr10.tfm:reencode=csr.enc;mode=node;liga=yes;kern=yes +-- +-- tfm metrics + enc file for mapping to tfm + bitmaps shapes +-- +-- \font\foo=file:csr10.tfm:reencode=csr.enc;bitmap=yes;mode=node;liga=yes;kern=yes +-- +-- One can add features: +-- +-- fonts.handlers.otf.addfeature { +-- name = "czechdqcheat", +-- type = "substitution", +-- data = { +-- quotedblright = "csquotedblright", +-- }, +-- } +-- +-- So "czechdqcheat=yes" is then a valid feature. And yes, it's a cheat. + +local loadtfmvf = tfm.readers.loadtfmvf + +local function read_from_tfm(specification) + local filename = specification.filename + local size = specification.size + depth[filename] = (depth[filename] or 0) + 1 + if trace_defining then + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata = loadtfmvf(filename,size) + if tfmdata then + + local features = specification.features and specification.features.normal or { } + local features = constructors.checkedfeatures("tfm",features) + specification.features.normal = features + + -- If reencode returns a new table, we assume that we're doing something + -- special. An 'auto' reencode picks up its vector from the pfb file. + + local getmapentry = fonts.mappings.getentry + + if getmapentry and not features.reencode then + -- This can happen multiple times but not that often so we don't + -- optimize this. + local encoding, pfbfile, encfile = getmapentry(filename) + if encoding and pfbfile then + features.reencode = encfile + features.pfbfile = pfbfile + end + end + local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata = newtfmdata + end + + local resources = tfmdata.resources or { } + local properties = tfmdata.properties or { } + local parameters = tfmdata.parameters or { } + local shared = tfmdata.shared or { } + -- + shared.features = features + shared.resources = resources + -- + properties.id = specification.id + properties.name = tfmdata.name -- todo: fallback + properties.fontname = tfmdata.fontname -- todo: fallback + properties.psname = tfmdata.psname -- todo: fallback + properties.fullname = tfmdata.fullname -- todo: fallback + properties.filename = specification.filename -- todo: fallback + properties.format = tfmdata.format or fonts.formats.tfm -- better than nothing + properties.usedbitmap = tfmdata.usedbitmap + -- + if getmapentry and newtfmdata then + properties.filename = features.pfbfile + end + -- + tfmdata.properties = properties + tfmdata.resources = resources + tfmdata.parameters = parameters + tfmdata.shared = shared + -- + shared.rawdata = { resources = resources } + shared.features = features + -- + -- The next branch is only entered when we have a proper encoded file i.e. + -- unicodes and such. It really nakes no sense to do feature juggling when + -- we have no names and unicodes. + -- + if newtfmdata then + -- + -- Some opentype processing assumes these to be present: + -- + if not resources.marks then + resources.marks = { } + end + if not resources.sequences then + resources.sequences = { } + end + if not resources.features then + resources.features = { + gsub = { }, + gpos = { }, + } + end + if not tfmdata.changed then + tfmdata.changed = { } + end + if not tfmdata.descriptions then + tfmdata.descriptions = tfmdata.characters + end + -- + -- It might be handy to have this: + -- + otf.readers.addunicodetable(tfmdata) + -- + -- We make a pseudo opentype font, e.g. kerns and ligatures etc: + -- + tfmenhancers.apply(tfmdata,filename) + -- + -- Now user stuff can kick in. + -- + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + -- + -- As that can also mess with names and such, we are now ready for finalizing + -- the unicode information. This is a different order that for instance type one + -- (afm) files. First we try to deduce unicodes from already present information. + -- + otf.readers.unifymissing(tfmdata) + -- + -- Next we fill in the gaps, based on names from teh agl. Probably not much will + -- happen here. + -- + fonts.mappings.addtounicode(tfmdata,filename) + -- + -- The tounicode data is passed to the backend that constructs the vectors for us. + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then + tfmdata.tounicode = 1 +end + local tounicode = fonts.mappings.tounicode + for unicode, v in next, tfmdata.characters do + local u = v.unicode + if u then + v.tounicode = tounicode(u) + end + end + -- + -- However, when we use a bitmap font those vectors can't be constructed because + -- that information is not carried with those fonts (there is no name info, nor + -- proper index info, nor unicodes at that end). So, we provide it ourselves. + -- + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + -- + shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil + -- + if size < 0 then + size = idiv(65536 * -size,100) + end + + parameters.factor = 1 -- already scaled + parameters.units = 1000 -- just in case + parameters.size = size + parameters.slant = parameters.slant or parameters[1] or 0 + parameters.space = parameters.space or parameters[2] or 0 + parameters.spacestretch = parameters.spacestretch or parameters[3] or 0 + parameters.spaceshrink = parameters.spaceshrink or parameters[4] or 0 + parameters.xheight = parameters.xheight or parameters[5] or 0 + parameters.quad = parameters.quad or parameters[6] or 0 + parameters.extraspace = parameters.extraspace or parameters[7] or 0 + -- + constructors.enhanceparameters(parameters) -- official copies for us + -- + properties.private = properties.private or tfmdata.private or privateoffset + -- + if newtfmdata then + -- + -- We do nothing as we assume flat tfm files. It would become real messy + -- otherwise and I don't have something for testing on my system anyway. + -- + else + -- already loaded + local fonts = tfmdata.fonts + if fonts then + for i=1,#fonts do + local font = fonts[i] + local id = font.id + if not id then + local name = font.name + local size = font.size + if name and size then + local data, id = constructors.readanddefine(name,size) + if id then + font.id = id + font.name = nil + font.size = nil + end + end + end + end + end + end + -- + properties.haskerns = true + properties.hasligatures = true + properties.hasitalics = true + resources.unicodes = { } + resources.lookuptags = { } + -- + depth[filename] = depth[filename] - 1 + -- + return tfmdata + else + depth[filename] = depth[filename] - 1 + end +end + +local function check_tfm(specification,fullname) -- we could split up like afm/otf + local foundname = findbinfile(fullname, 'tfm') or "" + if foundname == "" then + foundname = findbinfile(fullname, 'ofm') or "" -- not needed in context + end + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"tfm") or "" + end + if foundname ~= "" then + specification.filename = foundname + specification.format = "ofm" + return read_from_tfm(specification) + elseif trace_defining then + report_defining("loading tfm with name %a fails",specification.name) + end +end + +readers.check_tfm = check_tfm + +function readers.tfm(specification) + local fullname = specification.filename or "" + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + fullname = specification.name .. "." .. forced + else + fullname = specification.name + end + end + return check_tfm(specification,fullname) +end + +readers.ofm = readers.tfm + +-- The reencoding acts upon the 'reencode' feature which can have values 'auto' or +-- an enc file. You can also specify a 'pfbfile' feature (but it defaults to the +-- tfm filename) and a 'bitmap' feature. When no enc file is givven (auto) we will +-- get the vectors from the pfb file. + +do + + local outfiles = { } + + local tfmcache = table.setmetatableindex(function(t,tfmdata) + local id = font.define(tfmdata) + t[tfmdata] = id + return id + end) + + local encdone = table.setmetatableindex("table") + + function tfm.reencode(tfmdata,specification) + + local features = specification.features + + if not features then + return + end + + local features = features.normal + + if not features then + return + end + + local tfmfile = file.basename(tfmdata.name) + local encfile = features.reencode -- or features.enc + local pfbfile = features.pfbfile -- or features.pfb + local bitmap = features.bitmap -- or features.pk + + if not encfile then + return + end + + local pfbfile = pfbfile or outfiles[tfmfile] + + if pfbfile == nil then + if bitmap then + pfbfile = false + elseif type(pfbfile) ~= "string" then + pfbfile = tfmfile + end + if type(pfbfile) == "string" then + pfbfile = file.addsuffix(pfbfile,"pfb") + -- pdf.mapline(tfmfile .. "<" .. pfbfile) + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile = false -- use bitmap + end + outfiles[tfmfile] = pfbfile + end + + local encoding = false + local vector = false + if type(pfbfile) == "string" then + local pfb = constructors.handlers.pfb + if pfb and pfb.loadvector then + local v, e = pfb.loadvector(pfbfile) + if v then + vector = v + end + if e then + encoding = e + end + end + end + if type(encfile) == "string" and encfile ~= "auto" then + encoding = fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding = encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + + local unicoding = fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid = tfmcache[tfmdata] + local tfmdata = table.copy(tfmdata) -- good enough for small fonts + local characters = { } + local originals = tfmdata.characters + local indices = { } + local parentfont = { "font", 1 } -- can be zero (self referencing) + local private = tfmdata.privateoffset or constructors.privateoffset + local reported = encdone[tfmfile][encfile] -- bah, encdone for tfm or pfb ? + -- create characters table + + -- vector : pfbindex -> name + -- encoding : tfmindex -> name + + -- we store the order also because some tex encodings (see math-vfu) needs + -- that for remapping with non standard glyphs names cq. lack of unicode + -- slot information + + for k, v in next, originals do + v.order = k + end + + local backmap = vector and table.swapped(vector) + local done = { } -- prevent duplicate + for tfmindex, name in sortedhash(encoding) do -- predictable order + local original = originals[tfmindex] + if original then + local unicode = unicoding[name] + if unicode then + original.unicode = unicode + else + unicode = private + private = private + 1 + if trace_defining and not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end + end + characters[unicode] = original + indices[tfmindex] = unicode + original.name = name -- so one can lookup weird names + if backmap then + original.index = backmap[name] -- the pfb index + else -- probably bitmap + original.commands = { parentfont, charcommand[tfmindex] } -- or "slot" + original.oindex = tfmindex + end + done[name] = true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",tfmindex,tfmfile,name) + end + end + + encdone[tfmfile][encfile] = true + + -- redo kerns and ligatures + + for k, v in next, characters do + local kerns = v.kerns + if kerns then + local t = { } + for k, v in next, kerns do + local i = indices[k] + if i then + t[i] = v + end + end + v.kerns = next(t) and t or nil + end + local ligatures = v.ligatures + if ligatures then + local t = { } + for k, v in next, ligatures do + local i = indices[k] + if i then + t[i] = v + v.char = indices[v.char] + end + end + v.ligatures = next(t) and t or nil + end + end + + -- wrap up + + tfmdata.fonts = { { id = virtualid } } + tfmdata.characters = characters + tfmdata.fullname = tfmdata.fullname or tfmdata.name + tfmdata.psname = file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename = pfbfile + -- tfmdata.format = bitmap and "type3" or "type1" + tfmdata.format = "type1" +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then + tfmdata.encodingbytes = 2 + tfmdata.tounicode = 1 + tfmdata.embedding = "subset" +end + tfmdata.usedbitmap = bitmap and virtualid + tfmdata.private = private + + return tfmdata + end + +end + +-- Now we implement the regular features handlers. We need to convert the +-- tfm specific structures to opentype structures. In basemode they are +-- converted back so that is a bit of a waste but it's fast enough. + +do + + local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } + local noflags = { false, false, false, false } + + local function enhance_normalize_features(data) + local ligatures = setmetatableindex("table") + local kerns = setmetatableindex("table") + local characters = data.characters + for u, c in next, characters do + local l = c.ligatures + local k = c.kerns + if l then + ligatures[u] = l + for u, v in next, l do + l[u] = { ligature = v.char } + end + c.ligatures = nil + end + if k then + kerns[u] = k + for u, v in next, k do + k[u] = v -- { v, 0 } + end + c.kerns = nil + end + end + + for u, l in next, ligatures do + for k, v in next, l do + local vl = v.ligature + local dl = ligatures[vl] + if dl then + for kk, vv in next, dl do + v[kk] = vv -- table.copy(vv) + end + end + end + end + + local features = { + gpos = { }, + gsub = { }, + } + local sequences = { + -- only filled ones + } + if next(ligatures) then + features.gsub.liga = everywhere + data.properties.hasligatures = true + sequences[#sequences+1] = { + features = { + liga = everywhere, + }, + flags = noflags, + name = "s_s_0", + nofsteps = 1, + order = { "liga" }, + type = "gsub_ligature", + steps = { + { + coverage = ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern = everywhere + data.properties.haskerns = true + sequences[#sequences+1] = { + features = { + kern = everywhere, + }, + flags = noflags, + name = "p_s_0", + nofsteps = 1, + order = { "kern" }, + type = "gpos_pair", + steps = { + { + format = "kern", + coverage = kerns, + }, + }, + } + end + data.resources.features = features + data.resources.sequences = sequences + data.shared.resources = data.shared.resources or resources + end + + registertfmenhancer("normalize features", enhance_normalize_features) + registertfmenhancer("check extra features", otfenhancers.enhance) + +end + +-- As with type one (afm) loading, we just use the opentype ones: + +registertfmfeature { + name = "mode", + description = "mode", + initializers = { + base = otf.modeinitializer, + node = otf.modeinitializer, + } +} + +registertfmfeature { + name = "features", + description = "features", + default = true, + initializers = { + base = otf.basemodeinitializer, + node = otf.nodemodeinitializer, + }, + processors = { + node = otf.featuresprocessor, + } +} diff --git a/tex/context/base/mkxl/font-tpk.lmt b/tex/context/base/mkxl/font-tpk.lmt new file mode 100644 index 000000000..d216bc257 --- /dev/null +++ b/tex/context/base/mkxl/font-tpk.lmt @@ -0,0 +1,1304 @@ +if not modules then modules = { } end modules ['font-tpk'] = { + version = 1.001, + optimize = true, + 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" +} + +-- The bitmap loader is more or less derived from the luatex version (taco) +-- which is derived from pdftex (thanh) who uses code from dvips (thomas) +-- adapted by piet ... etc. The tfm and vf readers are also derived from +-- luatex. All do things a bit more luaish and errors are of course mine. + +local next = next +local extract, band, lshift, rshift = bit32.extract, bit32.band, bit32.lshift, bit32.rshift +local idiv = number.idiv +local char = string.char +local concat, insert, remove, copy = table.concat, table.insert, table.remove, table.copy +local tobitstring = number.tobitstring +local formatters = string.formatters +local round = math.round + +local streams = utilities.streams +local openstream = streams.open +local streamsize = streams.size +local readcardinal1 = streams.readcardinal1 +local readcardinal2 = streams.readcardinal2 +local readcardinal3 = streams.readcardinal3 +local readcardinal4 = streams.readcardinal4 +local readinteger1 = streams.readinteger1 +local readinteger2 = streams.readinteger2 +local readinteger3 = streams.readinteger3 +local readinteger4 = streams.readinteger4 +local readbyte = streams.readbyte +local readbytes = streams.readbytes +local readstring = streams.readstring +local skipbytes = streams.skipbytes +local getposition = streams.getposition +local setposition = streams.setposition + +if not fonts then fonts = { handlers = { tfm = { } } } end + +local handlers = fonts.handlers +local tfm = handlers.tfm or { } +handlers.tfm = tfm +local readers = tfm.readers or { } +tfm.readers = readers + +tfm.version = 1.005 +tfm.cache = containers.define("fonts", "tfm", tfm.version, true) + +-- Performance is no real issue here so I didn't optimize too much. After +-- all, these files are small and we mostly use opentype or type1 fonts. + +do + + local function readbitmap(glyph,s,flagbyte) + + local inputbyte = 0 + local bitweight = 0 + local dynf = 0 + local remainder = 0 + local realfunc = nil + local repeatcount = 0 + + local function getnyb() -- can be inlined + if bitweight == 0 then + bitweight = 16 + inputbyte = readbyte(s) + return extract(inputbyte,4,4) + else + bitweight = 0 + return band(inputbyte,15) + end + end + + local function getbit() -- can be inlined + bitweight = rshift(bitweight,1) + if bitweight == 0 then -- actually we can check for 1 + inputbyte = readbyte(s) + bitweight = 128 + end + return band(inputbyte,bitweight) + end + + local function pkpackednum() + local i = getnyb(s) + if i == 0 then + repeat + j = getnyb() + i = i + 1 + until (j ~= 0) + if i > 3 then + return handlehuge(i,j) + else + for i=1,i do + j = j * 16 + getnyb() + end + return j - 15 + (13 - dynf) * 16 + dynf + end + elseif i <= dynf then + return i + elseif i < 14 then + return (i - dynf - 1) * 16 + getnyb() + dynf + 1 + elseif i == 14 then + repeatcount = pkpackednum() + else + repeatcount = 1 + end + return realfunc() + end + + local function rest() + if remainder < 0 then + remainder = -remainder + return 0 + elseif remainder > 4000 then + remainder = 4000 - remainder + return 4000 + elseif remainder > 0 then + local i = remainder + remainder = 0 + realfunc = pkpackednum + return i + else + -- error = "pk issue that shouldn't happen" + return 0 + end + end + + local function handlehuge(i,j) + while i ~= 0 do + j = lshift(j,4) + getnyb() + -- j = extract(j,8,4) + getnyb() + i = i - 1 + end + remainder = j - 15 + (13 - dynf) * 16 + dynf + realfunc = rest + return rest() + end + + local gpower = { [0] = + 0, 1, 3, 7, 15, 31, 63, 127, + 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, + 65535 + } + + local raster = { } + local r = 0 + glyph.stream = raster + + local xsize = glyph.xsize + local ysize = glyph.ysize + local word = 0 + local wordweight = 0 + local wordwidth = idiv(xsize + 15,16) + local rowsleft = 0 + local turnon = band(flagbyte,8) == 8 and true or false + local hbit = 0 + local count = 0 + -- + realfunc = pkpackednum + dynf = idiv(flagbyte,16) + -- + if dynf == 14 then + bitweight = 0 + for i=1,ysize do + word = 0 + wordweight = 32768 + for j=1,xsize do + if getbit() ~= 0 then + word = word + wordweight + end + wordweight = rshift(wordweight,1) + if wordweight == 0 then + r = r + 1 + raster[r] = word + word = 0 + wordweight = 32768 + end + end + if wordweight ~= 32768 then + r = r + 1 + raster[r] = word + end + end + else + rowsleft = ysize + hbit = xsize + repeatcount = 0 + wordweight = 16 + word = 0 + bitweight = 0 + while rowsleft > 0 do + count = realfunc() + while count ~= 0 do + if count < wordweight and count < hbit then + if turnon then + word = word + gpower[wordweight] - gpower[wordweight - count] + end + hbit = hbit - count + wordweight = wordweight - count + count = 0 + elseif count >= hbit and hbit <= wordweight then + if turnon then + word = word + gpower[wordweight] - gpower[wordweight - hbit] + end + r = r + 1 + raster[r] = word + for i=1,repeatcount*wordwidth do + r = r + 1 + raster[r] = raster[r - wordwidth] + end + rowsleft = rowsleft - repeatcount - 1 + repeatcount = 0 + word = 0 + wordweight = 16 + count = count - hbit + hbit = xsize + else + if turnon then + word = word + gpower[wordweight] + end + r = r + 1 + raster[r] = word + word = 0 + count = count - wordweight + hbit = hbit - wordweight + wordweight = 16 + end + end + turnon = not turnon + end + if rowsleft ~= 0 or hbit ~= xsize then + print("ERROR",rowsleft,hbit,xsize) + -- error = "error while unpacking, more bits than required" + end + end + + end + + function readers.showpk(glyph) + local xsize = glyph.xsize + local ysize = glyph.ysize + local stream = glyph.stream + local result = { } + local rr = { } + local r = 0 + local s = 0 + local cw = idiv(xsize+ 7, 8) + local rw = idiv(xsize+15,16) + local extra = 2 * rw == cw + local b + for y=1,ysize do + r = 0 + for x=1,rw-1 do + s = s + 1 ; b = stream[s] + r = r + 1 ; rr[r] = tobitstring(b,16,16) + end + s = s + 1 ; b = stream[s] + if extra then + r = r + 1 ; rr[r] = tobitstring(b,16,16) + else + r = r + 1 ; rr[r] = tobitstring(extract(b,8+(8-cw),cw),cw,cw) + end + result[y] = concat(rr) + end + return concat(result,"\n") + end + + local template = formatters [ [[ +%.3N 0 %i %i %i %i d1 +q +%i 0 0 %i %i %i cm +BI + /W %i + /H %i + /IM true + /BPC 1 + /D [1 0] +ID %t +EI +Q]] ] + + function readers.pktopdf(glyph,data,factor) + local width = data.width * factor + local xsize = glyph.xsize or 0 + local ysize = glyph.ysize or 0 + local xoffset = glyph.xoffset or 0 + local yoffset = glyph.yoffset or 0 + local stream = glyph.stream + + local dpi = 1 + local newdpi = 1 + + local xdpi = dpi * xsize / newdpi + local ydpi = dpi * ysize / newdpi + + local llx = - xoffset + local lly = yoffset - ysize + 1 + local urx = llx + xsize + 1 + local ury = lly + ysize + + local result = { } + local r = 0 + local s = 0 + local cw = idiv(xsize+ 7, 8) + local rw = idiv(xsize+15,16) + local extra = 2 * rw == cw + local b + for y=1,ysize do + for x=1,rw-1 do + s = s + 1 ; b = stream[s] + r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8)) + end + s = s + 1 ; b = stream[s] + if extra then + r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8)) + else + r = r + 1 ; result[r] = char(extract(b,8,8)) + end + end + return template(width,llx,lly,urx,ury,xdpi,ydpi,llx,lly,xsize,ysize,result), width + end + + function readers.loadpk(filename) + local s = openstream(filename) + local preamble = readcardinal1(s) + local version = readcardinal1(s) + local comment = readstring(s,readcardinal1(s)) + local designsize = readcardinal4(s) + local checksum = readcardinal4(s) + local hppp = readcardinal4(s) + local vppp = readcardinal4(s) + if preamble ~= 247 or version ~= 89 or not vppp then + return { error = "invalid preamble" } + end + local glyphs = { } + local data = { + designsize = designsize, + comment = comment, + hppp = hppp, + vppp = vppp, + glyphs = glyphs, + } + while true do + local flagbyte = readcardinal1(s) + if flagbyte < 240 then + local c = band(flagbyte,7) + local length, index, width, pixels, xsize, ysize, xoffset, yoffset + if c >= 0 and c <= 3 then + length = band(flagbyte,7) * 256 + readcardinal1(s) - 3 + index = readcardinal1(s) + width = readinteger3(s) + pixels = readcardinal1(s) + xsize = readcardinal1(s) + ysize = readcardinal1(s) + xoffset = readcardinal1(s) + yoffset = readcardinal1(s) + if xoffset > 127 then + xoffset = xoffset - 256 + end + if yoffset > 127 then + yoffset = yoffset - 256 + end + elseif c >= 4 and c <= 6 then + length = band(flagbyte,3) * 65536 + readcardinal1(s) * 256 + readcardinal1(s) - 4 + index = readcardinal1(s) + width = readinteger3(s) + pixels = readcardinal2(s) + xsize = readcardinal2(s) + ysize = readcardinal2(s) + xoffset = readcardinal2(s) + yoffset = readcardinal2(s) + else -- 7 + length = readcardinal4(s) - 9 + index = readcardinal4(s) + width = readinteger4(s) + pixels = readcardinal4(s) + readcardinal4(s) + xsize = readcardinal4(s) + ysize = readcardinal4(s) + xoffset = readcardinal4(s) + yoffset = readcardinal4(s) + end + local glyph = { + index = index, + width = width, + pixels = pixels, + xsize = xsize, + ysize = ysize, + xoffset = xoffset, + yoffset = yoffset, + } + if length <= 0 then + data.error = "bad packet" + return data + end + readbitmap(glyph,s,flagbyte) + glyphs[index] = glyph + elseif flagbyte == 240 then + -- k[1] x[k] + skipbytes(s,readcardinal1(s)) + elseif flagbyte == 241 then + -- k[2] x[k] + skipbytes(s,readcardinal2(s)*2) + elseif flagbyte == 242 then + -- k[3] x[k] + skipbytes(s,readcardinal3(s)*3) + elseif flagbyte == 243 then + -- k[4] x[k] + skipbytes(s,readcardinal4(s)*4) -- readinteger4 + elseif flagbyte == 244 then + -- y[4] + skipbytes(s,4) + elseif flagbyte == 245 then + break + elseif flagbyte == 246 then + -- nop + else + data.error = "unknown pk command" + break + end + end + return data + end + +end + +do + + local leftboundary = -1 + local rightboundary = -2 + local boundarychar = 65536 + + function readers.loadtfm(filename) + local data + -- + local function someerror(m) + if not data then + data = { } + end + data.error = m or "fatal error" + return data + end + -- + local s = openstream(filename) + if not s then + return someerror() + end + -- + local wide = false + local header = 0 + local max = 0 + local size = streamsize(s) + local glyphs = table.setmetatableindex(function(t,k) + local v = { + -- we default because boundary chars have no dimension s + width = 0, + height = 0, + depth = 0, + italic = 0, + } + t[k] = v + return v + end) + local parameters = { } + local direction = 0 + -- + local lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np + -- + lf = readcardinal2(s) + if lf ~= 0 then + header = 6 + max = 255 + wide = false + lh = readcardinal2(s) + bc = readcardinal2(s) + ec = readcardinal2(s) + nw = readcardinal2(s) + nh = readcardinal2(s) + nd = readcardinal2(s) + ni = readcardinal2(s) + nl = readcardinal2(s) + nk = readcardinal2(s) + ne = readcardinal2(s) + np = readcardinal2(s) + else + header = 14 + max = 65535 + wide = readcardinal4(s) == 0 + if not wide then + return someerror("invalid format") + end + lf = readcardinal4(s) + lh = readcardinal4(s) + bc = readcardinal4(s) + ec = readcardinal4(s) + nw = readcardinal4(s) + nh = readcardinal4(s) + nd = readcardinal4(s) + ni = readcardinal4(s) + nl = readcardinal4(s) + nk = readcardinal4(s) + ne = readcardinal4(s) + np = readcardinal4(s) + direction = readcardinal4(s) + end + if (bc > ec + 1) or (ec > max) then + return someerror("file is too small") + end + if bc > max then + bc, ec = 1, 0 + end + local nlw = (wide and 2 or 1) * nl + local neew = (wide and 2 or 1) * ne + local ncw = (wide and 2 or 1) * (ec - bc + 1) + if lf ~= (header + lh + ncw + nw + nh + nd + ni + nlw + nk + neew + np) then + return someerror("file is too small") + end + if nw == 0 or nh == 0 or nd == 0 or ni == 0 then + return someerror("no glyphs") + end + if lf * 4 > size then + return someerror("file is too small") + end + local slh = lh + if lh < 2 then + return someerror("file is too small") + end + local checksum = readcardinal4(s) + local designsize = readcardinal2(s) + designsize = designsize * 256 + readcardinal1(s) + designsize = designsize * 16 + rshift(readcardinal1(s),4) + if designsize < 0xFFFF then + return someerror("weird designsize") + end + -- + local alpha = 16 + local z = designsize + while z >= 040000000 do + z = rshift(z,1) + alpha = alpha + alpha + end + local beta = idiv(256,alpha) + alpha = alpha * z + -- + local function readscaled() + local a, b, c, d = readbytes(s,4) + local n = idiv(rshift(rshift(d*z,8)+c*z,8)+b*z,beta) + if a == 0 then + return n + elseif a == 255 then + return n - alpha + else + return 0 + end + end + -- + local function readunscaled() + local a, b, c, d = readbytes(s,4) + if a > 127 then + a = a - 256 + end + return a * 0xFFFFF + b * 0xFFF + c * 0xF + rshift(d,4) + end + -- + while lh > 2 do -- can be one-liner + skipbytes(s,4) + lh = lh - 1 + end + local saved = getposition(s) + setposition(s,(header + slh + ncw) * 4 + 1) + local widths = { } for i=0,nw-1 do widths [i] = readscaled() end + local heights = { } for i=0,nh-1 do heights[i] = readscaled() end + local depths = { } for i=0,nd-1 do depths [i] = readscaled() end + local italics = { } for i=0,ni-1 do italics[i] = readscaled() end + if widths[0] ~= 0 or heights[0] ~= 0 or depths[0] ~= 0 then + return someerror("invalid dimensions") + end + -- + local blabel = nl + local bchar = boundarychar + -- + local ligatures = { } + if nl > 0 then + for i=0,nl-1 do + local a, b, c, d = readbytes(s,4) + ligatures[i] = { + skip = a, + nxt = b, + op = c, + rem = d, + } + if a > 128 then + if 256 * c + d >= nl then + return someerror("invalid ligature table") + end + if a == 255 and i == 0 then + bchar = b + end + else + if c < 128 then + -- whatever + elseif 256 * (c - 128) + d >= nk then + return someerror("invalid ligature table") + end + if (a < 128) and (i - 0 + a + 1 >= nl) then + return someerror("invalid ligature table") + end + end + if a == 255 then + blabel = 256 * c + d + end + end + end + local allkerns = { } + for i=0,nk-1 do + allkerns[i] = readscaled() + end + local extensibles = { } + for i=0,ne-1 do + extensibles[i] = wide and { + top = readcardinal2(s), + bot = readcardinal2(s), + mid = readcardinal2(s), + rep = readcardinal2(s), + } or { + top = readcardinal1(s), + bot = readcardinal1(s), + mid = readcardinal1(s), + rep = readcardinal1(s), + } + end + for i=1,np do + if i == 1 then + parameters[i] = readunscaled() + else + parameters[i] = readscaled() + end + end + for i=1,7 do + if not parameters[i] then + parameters[i] = 0 + end + end + -- + setposition(s,saved) + local extras = false + if blabel ~= nl then + local k = blabel + while true do + local l = ligatures[k] + local skip = l.skip + if skip <= 128 then + -- if l.op >= 128 then + -- extras = true -- kern + -- else + extras = true -- ligature + -- end + end + if skip == 0 then + k = k + 1 + else + if skip >= 128 then + break + end + k = k + skip + 1 + end + end + end + if extras then + local ligas = { } + local kerns = { } + local k = blabel + while true do + local l = ligatures[k] + local skip = l.skip + if skip <= 128 then + local nxt = l.nxt + local op = l.op + local rem = l.rem + if op >= 128 then + kerns[nxt] = allkerns[256 * (op - 128) + rem] + else + ligas[nxt] = { type = op * 2 + 1, char = rem } + end + end + if skip == 0 then + k = k + 1 + else + if skip >= 128 then + break; + end + k = k + skip + 1 + end + end + if next(kerns) then + local glyph = glyphs[leftboundary] + glyph.kerns = kerns + glyph.remainder = 0 + end + if next(ligas) then + local glyph = glyphs[leftboundary] + glyph.ligatures = ligas + glyph.remainder = 0 + end + end + for i=bc,ec do + local glyph, width, height, depth, italic, tag, remainder + if wide then + width = readcardinal2(s) + height = readcardinal1(s) + depth = readcardinal1(s) + italic = readcardinal1(s) + tag = readcardinal1(s) + remainder = readcardinal2(s) + else + width = readcardinal1(s) + height = readcardinal1(s) + depth = extract(height,0,4) + height = extract(height,4,4) + italic = readcardinal1(s) + tag = extract(italic,0,2) + italic = extract(italic,2,6) + remainder = readcardinal1(s) + end + if width == 0 then + -- nothing + else + if width >= nw or height >= nh or depth >= nd or italic >= ni then + return someerror("invalid dimension index") + end + local extensible, nextinsize + if tag == 0 then + -- nothing special + else + local r = remainder + if tag == 1 then + if r >= nl then + return someerror("invalid ligature index") + end + elseif tag == 2 then + if r < bc or r > ec then + return someerror("invalid chain index") + end + while r < i do + local g = glyphs[r] + if g.tag ~= list_tag then + break + end + r = g.remainder + end + if r == i then + return someerror("cycles in chain") + end + nextinsize = r + elseif tag == 3 then + if r >= ne then + return someerror("bad extensible") + end + extensible = extensibles[r] -- remainder ? + remainder = 0 + end + end + glyphs[i] = { + width = widths [width], + height = heights[height], + depth = depths [depth], + italic = italics[italic], + tag = tag, + -- index = i, + remainder = remainder, + extensible = extensible, + next = nextinsize, + } + end + end + for i=bc,ec do + local glyph = glyphs[i] + if glyph.tag == 1 then + -- ligature + local k = glyph.remainder + local l = ligatures[k] + if l.skip > 128 then + k = 256 * l.op + l.rem + end + local ligas = { } + local kerns = { } + while true do + local l = ligatures[k] + local skip = l.skip + if skip <= 128 then + local nxt = l.nxt + local op = l.op + local rem = l.rem + if op >= 128 then + local kern = allkerns[256 * (op - 128) + rem] + if nxt == bchar then + kerns[rightboundary] = kern + end + kerns[nxt] = kern + else + local ligature = { type = op * 2 + 1, char = rem } + if nxt == bchar then + ligas[rightboundary] = ligature + end + ligas[nxt] = ligature -- shared + end + end + if skip == 0 then + k = k + 1 + else + if skip >= 128 then + break + end + k = k + skip + 1 + end + end + if next(kerns)then + glyph.kerns = kerns + glyph.remainder = 0 + end + if next(ligas) then + glyph.ligatures = ligas + glyph.remainder = 0 + end + end + end + -- + if bchar ~= boundarychar then + glyphs[rightboundary] = copy(glyphs[bchar]) + end + -- + -- for k, v in next, glyphs do + -- v.tag = nil + -- v.remainder = nil + -- end + -- + return { + name = file.nameonly(filename), + fontarea = file.pathpart(filename), + glyphs = glyphs, + parameters = parameters, + designsize = designsize, + size = designsize, + direction = direction, + -- checksum = checksum, + -- embedding = "unknown", + -- extend = 1000, + -- slant = 0, + -- squeeze = 0, + -- format = "unknown", + -- identity = "unknown", + -- mode = 0, + -- streamprovider = 0, + -- tounicode = 0, + -- type = "unknown", + -- units_per_em = 0, + -- used = false, + -- width = 0, + -- writingmode = "unknown", + } + end + +end + +do + + local push = { "push" } + local push = { "pop" } + + local w, x, y, z, f + local stack + local s, result, r + local alpha, beta, z + + local function scaled1() + local a = readbytes(s,1) + if a == 0 then + return 0 + elseif a == 255 then + return - alpha + else + return 0 -- error + end + end + + local function scaled2() + local a, b = readbytes(s,2) + local sw = idiv(b*z,beta) + if a == 0 then + return sw + elseif a == 255 then + return sw - alpha + else + return 0 -- error + end + end + + local function scaled3() + local a, b, c = readbytes(s,3) + local sw = idiv(rshift(c*z,8)+b*z,beta) + if a == 0 then + return sw + elseif a == 255 then + return sw - alpha + else + return 0 -- error + end + end + + local function scaled4() + local a, b, c, d = readbytes(s,4) + local sw = idiv( rshift(rshift(d*z,8)+(c*z),8)+b*z,beta) + if a == 0 then + return sw + elseif a == 255 then + return sw - alpha + else + return 0 -- error + end + end + + local function dummy() + end + + local actions = { + + [128] = function() r = r + 1 result[r] = { "slot", f or 1, readcardinal1(s) } p = p + 1 end, + [129] = function() r = r + 1 result[r] = { "slot", f or 1, readcardinal2(s) } p = p + 2 end, + [130] = function() r = r + 1 result[r] = { "slot", f or 1, readcardinal3(s) } p = p + 3 end, + [131] = function() r = r + 1 result[r] = { "slot", f or 1, readcardinal4(s) } p = p + 4 end, + + [132] = function() + r = r + 1 + result[r] = { "rule", scaled4(), scaled4() } + p = p + 8 + end, + + [133] = function() + r = r + 1 result[r] = push + r = r + 1 result[r] = { "slot", f or 1, readcardinal1(s) } + r = r + 1 result[r] = pop + p = p + 1 + end, + [134] = function() + r = r + 1 result[r] = push + r = r + 1 result[r] = { "slot", f or 1, readcardinal2(s) } + r = r + 1 result[r] = pop + p = p + 2 + end, + [135] = function() + r = r + 1 result[r] = push + r = r + 1 result[r] = { "slot", f or 1, readcardinal2(s) } + r = r + 1 result[r] = pop + p = p + 3 + end, + [136] = function() + r = r + 1 result[r] = push + r = r + 1 result[r] = { "slot", f or 1, readcardinal4(s) } + r = r + 1 result[r] = pop + p = p + 4 + end, + + [137] = function() + r = r + 1 result[r] = push + r = r + 1 result[r] = { "rule", scaled4(), scaled4() } + r = r + 1 result[r] = pop + p = p + 8 + end, + + [138] = dummy, -- nop + [139] = dummy, -- bop + [140] = dummy, -- eop + + [141] = function() + insert(stack, { w, x, y, z }) + r = r + 1 + result[r] = push + end, + [142] = function() + local t = remove(stack) + if t then + w, x, y, z = t[1], t[2], t[3], t[4] + r = r + 1 + result[r] = pop + end + end, + + [143] = function() r = r + 1 result[r] = { "right", scaled1() } p = p + 1 end, + [144] = function() r = r + 1 result[r] = { "right", scaled2() } p = p + 2 end, + [145] = function() r = r + 1 result[r] = { "right", scaled3() } p = p + 3 end, + [146] = function() r = r + 1 result[r] = { "right", scaled4() } p = p + 4 end, + + [148] = function() w = scaled1() r = r + 1 result[r] = { "right", w } p = p + 1 end, + [149] = function() w = scaled2() r = r + 1 result[r] = { "right", w } p = p + 2 end, + [150] = function() w = scaled3() r = r + 1 result[r] = { "right", w } p = p + 3 end, + [151] = function() w = scaled4() r = r + 1 result[r] = { "right", w } p = p + 4 end, + + [153] = function() x = scaled1() r = r + 1 result[r] = { "right", x } p = p + 1 end, + [154] = function() x = scaled2() r = r + 1 result[r] = { "right", x } p = p + 2 end, + [155] = function() x = scaled3() r = r + 1 result[r] = { "right", x } p = p + 3 end, + [156] = function() x = scaled4() r = r + 1 result[r] = { "right", x } p = p + 4 end, + + [157] = function() r = r + 1 result[r] = { "down", scaled1() } p = p + 1 end, + [158] = function() r = r + 1 result[r] = { "down", scaled2() } p = p + 2 end, + [159] = function() r = r + 1 result[r] = { "down", scaled3() } p = p + 3 end, + [160] = function() r = r + 1 result[r] = { "down", scaled4() } p = p + 4 end, + + [162] = function() y = scaled1() r = r + 1 result[r] = { "down", y } p = p + 1 end, + [163] = function() y = scaled2() r = r + 1 result[r] = { "down", y } p = p + 2 end, + [164] = function() y = scaled3() r = r + 1 result[r] = { "down", y } p = p + 3 end, + [165] = function() y = scaled3() r = r + 1 result[r] = { "down", y } p = p + 4 end, + + [167] = function() z = scaled1() r = r + 1 ; result[r] = { "down", z } p = p + 4 end, + [168] = function() z = scaled2() r = r + 1 ; result[r] = { "down", z } p = p + 4 end, + [169] = function() z = scaled3() r = r + 1 ; result[r] = { "down", z } p = p + 4 end, + [170] = function() z = scaled4() r = r + 1 ; result[r] = { "down", z } p = p + 4 end, + + [147] = function() r = r + 1 result[r] = { "right", w } end, + [152] = function() r = r + 1 result[r] = { "right", x } end, + [161] = function() r = r + 1 result[r] = { "down", y } end, + [166] = function() r = r + 1 result[r] = { "down", z } end, + + [235] = function() f = readcardinal1(s) p = p + 1 end, + [236] = function() f = readcardinal2(s) p = p + 3 end, + [237] = function() f = readcardinal3(s) p = p + 3 end, + [238] = function() f = readcardinal4(s) p = p + 4 end, + + [239] = function() local n = readcardinal1(s) r = r + 1 result[r] = { "special", readstring(s,n) } p = p + 1 + n end, + [240] = function() local n = readcardinal2(s) r = r + 1 result[r] = { "special", readstring(s,n) } p = p + 2 + n end, + [241] = function() local n = readcardinal3(s) r = r + 1 result[r] = { "special", readstring(s,n) } p = p + 3 + n end, + [242] = function() local n = readcardinal4(s) r = r + 1 result[r] = { "special", readstring(s,n) } p = p + 4 + n end, + + [250] = function() local n = readcardinal1(s) r = r + 1 result[r] = { "pdf", readstring(s,n) } p = p + 1 + n end, + [251] = function() local n = readcardinal2(s) r = r + 1 result[r] = { "pdf", readstring(s,n) } p = p + 2 + n end, + [252] = function() local n = readcardinal3(s) r = r + 1 result[r] = { "pdf", readstring(s,n) } p = p + 3 + n end, + [253] = function() local n = readcardinal4(s) r = r + 1 result[r] = { "pdf", readstring(s,n) } p = p + 4 + n end, + + } + + table.setmetatableindex(actions,function(t,cmd) + local v + if cmd >= 0 and cmd <= 127 then + v = function() + if f == 0 then + f = 1 + end + r = r + 1 ; result[r] = { "slot", f, cmd } + end + elseif cmd >= 171 and cmd <= 234 then + cmd = cmd - 170 + v = function() + r = r + 1 ; result[r] = { "font", cmd } + end + else + v = dummy + end + t[cmd] = v + return v + end) + + function readers.loadvf(filename,data) + -- + local function someerror(m) + if not data then + data = { } + end + data.error = m or "fatal error" + return data + end + -- + s = openstream(filename) + if not s then + return someerror() + end + -- + local cmd = readcardinal1(s) + if cmd ~= 247 then + return someerror("bad preamble") + end + cmd = readcardinal1(s) + if cmd ~= 202 then + return someerror("bad version") + end + local header = readstring(s,readcardinal1(s)) + local checksum = readcardinal4(s) + local designsize = idiv(readcardinal4(s),16) + local fonts = data and data.fonts or { } + local glyphs = data and data.glyphs or { } + -- + alpha = 16 + z = designsize + while z >= 040000000 do + z = rshift(z,1) + alpha = alpha + alpha + end + beta = idiv(256,alpha) + alpha = alpha * z + -- + cmd = readcardinal1(s) + while true do + local n + if cmd == 243 then + n = readcardinal1(s) + 1 + elseif cmd == 244 then + n = readcardinal2(s) + 1 + elseif cmd == 245 then + n = readcardinal3(s) + 1 + elseif cmd == 246 then + n = readcardinal4(s) + 1 + else + break + end + local checksum = skipbytes(s,4) + local size = scaled4() + local designsize = idiv(readcardinal4(s),16) + local pathlen = readcardinal1(s) + local namelen = readcardinal1(s) + local path = readstring(s,pathlen) + local name = readstring(s,namelen) + fonts[n] = { path = path, name = name, size = size } + cmd = readcardinal1(s) + end + local index = 0 + while cmd and cmd <= 242 do + local width = 0 + local length = 0 + local checksum = 0 + if cmd == 242 then + length = readcardinal4(s) + checksum = readcardinal4(s) + width = readcardinal4(s) + else + length = cmd + checksum = readcardinal1(s) + width = readcardinal3(s) + end + w, x, y, z, f = 0, 0, 0, 0, false + stack, result, r, p = { }, { }, 0, 0 + while p < length do + local cmd = readcardinal1(s) + p = p + 1 + actions[cmd]() + end + local glyph = glyphs[index] + if glyph then + glyph.width = width + glyph.commands = result + else + glyphs[index] = { + width = width, + commands = result, + } + end + index = index + 1 + if #stack > 0 then + -- error: more pushes than pops + end + if packet_length ~= 0 then + -- error: invalid packet length + end + cmd = readcardinal1(s) + end + if readcardinal1(s) ~= 248 then + -- error: no post + end + s, result, r = nil, nil, nil + if data then + data.glyphs = data.glyphs or glyphs + data.fonts = data.fonts or fonts + return data + else + return { + name = file.nameonly(filename), + fontarea = file.pathpart(filename), + glyphs = glyphs, + designsize = designsize, + header = header, + fonts = fonts, + } + end + end + + -- the replacement loader (not sparse): + + function readers.loadtfmvf(tfmname,size) + local vfname = file.addsuffix(file.nameonly(tfmfile),"vf") + local tfmfile = tfmname + local vffile = resolvers.findbinfile(vfname,"ovf") + if tfmfile and tfmfile ~= "" then + if size < 0 then + size = idiv(65536 * -size,100) + end + local data = readers.loadtfm(tfmfile) + if data.error then + return data + end + if vffile and vffile ~= "" then + data = readers.loadvf(vffile,data) + if data.error then + return data + end + end + local designsize = data.designsize + local glyphs = data.glyphs + local parameters = data.parameters + local fonts = data.fonts + if size ~= designsize then + local factor = size / designsize + for index, glyph in next, glyphs do + if next(glyph) then + glyph.width = round(factor*glyph.width) + glyph.height = round(factor*glyph.height) + glyph.depth = round(factor*glyph.depth) + local italic = glyph.italic + if italic == 0 then + glyph.italic = nil + else + glyph.italic = round(factor*glyph.italic) + end + -- + local kerns = glyph.kerns + if kerns then + for index, kern in next, kerns do + kerns[index] = round(factor*kern) + end + end + -- + local commands = glyph.commands + if commands then + for i=1,#commands do + local c = commands[i] + local t = c[1] + if t == "down" or t == "right" then + c[2] = round(factor*c[2]) + elseif t == "rule" then + c[2] = round(factor*c[2]) + c[3] = round(factor*c[3]) + end + end + end + else + glyphs[index] = nil + end + end + for i=2,30 do + local p = parameters[i] + if p then + parameters[i] = round(factor*p) + else + break + end + end + if fonts then + for k, v in next, fonts do + v.size = round(factor*v.size) + end + end + else + for index, glyph in next, glyphs do + if next(glyph) then + if glyph.italic == 0 then + glyph.italic = nil + end + else + glyphs[index] = nil + end + end + end + -- + parameters.slant = parameters[1] + parameters.space = parameters[2] + parameters.spacestretch = parameters[3] + parameters.spaceshrink = parameters[4] + parameters.xheight = parameters[5] + parameters.quad = parameters[6] + parameters.extraspace = parameters[7] + -- + for i=1,7 do + parameters[i] = nil -- so no danger for async + end + -- + data.characters = glyphs + data.glyphs = nil + data.size = size + -- we assume type1 for now ... maybe the format should be unknown + data.filename = tfmfile -- file.replacesuffix(tfmfile,"pfb") + data.format = "unknown" + -- + return data + end + end + +end + +-- inspect(readers.loadtfmvf(resolvers.findfile("mi-iwonari.tfm"))) +-- inspect(readers.loadtfm(resolvers.findfile("texnansi-palatinonova-regular.tfm"))) +-- inspect(readers.loadtfm(resolvers.findfile("cmex10.tfm"))) +-- inspect(readers.loadtfm(resolvers.findfile("cmr10.tfm"))) +-- local t = readers.loadtfmvf("texnansi-lte50019.tfm") +-- inspect(t) diff --git a/tex/context/base/mkxl/lang-dis.lmt b/tex/context/base/mkxl/lang-dis.lmt index 5c4ab1e34..36fea59c0 100644 --- a/tex/context/base/mkxl/lang-dis.lmt +++ b/tex/context/base/mkxl/lang-dis.lmt @@ -205,7 +205,7 @@ local flatten = languages.flatten nodes.handlers.flattenline = flatten function nodes.handlers.flatten(head,where) - if head and (where == "box" or where == "adjusted_hbox") then + if head and (where == "box" or where == "adjustedhbox") then return flatten(head) end return head diff --git a/tex/context/base/mkxl/lang-hyp.lmt b/tex/context/base/mkxl/lang-hyp.lmt index 590528495..90823851e 100644 --- a/tex/context/base/mkxl/lang-hyp.lmt +++ b/tex/context/base/mkxl/lang-hyp.lmt @@ -1645,7 +1645,7 @@ featureset.hyphenonly = hyphenonly == v_yes function hyphenators.handler(head,groupcode) if usedmethod then - if optimize and (groupcode == "hbox" or groupcode == "adjusted_hbox") then + if optimize and (groupcode == "hbox" or groupcode == "adjustedhbox") then if getcount("hyphenstate") > 0 then forced = false return usedmethod(head) diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt index 6183d073a..0ac497d57 100644 --- a/tex/context/base/mkxl/math-act.lmt +++ b/tex/context/base/mkxl/math-act.lmt @@ -110,7 +110,7 @@ end function mathematics.checkaccentbaseheight(target,original) local mathparameters = target.mathparameters if mathparameters and mathparameters.AccentBaseHeight == 0 then - mathparameters.AccentBaseHeight = target.parameters.x_height -- needs checking + mathparameters.AccentBaseHeight = target.parameters.xheight -- needs checking end end @@ -565,11 +565,11 @@ end -- local function fix(target,original,targetcharacters,unicode,factor) -- local chardata = targetcharacters[unicode] -- if chardata and factor then --- local accent = chardata.top_accent +-- local accent = chardata.topaccent -- if not accent then -- local width = chardata.width or 0 -- local accent = (tonumber(factor) and factor * width) or (factor and minint) --- chardata.top_accent = accent +-- chardata.topaccent = accent -- if trace_tweaking then -- report_tweak("fixing accent %U",target,original,unicode) -- end @@ -715,15 +715,15 @@ local function extensiblecode(font,unicode) if not char then return unknown end - if character.horiz_variants then - if character.vert_variants then + if character.hvariants then + if character.vvariants 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 + elseif character.vvariants then local m = char.mathextensible local e = m and extensibles[m] return e and { e, code, character } or unknown @@ -765,19 +765,19 @@ local function horizontalcode(family,unicode) local loffset = 0 local roffset = 0 if kind == e_left then - local charlist = data[3].horiz_variants + local charlist = data[3].hvariants 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 + local charlist = data[3].hvariants 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 + local charlist = data[3].hvariants if charlist then local left = charlist[1] local right = charlist[#charlist] diff --git a/tex/context/base/mkxl/math-dim.lmt b/tex/context/base/mkxl/math-dim.lmt new file mode 100644 index 000000000..1bf2420bf --- /dev/null +++ b/tex/context/base/mkxl/math-dim.lmt @@ -0,0 +1,249 @@ +if not modules then modules = { } end modules ['math-dim'] = { + 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" +} + +-- The radical_rule value is also used as a trigger. In luatex the accent +-- placement happens either the opentype way (using topaccent cum suis) or the +-- traditional way. In order to determine what method to use the \Umathradicalrule +-- setting is consulted to determine what method to use. This is more efficient +-- than analyzing the (potentially spread over multiple families) situation. For +-- this reason we need to set the radical_rule here. It used to be "<unset>" in +-- which case the engine takes the rulethickness. In c-speak: +-- +-- int compat_mode = (radical_rule(cur_style) == undefined_math_parameter) ; +-- +-- In the meantime things have been updated and we now have two code paths. + +local abs, next = math.abs, next + +local defaults = { + axis = { default = { "AxisHeight", "axisheight" }, }, + accent_base_height = { default = { "AccentBaseHeight", "xheight" }, }, + fraction_del_size = { default = { "FractionDelimiterSize", "delim2" }, + cramped_display_style = { "FractionDelimiterDisplayStyleSize", "delim1" }, + display_style = { "FractionDelimiterDisplayStyleSize", "delim1" }, }, + fraction_denom_down = { default = { "FractionDenominatorShiftDown", "denom2" }, + cramped_display_style = { "FractionDenominatorDisplayStyleShiftDown", "denom1" }, + display_style = { "FractionDenominatorDisplayStyleShiftDown", "denom1" }, }, + fraction_denom_vgap = { default = { "FractionDenominatorGapMin", "defaultrulethickness" }, + cramped_display_style = { "FractionDenominatorDisplayStyleGapMin", "3*defaultrulethickness" }, + display_style = { "FractionDenominatorDisplayStyleGapMin", "3*defaultrulethickness" }, }, + fraction_num_up = { default = { "FractionNumeratorShiftUp", "num2" }, + cramped_display_style = { "FractionNumeratorDisplayStyleShiftUp", "num1" }, + display_style = { "FractionNumeratorDisplayStyleShiftUp", "num1" }, }, + fraction_num_vgap = { default = { "FractionNumeratorGapMin", "defaultrulethickness" }, + cramped_display_style = { "FractionNumeratorDisplayStyleGapMin", "3*defaultrulethickness" }, + display_style = { "FractionNumeratorDisplayStyleGapMin", "3*defaultrulethickness" }, }, + skewed_fraction_hgap = { default = { "SkewedFractionHorizontalGap", "mathquad/2" }, + cramped_display_style = { "SkewedFractionHorizontalGap", "mathquad/2" }, + display_style = { "SkewedFractionHorizontalGap", "mathquad/2" }, }, + skewed_fraction_vgap = { default = { "SkewedFractionVerticalGap", "xheight" }, + cramped_display_style = { "SkewedFractionVerticalGap", "xheight" }, + display_style = { "SkewedFractionVerticalGap", "xheight" }, }, + fraction_rule = { default = { "FractionRuleThickness", "defaultrulethickness" }, }, + limit_above_bgap = { default = { "UpperLimitBaselineRiseMin", "bigopspacing3" }, }, + limit_above_vgap = { default = { "UpperLimitGapMin", "bigopspacing1" }, }, + limit_above_kern = { default = { "0", "bigopspacing5" }, }, + limit_below_bgap = { default = { "LowerLimitBaselineDropMin", "bigopspacing4" }, }, + limit_below_vgap = { default = { "LowerLimitGapMin", "bigopspacing2" }, }, + limit_below_kern = { default = { "0", "bigopspacing5" }, }, + math_operator_size = { default = { "DisplayOperatorMinHeight", "mathxheight*3" }, }, -- 2 + overbar_kern = { default = { "OverbarExtraAscender", "defaultrulethickness" }, }, + overbar_rule = { default = { "OverbarRuleThickness", "defaultrulethickness" }, }, + overbar_vgap = { default = { "OverbarVerticalGap", "3*defaultrulethickness" }, }, + quad = { default = { "fontsize(f)", "mathquad" }, }, + radical_kern = { default = { "RadicalExtraAscender", "defaultrulethickness" }, }, + radical_rule = { default = { "RadicalRuleThickness", "defaultrulethickness" }, }, + -- default = { "surdheight(f)", "defaultrulethickness" }, + radical_vgap = { default = { "RadicalVerticalGap", "defaultrulethickness+(abs(defaultrulethickness)/4)" }, + display_style = { "RadicalDisplayStyleVerticalGap", "defaultrulethickness+(abs(mathxheight)/4)" }, }, + space_after_script = { default = { "SpaceAfterScript", "scriptspace" }, }, + space_before_script = { default = { "SpaceAfterScript", "scriptspace" }, }, + stack_denom_down = { default = { "StackBottomShiftDown", "denom2" }, + cramped_display_style = { "StackBottomDisplayStyleShiftDown", "denom1" }, + display_style = { "StackBottomDisplayStyleShiftDown", "denom1" }, }, + stack_num_up = { default = { "StackTopShiftUp", "num3" }, + cramped_display_style = { "StackTopDisplayStyleShiftUp", "num1" }, + display_style = { "StackTopDisplayStyleShiftUp", "num1" }, }, + stack_vgap = { default = { "StackGapMin", "3*defaultrulethickness" }, + cramped_display_style = { "StackDisplayStyleGapMin", "7*defaultrulethickness" }, + display_style = { "StackDisplayStyleGapMin", "7*defaultrulethickness" }, }, + sub_shift_down = { default = { "SubscriptShiftDown", "sub1" }, }, + sub_shift_drop = { default = { "SubscriptBaselineDropMin", "subdrop" }, }, + sub_sup_shift_down = { default = { "SubscriptShiftDown", "sub2" }, }, + sub_top_max = { default = { "SubscriptTopMax", "abs(mathxheight*4)/5" }, }, + subsup_vgap = { default = { "SubSuperscriptGapMin", "4*defaultrulethickness" }, }, + sup_bottom_min = { default = { "SuperscriptBottomMin", "abs(mathxheight)/4" }, }, + sup_shift_drop = { default = { "SuperscriptBaselineDropMax", "supdrop" }, }, + sup_shift_up = { cramped_display_style = { "SuperscriptShiftUpCramped", "sup3" }, + cramped_script_script_style = { "SuperscriptShiftUpCramped", "sup3" }, + cramped_script_style = { "SuperscriptShiftUpCramped", "sup3" }, + cramped_text_style = { "SuperscriptShiftUpCramped", "sup3" }, + display_style = { "SuperscriptShiftUp", "sup1" }, + script_script_style = { "SuperscriptShiftUp", "sup2" }, + script_style = { "SuperscriptShiftUp", "sup2" }, + text_style = { "SuperscriptShiftUp", "sup2" }, }, + sup_sub_bottom_max = { default = { "SuperscriptBottomMaxWithSubscript", "abs(mathxheight*4)/5" }, }, + underbar_kern = { default = { "UnderbarExtraDescender", "0" }, }, + underbar_rule = { default = { "UnderbarRuleThickness", "defaultrulethickness" }, }, + underbar_vgap = { default = { "UnderbarVerticalGap", "3*defaultrulethickness" }, }, + connector_overlap_min = { default = { "MinConnectorOverlap", "0.25*defaultrulethickness" }, }, + over_delimiter_vgap = { default = { "StretchStackGapBelowMin", "bigopspacing1" }, }, + over_delimiter_bgap = { default = { "StretchStackTopShiftUp", "bigopspacing3" }, }, + under_delimiter_vgap = { default = { "StretchStackGapAboveMin", "bigopspacing2" }, }, + under_delimiter_bgap = { default = { "StretchStackBottomShiftDown", "bigopspacing4" }, }, + radical_degree_before = { default = { "RadicalKernBeforeDegree", "(5/18)*quad" }, }, + radical_degree_after = { default = { "RadicalKernAfterDegree", "(-10/18)*quad" }, }, + radical_degree_raise = { default = { "RadicalDegreeBottomRaisePercent", "60" }, }, + no_limit_sub_factor = { default = { "NoLimitSubFactor", "0" }, }, + no_limit_sup_factor = { default = { "NoLimitSupFactor", "0" }, }, +} + +local styles = { + 'cramped_display_style', + 'cramped_script_script_style', + 'cramped_script_style', + 'cramped_text_style', + 'display_style', + 'script_script_style', + 'script_style', + 'text_style', +} + +for k, v in next, defaults do + for _, s in next, styles do + if not v[s] then + v[s] = v.default + end + end +end + +-- we cannot use a metatable because we do a copy (takes a bit more work) +-- +-- local mt = { } setmetatable(defaults,mt) +-- +-- mt.__index = function(t,s) +-- return t.default or t.text_style or 0 +-- end + +function mathematics.dimensions(dimens) -- beware, dimens get spoiled + if dimens.SpaceAfterScript then + dimens.SubscriptShiftDownWithSuperscript = dimens.SubscriptShiftDown * 1.5 -- move this one + return table.fastcopy(dimens), { } + elseif dimens.AxisHeight or dimens.axisheight then + local t = { } + local mathxheight = dimens.xheight or 10*65536 + local mathquad = dimens.quad or 10*65536 + local defaultrulethickness = dimens.FractionDenominatorGapMin or dimens.defaultrulethickness or 0.4*65536 + dimens["0"] = 0 + dimens["60"] = 60 + dimens["0.25*defaultrulethickness"] = defaultrulethickness / 4 + dimens["3*defaultrulethickness"] = 3 * defaultrulethickness + dimens["4*defaultrulethickness"] = 4 * defaultrulethickness + dimens["7*defaultrulethickness"] = 7 * defaultrulethickness + dimens["(5/18)*quad"] = (mathquad * 5) / 18 + dimens["(-10/18)*quad"] = - (mathquad * 10) / 18 + dimens["mathxheight*3"] = mathxheight * 3 -- needs checking + dimens["abs(mathxheight*4)/5"] = abs(mathxheight * 4) / 5 + dimens["defaultrulethickness+(abs(defaultrulethickness)/4)"] = defaultrulethickness+(abs(defaultrulethickness) / 4) + dimens["defaultrulethickness+(abs(mathxheight)/4)"] = defaultrulethickness+(abs(mathxheight) / 4) + dimens["abs(mathxheight)/4"] = abs(mathxheight) / 4 + dimens["abs(mathxheight*4)/5"] = abs(mathxheight * 4) / 5 + dimens["<not set>"] = false + dimens["script_space"] = false -- at macro level + for variable, styles in next, defaults do + local tt = { } + for style, default in next, styles do + local one = default[1] + local two = default[2] + local value = dimens[one] + if value then + tt[style] = value + else + value = dimens[two] + if value == false then + tt[style] = nil + else + tt[style] = value or 0 + end + end + end + t[variable] = tt + end + local d = { + AccentBaseHeight = t . accent_base_height . text_style, + AxisHeight = t . axis . text_style, + -- DelimitedSubFormulaMinHeight + DisplayOperatorMinHeight = t . math_operator_size . text_style, -- no longer let tex decide (weird values) + -- FlattenedAccentBaseHeight + FractionDenominatorDisplayStyleGapMin = t . fraction_denom_vgap . display_style, + FractionDenominatorDisplayStyleShiftDown = t . fraction_denom_down . display_style, + FractionDenominatorGapMin = t . fraction_denom_vgap . text_style, + FractionDenominatorShiftDown = t . fraction_denom_down . text_style, + FractionNumeratorDisplayStyleGapMin = t . fraction_num_vgap . display_style, + FractionNumeratorDisplayStyleShiftUp = t . fraction_num_up . display_style, + FractionNumeratorGapMin = t . fraction_num_vgap . text_style, + FractionNumeratorShiftUp = t . fraction_num_up . text_style, + FractionRuleThickness = t . fraction_rule . text_style, + FractionDelimiterSize = t . fraction_del_size . text_style, + FractionDelimiterDisplayStyleSize = t . fraction_del_size . display_style, + LowerLimitBaselineDropMin = t . limit_below_bgap . text_style, + LowerLimitGapMin = t . limit_below_vgap . text_style, + -- MathLeading + MinConnectorOverlap = t . connector_overlap_min . text_style, + OverbarExtraAscender = t . overbar_kern . text_style, + OverbarRuleThickness = t . overbar_rule . text_style, + OverbarVerticalGap = t . overbar_vgap . text_style, + RadicalDisplayStyleVerticalGap = t . radical_vgap . display_style, + RadicalExtraAscender = t . radical_kern . text_style, + RadicalRuleThickness = t . radical_rule . text_style, + RadicalVerticalGap = t . radical_vgap . text_style, + RadicalKernBeforeDegree = t . radical_degree_before . display_style, + RadicalKernAfterDegree = t . radical_degree_after . display_style, + RadicalDegreeBottomRaisePercent = t . radical_degree_raise . display_style, + -- ScriptPercentScaleDown + -- ScriptScriptPercentScaleDown + -- SkewedFractionHorizontalGap + -- SkewedFractionVerticalGap + SpaceAfterScript = t . space_after_script . text_style, + StackBottomDisplayStyleShiftDown = t . stack_denom_down . display_style, + StackBottomShiftDown = t . stack_denom_down . text_style, + StackDisplayStyleGapMin = t . stack_vgap . display_style, + StackGapMin = t . stack_vgap . text_style, + StackTopDisplayStyleShiftUp = t . stack_num_up . display_style, + StackTopShiftUp = t . stack_num_up . text_style, + StretchStackGapBelowMin = t . over_delimiter_vgap . text_style, + StretchStackTopShiftUp = t . over_delimiter_bgap . text_style, + StretchStackGapAboveMin = t . under_delimiter_vgap . text_style, + StretchStackBottomShiftDown = t . under_delimiter_bgap . text_style, + SubSuperscriptGapMin = t . subsup_vgap . text_style, + SubscriptBaselineDropMin = t . sub_shift_drop . text_style, + SubscriptShiftDown = t . sub_shift_down . text_style, + SubscriptShiftDownWithSuperscript = t . sub_sup_shift_down . text_style, + SubscriptTopMax = t . sub_top_max . text_style, + SuperscriptBaselineDropMax = t . sup_shift_drop . text_style, + SuperscriptBottomMaxWithSubscript = t . sup_sub_bottom_max . text_style, + SuperscriptBottomMin = t . sup_bottom_min . text_style, + SuperscriptShiftUp = t . sup_shift_up . text_style, + SuperscriptShiftUpCramped = t . sup_shift_up . cramped_text_style, + UnderbarExtraDescender = t . underbar_kern . text_style, + UnderbarRuleThickness = t . underbar_rule . text_style, + UnderbarVerticalGap = t . underbar_vgap . text_style, + UpperLimitBaselineRiseMin = t . limit_above_bgap . text_style, + UpperLimitGapMin = t . limit_above_vgap . text_style, + } + + -- too fragile for tx/px ... even the same values give different results + d.DisplayOperatorMinHeight = nil + -- + d.AccentBaseHeight = 0 -- here? still? + return d, t -- t only for diagnostics + else + return { }, { } + end +end + diff --git a/tex/context/base/mkxl/math-fbk.lmt b/tex/context/base/mkxl/math-fbk.lmt index 32ad909f7..80b99d83b 100644 --- a/tex/context/base/mkxl/math-fbk.lmt +++ b/tex/context/base/mkxl/math-fbk.lmt @@ -297,10 +297,10 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s break end end - local hv = olddata.horiz_variants + local hv = olddata.hvariants if hv then hv = fastcopy(hv) - newdata.horiz_variants = hv + newdata.hvariants = hv for i=1,#hv do local hvi = hv[i] local oldglyph = hvi.glyph @@ -314,7 +314,7 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s } hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata) else - report_fallbacks("error in fallback: no valid horiz_variants, slot %X, index %i",oldglyph,i) + report_fallbacks("error in fallback: no valid hvariants, slot %X, index %i",oldglyph,i) end end end @@ -393,7 +393,7 @@ local function smashed(data,unicode,private) local height = target.parameters.xheight / 2 local c, done = accent_to_extensible(target,private,data.original,unicode,height,0,nil,-height,unicode) if done then - c.top_accent = nil -- or maybe also all the others + c.topaccent = nil -- or maybe also all the others end return c end @@ -717,7 +717,7 @@ virtualcharacters[0x305] = function(data) height = height, depth = depth, commands = { { "rule", height, width } }, - horiz_variants = { + hvariants = { { advance = width, ["end"] = used, diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt index d199d5063..4ac76fa62 100644 --- a/tex/context/base/mkxl/math-ini.lmt +++ b/tex/context/base/mkxl/math-ini.lmt @@ -601,7 +601,7 @@ function mathematics.big(tfmdata,unicode,n,method) local t = tfmdata.characters local c = t[unicode] if c and n > 0 then - local vv = c.vert_variants or c.next and t[c.next].vert_variants + local vv = c.vvariants or c.next and t[c.next].vvariants if vv then local vvn = vv[n] return vvn and vvn.glyph or vv[#vv].glyph or unicode diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl index 3404e25f3..8ff839107 100644 --- a/tex/context/base/mkxl/math-ini.mkxl +++ b/tex/context/base/mkxl/math-ini.mkxl @@ -65,7 +65,7 @@ % test $[[\char948 \cldcontext{utf.char(948)}]]$ \registerctxluafile{math-ini}{autosuffix} -\registerctxluafile{math-dim}{} +\registerctxluafile{math-dim}{autosuffix} \registerctxluafile{math-act}{autosuffix} \registerctxluafile{math-ext}{} \registerctxluafile{math-vfu}{autosuffix} diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt index 025333699..66e8caade 100644 --- a/tex/context/base/mkxl/math-noa.lmt +++ b/tex/context/base/mkxl/math-noa.lmt @@ -197,19 +197,19 @@ local undernoad_code = noadcodes.under local overnoad_code = noadcodes.over local vcenternoad_code = noadcodes.vcenter -local noad_code = nodecodes.noad -- attr nucleus sub sup -local accent_code = nodecodes.accent -- attr nucleus sub sup accent -local radical_code = nodecodes.radical -- attr nucleus sub sup left degree -local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right -local subbox_code = nodecodes.subbox -- attr list -local submlist_code = nodecodes.submlist -- attr list -local mathchar_code = nodecodes.mathchar -- attr fam char -local mathtextchar_code = nodecodes.mathtextchar -- attr fam char -local delimiter_code = nodecodes.delimiter -- attr small_fam small_char large_fam large_char ------ style_code = nodecodes.style -- attr style ------ parameter_code = nodecodes.parameter -- attr style -local math_choice = nodecodes.choice -- attr display text script scriptscript -local fence_code = nodecodes.fence -- attr subtype +local noad_code = nodecodes.noad +local accent_code = nodecodes.accent +local radical_code = nodecodes.radical +local fraction_code = nodecodes.fraction +local subbox_code = nodecodes.subbox +local submlist_code = nodecodes.submlist +local mathchar_code = nodecodes.mathchar +local mathtextchar_code = nodecodes.mathtextchar +local delimiter_code = nodecodes.delimiter +----- style_code = nodecodes.style +----- parameter_code = nodecodes.parameter +local math_choice = nodecodes.choice +local fence_code = nodecodes.fence local leftfence_code = fencecodes.left local middlefence_code = fencecodes.middle @@ -316,8 +316,8 @@ local function process(start,what,n,parent) noad = getsuppre (start) if noad then process(noad,what,n,start) end -- list noad = getsubpre (start) if noad then process(noad,what,n,start) end -- list end - noad = getfield(start,"accent") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"bot_accent") if noad then process(noad,what,n,start) end -- list + noad = getfield(start,"topaccent") if noad then process(noad,what,n,start) end -- list + noad = getfield(start,"botaccent") if noad then process(noad,what,n,start) end -- list -- elseif id == style_code then -- -- has a next -- elseif id == parameter_code then @@ -375,8 +375,8 @@ local function processnested(current,what,n) noad = getsuppre (current) if noad then process(noad,what,n,current) end -- list noad = getsubpre (current) if noad then process(noad,what,n,current) end -- list end - noad = getfield(current,"accent") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"bot_accent") if noad then process(noad,what,n,current) end -- list + noad = getfield(current,"topaccent") if noad then process(noad,what,n,current) end -- list + noad = getfield(current,"botaccent") if noad then process(noad,what,n,current) end -- list end end @@ -423,8 +423,8 @@ local function processstep(current,process,n,id) noad = getsuppre (current) if noad then process(noad,n,current) end -- list noad = getsubpre (current) if noad then process(noad,n,current) end -- list end - noad = getfield(current,"accent") if noad then process(noad,n,current) end -- list - noad = getfield(current,"bot_accent") if noad then process(noad,n,current) end -- list + noad = getfield(current,"topaccent") if noad then process(noad,n,current) end -- list + noad = getfield(current,"botaccent") if noad then process(noad,n,current) end -- list end end @@ -584,7 +584,7 @@ do end end families[delimiter_code] = function(pointer) - if getfield(pointer,"small_fam") == 0 then + if getfield(pointer,"smallfamily") == 0 then local a = getattr(pointer,a_mathfamily) if a and a > 0 then setattr(pointer,a_mathfamily,0) @@ -593,23 +593,23 @@ do a = a - 3 end local fam = getfontoffamily(a) - local char = getfield(pointer,"small_char") + local char = getfield(pointer,"smallchar") local okay = fontcharacters[fam][char] if okay then - setfield(pointer,"small_fam",a) + setfield(pointer,"smallfamily",a) elseif a > 2 then - setfield(pointer,"small_fam",a-3) + setfield(pointer,"smallfamily",a-3) end - local char = getfield(pointer,"large_char") + local char = getfield(pointer,"largechar") local okay = fontcharacters[fam][char] if okay then - setfield(pointer,"large_fam",a) + setfield(pointer,"largefamily",a) elseif a > 2 then - setfield(pointer,"large_fam",a-3) + setfield(pointer,"largefamily",a-3) end else - setfield(pointer,"small_fam",0) - setfield(pointer,"large_fam",0) + setfield(pointer,"smallfamily",0) + setfield(pointer,"largefamily",0) end end end @@ -827,8 +827,8 @@ end -- empty and no larger next will be forced) -- -- beware: we don't use \delcode but \Udelcode and as such have --- no large_fam; also, we need to check for subtype and/or --- small_fam not being 0 because \. sits in 0,0 by default +-- no largefamily; also, we need to check for subtype and/or +-- smallfamily not being 0 because \. sits in 0,0 by default -- -- todo: just replace the character by an ord noad -- and remove the right delimiter as well diff --git a/tex/context/base/mkxl/math-tag.lmt b/tex/context/base/mkxl/math-tag.lmt index fa10c51c2..9ecc7047a 100644 --- a/tex/context/base/mkxl/math-tag.lmt +++ b/tex/context/base/mkxl/math-tag.lmt @@ -43,18 +43,18 @@ local nextnode = nuts.traversers.node local nodecodes = nodes.nodecodes -local noad_code = nodecodes.noad -- attr nucleus sub sup -local accent_code = nodecodes.accent -- attr nucleus sub sup accent -local radical_code = nodecodes.radical -- attr nucleus sub sup left degree -local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right -local subbox_code = nodecodes.subbox -- attr list -local submlist_code = nodecodes.submlist -- attr list -local mathchar_code = nodecodes.mathchar -- attr fam char -local mathtextchar_code = nodecodes.mathtextchar -- attr fam char -local delimiter_code = nodecodes.delimiter -- attr small_fam small_char large_fam large_char -local style_code = nodecodes.style -- attr style -local choice_code = nodecodes.choice -- attr display text script scriptscript -local fence_code = nodecodes.fence -- attr subtype +local noad_code = nodecodes.noad +local accent_code = nodecodes.accent +local radical_code = nodecodes.radical +local fraction_code = nodecodes.fraction +local subbox_code = nodecodes.subbox +local submlist_code = nodecodes.submlist +local mathchar_code = nodecodes.mathchar +local mathtextchar_code = nodecodes.mathtextchar +local delimiter_code = nodecodes.delimiter +local style_code = nodecodes.style +local choice_code = nodecodes.choice +local fence_code = nodecodes.fence local accentcodes = nodes.accentcodes local fencecodes = nodes.fencecodes @@ -526,39 +526,39 @@ process = function(start) -- we cannot use the processor as we have no finalizer stop_tagged() end elseif id == accent_code then - local accent = getfield(start,"accent") - local bot_accent = getfield(start,"bot_accent") - if bot_accent then - if accent then + local topaccent = getfield(start,"topaccent") + local botaccent = getfield(start,"botaccent") + if botaccent then + if topaccent then setattr(start,a_tagged,start_tagged("munderover", { accent = true, - top = getunicode(accent), - bottom = getunicode(bot_accent), + top = getunicode(topaccent), + bottom = getunicode(botaccent), topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code, bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) - process(bot_accent) - process(accent) + process(botaccent) + process(topaccent) stop_tagged() else setattr(start,a_tagged,start_tagged("munder", { accent = true, - bottom = getunicode(bot_accent), + bottom = getunicode(botaccent), bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) - process(bot_accent) + process(botaccent) stop_tagged() end - elseif accent then + elseif topaccent then setattr(start,a_tagged,start_tagged("mover", { accent = true, - top = getunicode(accent), + top = getunicode(topaccent), topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) - process(accent) + process(topaccent) stop_tagged() else processsubsup(start) diff --git a/tex/context/base/mkxl/math-vfu.lmt b/tex/context/base/mkxl/math-vfu.lmt index 6584b0158..abe336f53 100644 --- a/tex/context/base/mkxl/math-vfu.lmt +++ b/tex/context/base/mkxl/math-vfu.lmt @@ -9,7 +9,9 @@ if not modules then modules = { } end modules ['math-vfu'] = { -- All these math vectors .. thanks to Aditya and Mojca they become better and -- better. If you have problems with math fonts or miss characters report it to the -- ConTeXt mailing list. Also thanks to Boguslaw for finding a couple of errors. --- This mechanism will eventually disappear. + +-- This mechanism will eventually disappear or at least needs to be updated to the +-- way lmtx does virtual fonts. -- 20D6 -> 2190 -- 20D7 -> 2192 @@ -83,7 +85,7 @@ local shared = { } local function brace(main,characters,id,size,unicode,first,rule,left,right,rule,last) if not characters[unicode] then characters[unicode] = { - horiz_variants = { + hvariants = { { extender = 0, glyph = first }, { extender = 1, glyph = rule }, { extender = 0, glyph = left }, @@ -121,7 +123,7 @@ local function extension(main,characters,id,size,unicode,first,middle,last) if lw == 0 then lw = 1 end - chr.horiz_variants = { + chr.hvariants = { { extender = 0, glyph = first, ["end"] = fw/2, start = 0, advance = fw }, { extender = 1, glyph = middle, ["end"] = mw/2, start = mw/2, advance = mw }, { extender = 0, glyph = last, ["end"] = 0, start = lw/2, advance = lw }, @@ -131,7 +133,7 @@ end local function parent(main,characters,id,size,unicode,first,rule,last) if not characters[unicode] then characters[unicode] = { - horiz_variants = { + hvariants = { { extender = 0, glyph = first }, { extender = 1, glyph = rule }, { extender = 0, glyph = last }, @@ -150,7 +152,7 @@ local function make(main,characters,id,size,n,m) local dnslot = 0xFF200 + n local uprule = 0xFF300 + m local dnrule = 0xFF400 + m - local xu = main.parameters.x_height + 0.3*size + local xu = main.parameters.xheight + 0.3*size local xd = 0.3*size local w = c.width or 0 local h = c.height or 0 @@ -226,7 +228,7 @@ end local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess local raised = fonts.hashes.characters[main.fonts[id_of_smaller].id][private] -- characters[private] if raised then - local up = 0.85 * main.parameters.x_height + local up = 0.85 * main.parameters.xheight local slot = { "slot", id_of_smaller, private } local commands = { push, upcommand[up], slot, @@ -659,10 +661,10 @@ local function copy_glyph(main,target,original,unicode,slot) break -- safeguard (when testing stuff) end end - local hv = olddata.horiz_variants + local hv = olddata.hvariants if hv then hv = fastcopy(hv) - newdata.horiz_variants = hv + newdata.hvariants = hv for i=1,#hv do local hvi = hv[i] local oldglyph = hvi.glyph @@ -677,10 +679,10 @@ local function copy_glyph(main,target,original,unicode,slot) hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata) end end - local vv = olddata.vert_variants + local vv = olddata.vvariants if vv then vv = fastcopy(vv) - newdata.vert_variants = vv + newdata.vvariants = vv for i=1,#vv do local vvi = vv[i] local oldglyph = vvi.glyph @@ -822,8 +824,8 @@ function vfmath.define(specification,set,goodies) properties.fullname = fullname .. "-" .. unique end -- - if not parameters.x_height then - parameters.x_height = 0 + if not parameters.xheight then + parameters.xheight = 0 end -- local already_reported = false @@ -845,32 +847,33 @@ function vfmath.define(specification,set,goodies) elseif not newparameters then report_virtual("no parameters set in font %a",name) elseif ss.extension then - mathparameters.math_x_height = newparameters.x_height or 0 -- math_x_height : height of x - mathparameters.default_rule_thickness = newparameters[ 8] or 0 -- default_rule_thickness : thickness of \over bars - mathparameters.big_op_spacing1 = newparameters[ 9] or 0 -- big_op_spacing1 : minimum clearance above a displayed op - mathparameters.big_op_spacing2 = newparameters[10] or 0 -- big_op_spacing2 : minimum clearance below a displayed op - mathparameters.big_op_spacing3 = newparameters[11] or 0 -- big_op_spacing3 : minimum baselineskip above displayed op - mathparameters.big_op_spacing4 = newparameters[12] or 0 -- big_op_spacing4 : minimum baselineskip below displayed op - mathparameters.big_op_spacing5 = newparameters[13] or 0 -- big_op_spacing5 : padding above and below displayed limits + mathparameters.xheight = newparameters.xheight or 0 -- mathxheight : height of x + mathparameters.defaultrulethickness = newparameters[ 8] or 0 -- defaultrulethickness : thickness of \over bars + mathparameters.bigopspacing1 = newparameters[ 9] or 0 -- bigopspacing1 : minimum clearance above a displayed op + mathparameters.bigopspacing2 = newparameters[10] or 0 -- bigopspacing2 : minimum clearance below a displayed op + mathparameters.bigopspacing3 = newparameters[11] or 0 -- bigopspacing3 : minimum baselineskip above displayed op + mathparameters.bigopspacing4 = newparameters[12] or 0 -- bigopspacing4 : minimum baselineskip below displayed op + mathparameters.bigopspacing5 = newparameters[13] or 0 -- bigopspacing5 : padding above and below displayed limits -- report_virtual("loading and virtualizing font %a at size %p, setting ex parameters",name,size) elseif ss.parameters then - mathparameters.x_height = newparameters.x_height or mathparameters.x_height - mathparameters.x_height = mathparameters.x_height or fp.x_height or 0 -- x_height : height of x - mathparameters.num1 = newparameters[ 8] or 0 -- num1 : numerator shift-up in display styles - mathparameters.num2 = newparameters[ 9] or 0 -- num2 : numerator shift-up in non-display, non-\atop - mathparameters.num3 = newparameters[10] or 0 -- num3 : numerator shift-up in non-display \atop - mathparameters.denom1 = newparameters[11] or 0 -- denom1 : denominator shift-down in display styles - mathparameters.denom2 = newparameters[12] or 0 -- denom2 : denominator shift-down in non-display styles - mathparameters.sup1 = newparameters[13] or 0 -- sup1 : superscript shift-up in uncramped display style - mathparameters.sup2 = newparameters[14] or 0 -- sup2 : superscript shift-up in uncramped non-display - mathparameters.sup3 = newparameters[15] or 0 -- sup3 : superscript shift-up in cramped styles - mathparameters.sub1 = newparameters[16] or 0 -- sub1 : subscript shift-down if superscript is absent - mathparameters.sub2 = newparameters[17] or 0 -- sub2 : subscript shift-down if superscript is present - mathparameters.sup_drop = newparameters[18] or 0 -- sup_drop : superscript baseline below top of large box - mathparameters.sub_drop = newparameters[19] or 0 -- sub_drop : subscript baseline below bottom of large box - mathparameters.delim1 = newparameters[20] or 0 -- delim1 : size of \atopwithdelims delimiters in display styles - mathparameters.delim2 = newparameters[21] or 0 -- delim2 : size of \atopwithdelims delimiters in non-displays - mathparameters.axis_height = newparameters[22] or 0 -- axis_height : height of fraction lines above the baseline + mathparameters.xheight = newparameters.xheight + or mathparameters.xheight + or fs.xheight or 0 -- xheight : height of x + mathparameters.num1 = newparameters[ 8] or 0 -- num1 : numerator shift-up in display styles + mathparameters.num2 = newparameters[ 9] or 0 -- num2 : numerator shift-up in non-display, non-\atop + mathparameters.num3 = newparameters[10] or 0 -- num3 : numerator shift-up in non-display \atop + mathparameters.denom1 = newparameters[11] or 0 -- denom1 : denominator shift-down in display styles + mathparameters.denom2 = newparameters[12] or 0 -- denom2 : denominator shift-down in non-display styles + mathparameters.sup1 = newparameters[13] or 0 -- sup1 : superscript shift-up in uncramped display style + mathparameters.sup2 = newparameters[14] or 0 -- sup2 : superscript shift-up in uncramped non-display + mathparameters.sup3 = newparameters[15] or 0 -- sup3 : superscript shift-up in cramped styles + mathparameters.sub1 = newparameters[16] or 0 -- sub1 : subscript shift-down if superscript is absent + mathparameters.sub2 = newparameters[17] or 0 -- sub2 : subscript shift-down if superscript is present + mathparameters.sup_drop = newparameters[18] or 0 -- sup_drop : superscript baseline below top of large box + mathparameters.sub_drop = newparameters[19] or 0 -- sub_drop : subscript baseline below bottom of large box + mathparameters.delim1 = newparameters[20] or 0 -- delim1 : size of \atopwithdelims delimiters in display styles + mathparameters.delim2 = newparameters[21] or 0 -- delim2 : size of \atopwithdelims delimiters in non-displays + mathparameters.axisheight = newparameters[22] or 0 -- axisheight : height of fraction lines above the baseline -- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size) end if ss.overlay then @@ -941,13 +944,13 @@ function vfmath.define(specification,set,goodies) local kerns = fci.kerns local width = fci.width local italic = fci.italic --- if trace_virtual then --- report_virtual("character %C uses index %H in vector %a for font %a, %s, %s", --- unicode,index,vectorname,fontname, --- kerns and "adding kerns" or "no kerns", --- kerns and "adding italic" or "no italic" --- ) --- end + -- if trace_virtual then + -- report_virtual("character %C uses index %H in vector %a for font %a, %s, %s", + -- unicode,index,vectorname,fontname, + -- kerns and "adding kerns" or "no kerns", + -- kerns and "adding italic" or "no italic" + -- ) + -- end if italic and italic > 0 then -- int_a^b if isextension then @@ -976,7 +979,7 @@ function vfmath.define(specification,set,goodies) if skewchar then local k = kerns[skewchar] if k then - t.top_accent = width/2 + k + t.topaccent = width/2 + k end end characters[unicode] = t @@ -1014,30 +1017,30 @@ function vfmath.define(specification,set,goodies) if n then t.next = offset + n elseif variants_done then - local vv = fci.vert_variants + local vv = fci.vvariants if vv then - t.vert_variants = vv + t.vvariants = vv end - local hv = fci.horiz_variants + local hv = fci.hvariants if hv then - t.horiz_variants = hv + t.hvariants = hv end else - local vv = fci.vert_variants + local vv = fci.vvariants if vv then for i=1,#vv do local vvi = vv[i] vvi.glyph = vvi.glyph + offset end - t.vert_variants = vv + t.vvariants = vv end - local hv = fci.horiz_variants + local hv = fci.hvariants if hv then for i=1,#hv do local hvi = hv[i] hvi.glyph = hvi.glyph + offset end - t.horiz_variants = hv + t.hvariants = hv end end characters[offset + index] = t diff --git a/tex/context/base/mkxl/node-aux.lmt b/tex/context/base/mkxl/node-aux.lmt index 1aeae3b45..0c9bfc837 100644 --- a/tex/context/base/mkxl/node-aux.lmt +++ b/tex/context/base/mkxl/node-aux.lmt @@ -221,7 +221,7 @@ local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob- n = copy_node(space) elseif fonts then -- depedency local parameters = fonts.hashes.identifiers[fnt].parameters - space = new_glue(parameters.space,parameters.space_stretch,parameters.space_shrink) + space = new_glue(parameters.space,parameters.spacestretch,parameters.spaceshrink) n = space end elseif template then @@ -354,8 +354,8 @@ end do local parcodes = nodes.parcodes - local hmodepar_code = parcodes.hmode_par - local vmodepar_code = parcodes.vmode_par + local hmodepar_code = parcodes.hmodepar + local vmodepar_code = parcodes.vmodepar local getnest = tex.getnest local getsubtype = nuts.getsubtype diff --git a/tex/context/base/mkxl/node-pro.lmt b/tex/context/base/mkxl/node-pro.lmt index bbcbc9bdc..f38e8280b 100644 --- a/tex/context/base/mkxl/node-pro.lmt +++ b/tex/context/base/mkxl/node-pro.lmt @@ -111,11 +111,6 @@ do local lineactions = tasks.actions("contributers") local adjustactions = tasks.actions("adjusters") - -- contribute_head : pre_box - -- pre_adjust_head : pre_adjust - -- just_box : box - -- post_adjust_head : adjust - -- this was the "contributers" callback but we changed the interface -- historically we use a different order than the callback @@ -133,7 +128,7 @@ do end end end - elseif where == "post_adjust" or where == "pre_adjust" then + elseif where == "postadjust" or where == "preadjust" then -- we use the same order as for lines return adjustactions(head,where,tail,index) end diff --git a/tex/context/base/mkxl/node-rul.lmt b/tex/context/base/mkxl/node-rul.lmt index 8fa02cc89..0d1a9548e 100644 --- a/tex/context/base/mkxl/node-rul.lmt +++ b/tex/context/base/mkxl/node-rul.lmt @@ -341,8 +341,15 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a end end + local first = 1 + local last = level + + if extra then + first = level + end + if mp and mp ~= "" then - for i=extra and level or 1,level do + for i=first,last do local r = usernutrule { width = wd, height = ht, @@ -369,7 +376,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a l = hpack_nodes(l,wd,"exactly") inject(l,wd,ht,dp) else - for i=extra and level or 1,level do + for i=first,last do local hd = (offset+(i-1)*dy)*e - m local ht = hd + rulethickness local dp = -hd + rulethickness diff --git a/tex/context/base/mkxl/node-ser.lmt b/tex/context/base/mkxl/node-ser.lmt index c14a3826f..333784803 100644 --- a/tex/context/base/mkxl/node-ser.lmt +++ b/tex/context/base/mkxl/node-ser.lmt @@ -52,9 +52,9 @@ local canbeignored = { } local canbechar = { - char = true, - small_char = true, - large_char = true, + char = true, + smallchar = true, + largechar = true, } local fieldtypes = table.setmetatableindex(function(t,k) @@ -119,7 +119,7 @@ local function to_table(n,flat,verbose,noattributes,done) for field, fieldtype in sortedhash(fields) do local value = n[field] if value then - if fieldtype == "attribute_list" or fieldtype == "attribute" then + if fieldtype == "attributelist" or fieldtype == "attribute" or fieldtype == "attribute_list" then if noattributes then result[value] = canbeignored[value] else diff --git a/tex/context/base/mkxl/node-typ.lmt b/tex/context/base/mkxl/node-typ.lmt new file mode 100644 index 000000000..c09fd5f67 --- /dev/null +++ b/tex/context/base/mkxl/node-typ.lmt @@ -0,0 +1,135 @@ +if not modules then modules = { } end modules ['node-typ'] = { + 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" +} + +-- code has been moved to blob-ini.lua + +local typesetters = nodes.typesetters or { } +nodes.typesetters = typesetters + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local setlink = nuts.setlink +local setchar = nuts.setchar +local setattrlist = nuts.setattrlist + +local getfont = nuts.getfont + +local hpack_node_list = nuts.hpack +local vpack_node_list = nuts.vpack +local full_hpack_list = nuts.fullhpack + +local nodepool = nuts.pool +local new_glyph = nodepool.glyph +local new_glue = nodepool.glue + +local utfvalues = utf.values + +local currentfont = font.current +local currentattributes = nodes.currentattributes +local fontparameters = fonts.hashes.parameters + +-- when attrid == true then take from glyph or current else use the given value + +-- todo: glyphscale etc + +local function tonodes(str,fontid,spacing,templateglyph,attrid) -- quick and dirty + local head, prev = nil, nil + if not fontid then + fontid = templateglyph and getfont(templateglyph) or currentfont() + end + if attrid == true then + if templateglyph then + attrid = false -- we copy with the glyph + else + attrid = currentattributes() + end + end + local fp = fontparameters[fontid] + local s, p, m + if spacing then + s, p, m = spacing, 0, 0 + else + s, p, m = fp.space, fp.spacestretch, fp.spaceshrink + end + local spacedone = false + for c in utfvalues(str) do + local next + if c == 32 then + if not spacedone then + next = new_glue(s,p,m) + spacedone = true + end + elseif templateglyph then + next = copy_glyph(templateglyph) + setchar(next,c) + spacedone = false + else + next = new_glyph(fontid or 1,c) + spacedone = false + end + if not next then + -- nothing + elseif not head then + if attrid then + setattrlist(next,attrid) + end + head = next + else + if attrid then + setattrlist(next,attrid) + end + setlink(prev,next) + end + prev = next + end + return head +end + +local function tohpack(str,fontid,spacing) + return hpack_node_list(tonodes(str,fontid,spacing),"exactly") +end + +local function tohbox(str,fontid,spacing) + return full_hpack_list(tonodes(str,fontid,spacing),"exactly") +end + +local function tovpack(str,fontid,spacing) + -- vpack is just a hack, and a proper implementation is on the agenda + -- as it needs more info etc than currently available + return vpack_node_list(tonodes(str,fontid,spacing)) +end + +local tovbox = tovpack -- for now no vpack filter + +local tnuts = { } +nuts.typesetters = tnuts + +tnuts.tonodes = tonodes +tnuts.tohpack = tohpack +tnuts.tohbox = tohbox +tnuts.tovpack = tovpack +tnuts.tovbox = tovbox + +typesetters.tonodes = function(...) local h, b = tonodes(...) return tonode(h), b end +typesetters.tohpack = function(...) local h, b = tohpack(...) return tonode(h), b end +typesetters.tohbox = function(...) local h, b = tohbox (...) return tonode(h), b end +typesetters.tovpack = function(...) local h, b = tovpack(...) return tonode(h), b end +typesetters.tovbox = function(...) local h, b = tovbox (...) return tonode(h), b end + +typesetters.hpack = typesetters.tohpack -- obsolete +typesetters.hbox = typesetters.tohbox -- obsolete +typesetters.vpack = typesetters.tovpack -- obsolete + +-- context(nodes.typesetters.tohpack("Hello World!")) +-- context(nodes.typesetters.tohbox ("Hello World!")) +-- context(nodes.typesetters.tohpack("Hello World!",1,100*1024*10)) +-- context(nodes.typesetters.tohbox ("Hello World!",1,100*1024*10)) + +string.tonodes = function(...) return tonode(tonodes(...)) end -- quite convenient diff --git a/tex/context/base/mkxl/page-ini.lmt b/tex/context/base/mkxl/page-ini.lmt index ef34687c6..ec2278c01 100644 --- a/tex/context/base/mkxl/page-ini.lmt +++ b/tex/context/base/mkxl/page-ini.lmt @@ -361,10 +361,10 @@ implement { -- usage = "value", -- actions = function() -- local result = 0 --- if nodes.nuts.getspeciallist("contribute_head") then +-- if nodes.nuts.getspeciallist("contributehead") then -- result = result | 1 -- end --- if nodes.nuts.getspeciallist("page_head") then +-- if nodes.nuts.getspeciallist("pagehead") then -- result = result | 2 -- end -- return tokens.values.integer, result diff --git a/tex/context/base/mkxl/scrn-ref.lmt b/tex/context/base/mkxl/scrn-ref.lmt new file mode 100644 index 000000000..be298e2d1 --- /dev/null +++ b/tex/context/base/mkxl/scrn-ref.lmt @@ -0,0 +1,57 @@ +if not modules then modules = { } end modules ['scrn-ref'] = { + version = 1.001, + comment = "companion to scrn-int.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +interactions = interactions or { } +interactions.references = interactions.references or { } +local references = interactions.references + +local codeinjections = backends.codeinjections + +local identify = structures.references.identify + +local implement = interfaces.implement + +local function check(what) + if what and what ~= "" then + local set, bug = identify("",what) + return not bug and #set > 0 and set + end +end + +function references.setopendocumentaction(open) + local opendocument = check(open) + if opendocument then + codeinjections.registerdocumentopenaction(opendocument) + end +end + +function references.setclosedocumentaction(close) + local closedocument = check(close) + if closedocument then + codeinjections.registerdocumentcloseaction(closedocument) + end +end + +function references.setopenpageaction(open) + local openpage = check(open) + if openpage then + codeinjections.registerpageopenaction(openpage) + end +end + +function references.setclosepageaction(close) + local closepage = check(close) + if closepage then + codeinjections.registerpagecloseaction(closepage) + end +end + +implement { name = "setopendocumentaction", arguments = "string", actions = references.setopendocumentaction } +implement { name = "setclosedocumentaction", arguments = "string", actions = references.setclosedocumentaction } +implement { name = "setopenpageaction", arguments = "string", actions = references.setopenpageaction } +implement { name = "setclosepageaction", arguments = "string", actions = references.setclosepageaction } diff --git a/tex/context/base/mkxl/scrn-ref.mklx b/tex/context/base/mkxl/scrn-ref.mklx index d6fc6e127..ffe1fab16 100644 --- a/tex/context/base/mkxl/scrn-ref.mklx +++ b/tex/context/base/mkxl/scrn-ref.mklx @@ -13,7 +13,7 @@ \writestatus{loading}{ConTeXt Screen Macros / References} -\registerctxluafile{scrn-ref}{} +\registerctxluafile{scrn-ref}{autosuffix} \unprotect diff --git a/tex/context/base/mkxl/scrp-ini.lmt b/tex/context/base/mkxl/scrp-ini.lmt index b71a530a2..a8856f148 100644 --- a/tex/context/base/mkxl/scrp-ini.lmt +++ b/tex/context/base/mkxl/scrp-ini.lmt @@ -871,8 +871,8 @@ do if lastfont ~= font then local pf = parameters[font] space = pf.space - stretch = pf.space_stretch - shrink = pf.space_shrink + stretch = pf.spacestretch + shrink = pf.spaceshrink lastfont = font end return new_glue( diff --git a/tex/context/base/mkxl/spac-chr.lmt b/tex/context/base/mkxl/spac-chr.lmt index e38f2a30e..554dc0400 100644 --- a/tex/context/base/mkxl/spac-chr.lmt +++ b/tex/context/base/mkxl/spac-chr.lmt @@ -131,7 +131,7 @@ local function nbsp(head,current) if attr >= 1 and attr <= 3 then -- flushright head, current = inject_nobreak_space(0x00A0,head,current,para.space,0,0) else - head, current = inject_nobreak_space(0x00A0,head,current,para.space,para.space_stretch,para.space_shrink) + head, current = inject_nobreak_space(0x00A0,head,current,para.space,para.spacestretch,para.spaceshrink) end setsubtype(current,spaceskip_code) return head, current @@ -190,7 +190,7 @@ local methods = { head, current = remove_node(head,current,true) if not is_punctuation[char] then local p = fontparameters[font] - head, current = insertnodebefore(head,current,new_glue(p.space,p.space_stretch,p.space_shrink)) + head, current = insertnodebefore(head,current,new_glue(p.space,p.spacestretch,p.spaceshrink)) end end end diff --git a/tex/context/base/mkxl/spac-prf.lmt b/tex/context/base/mkxl/spac-prf.lmt index 2223c7730..c38cdc97b 100644 --- a/tex/context/base/mkxl/spac-prf.lmt +++ b/tex/context/base/mkxl/spac-prf.lmt @@ -269,9 +269,9 @@ end profiling.get = getprofile local function getpagelist() - local pagehead = texlists.page_head + local pagehead = texlists.pagehead if pagehead then - pagehead = tonut(texlists.page_head) + pagehead = tonut(texlists.pagehead) pagetail = find_node_tail(pagehead) else pagetail = nil diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt index ca0544cf8..fcb1b7e7f 100644 --- a/tex/context/base/mkxl/spac-ver.lmt +++ b/tex/context/base/mkxl/spac-ver.lmt @@ -1054,7 +1054,7 @@ end -- implementation --- alignment box begin_of_par vmode_par hmode_par insert penalty before_display after_display +-- alignment box begin_of_par vmodepar hmodepar insert penalty before_display after_display function vspacing.snapbox(n,how) local sv = snapmethods[how] @@ -1440,7 +1440,7 @@ do -- quit, we're not on the mvl else -- inefficient when we're at the end of a page - local c = tonut(texlists.page_head) + local c = tonut(texlists.pagehead) while c and c ~= n do local id = getid(c) if id == hlist_code then @@ -1486,7 +1486,7 @@ do -- local function getpagelist() if not pagehead then - pagehead = texlists.page_head + pagehead = texlists.pagehead if pagehead then pagehead = tonut(pagehead) pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet @@ -2263,7 +2263,7 @@ do function vspacing.getnofpreviouslines(head) if enabled then if not thead then - head = texlists.page_head + head = texlists.pagehead end local noflines = 0 if head then @@ -2314,7 +2314,7 @@ do if trace then local newdepth = outer.prevdepth local olddepth = newdepth - if not texlists.page_head then + if not texlists.pagehead then newdepth = ignoredepth texset("prevdepth",ignoredepth) outer.prevdepth = ignoredepth @@ -2322,7 +2322,7 @@ do report("page %i, prevdepth %p => %p",texgetcount("realpageno"),olddepth,newdepth) -- report("list %s",nodes.idsandsubtypes(head)) else - if not texlists.page_head then + if not texlists.pagehead then texset("prevdepth",ignoredepth) outer.prevdepth = ignoredepth end @@ -2353,7 +2353,7 @@ do end nest.prevdepth = depth elseif id == temp_code and texgetnest("ptr") == 0 then - local head = texgetlist("page_head") + local head = texgetlist("pagehead") if head then tail = getnodetail(head) if tail and tail.id == hlist_code then @@ -2472,11 +2472,11 @@ do -- check if in mvl if texgetnest("ptr") == 0 then -- this flushes the contributions - while getspeciallist("contribute_head") do + while getspeciallist("contributehead") do triggerbuildpage() end -- now we consult the last line (if present) - local head, tail = getspeciallist("page_head") + local head, tail = getspeciallist("pagehead") if tail then for n, id, subtype in treversenode, tail do if id == hlist_code then @@ -2521,7 +2521,7 @@ do -- interfaces.implement { -- name = "removelastline", -- actions = function() - -- local h, t = getspeciallist("page_head") + -- local h, t = getspeciallist("pagehead") -- if t and getid(t) == hlist_code and getsubtype(t) == line_code then -- local total = gettotal(t) -- h = remove_node(h,t,true) @@ -2663,10 +2663,10 @@ do -- interfaces.implement { -- name = "fakenextstrutline", -- actions = function() - -- local head = texlists.page_head + -- local head = texlists.pagehead -- if head then -- local head = remove_node(head,find_node_tail(head),true) - -- texlists.page_head = head + -- texlists.pagehead = head -- buildpage() -- end -- end @@ -2675,13 +2675,13 @@ do implement { name = "removelastline", actions = function() - local head = texlists.page_head + local head = texlists.pagehead if head then local tail = find_node_tail(head) if tail then -- maybe check for hlist subtype 1 local head = remove_node(head,tail,true) - texlists.page_head = head + texlists.pagehead = head buildpage() end end @@ -2691,7 +2691,7 @@ do implement { name = "showpagelist", -- will improve actions = function() - local head = texlists.page_head + local head = texlists.pagehead if head then print("start") while head do diff --git a/tex/context/base/mkxl/supp-box.lmt b/tex/context/base/mkxl/supp-box.lmt index 03bb54137..8a290b5ae 100644 --- a/tex/context/base/mkxl/supp-box.lmt +++ b/tex/context/base/mkxl/supp-box.lmt @@ -757,9 +757,9 @@ end implement { name = "lastlinewidth", actions = function() - local head = tex.lists.page_head + local head = tex.lists.pagehead -- list dimensions returns 3 value but we take the first - context(head and getdimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0) + context(head and getdimensions(getlist(find_tail(tonut(tex.lists.pagehead)))) or 0) end } diff --git a/tex/context/base/mkxl/trac-jus.lmt b/tex/context/base/mkxl/trac-jus.lmt new file mode 100644 index 000000000..e9c8fac28 --- /dev/null +++ b/tex/context/base/mkxl/trac-jus.lmt @@ -0,0 +1,122 @@ +if not modules then modules = { } end modules ['trac-jus'] = { + version = 1.001, + comment = "companion to trac-jus.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local checkers = typesetters.checkers or { } +typesetters.checkers = checkers + +----- report_justification = logs.reporter("visualize","justification") + +local a_alignstate = attributes.private("alignstate") +local a_justification = attributes.private("justification") + +local nuts = nodes.nuts + +local getfield = nuts.getfield +local getlist = nuts.getlist +local getattr = nuts.getattr +local setattr = nuts.setattr +local setlist = nuts.setlist +local setlink = nuts.setlink +local getwidth = nuts.getwidth +local findtail = nuts.tail + +local nexthlist = nuts.traversers.hlist + +local getdimensions = nuts.dimensions +local copylist = nuts.copylist + +local tracedrule = nodes.tracers.pool.nuts.rule + +local nodepool = nuts.pool + +local new_hlist = nodepool.hlist +local new_kern = nodepool.kern + +local hlist_code = nodes.nodecodes.hlist + +local texsetattribute = tex.setattribute +local unsetvalue = attributes.unsetvalue + +local enableaction = nodes.tasks.enableaction + +local min_threshold = 0 +local max_threshold = 0 + +local function set(n) + enableaction("mvlbuilders", "typesetters.checkers.handler") + enableaction("vboxbuilders","typesetters.checkers.handler") + texsetattribute(a_justification,n or 1) + function typesetters.checkers.set(n) + texsetattribute(a_justification,n or 1) + end +end + +local function reset() + texsetattribute(a_justification,unsetvalue) +end + +checkers.set = set +checkers.reset = reset + +interfaces.implement { + name = "showjustification", + actions = set +} + +trackers.register("visualizers.justification", function(v) + if v then + set(1) + else + reset() + end +end) + +function checkers.handler(head) + for current in nexthlist, head do + if getattr(current,a_justification) == 1 then + setattr(current,a_justification,0) -- kind of reset + local width = getwidth(current) + if width > 0 then + local list = getlist(current) + if list then + local naturalwidth, naturalheight, naturaldepth = getdimensions(list) + local delta = naturalwidth - width + if naturalwidth == 0 or delta == 0 then + -- special box + elseif delta >= max_threshold then + local rule = new_hlist(tracedrule(delta,naturalheight,naturaldepth,getfield(list,"glueset") == 1 and "trace:dr" or "trace:db")) + setlink(findtail(list),rule) + setlist(current,list) + elseif delta <= min_threshold then + local alignstate = getattr(list,a_alignstate) + if alignstate == 1 then + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dc")) + setlink(rule,list) + setlist(current,rule) + elseif alignstate == 2 then + local lrule = new_hlist(tracedrule(-delta/2,naturalheight,naturaldepth,"trace:dy")) + local rrule = copylist(lrule) + setlink(lrule,list) + setlink(findtail(list),new_kern(delta/2),rrule) + setlist(current,lrule) + elseif alignstate == 3 then + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dm")) + setlink(findtail(list),new_kern(delta),rule) + setlist(current,list) + else + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dg")) + setlink(findtail(list),new_kern(delta),rule) + setlist(current,list) + end + end + end + end + end + end + return head +end diff --git a/tex/context/base/mkxl/trac-jus.mkxl b/tex/context/base/mkxl/trac-jus.mkxl index 3375e5ee7..387478cb1 100644 --- a/tex/context/base/mkxl/trac-jus.mkxl +++ b/tex/context/base/mkxl/trac-jus.mkxl @@ -13,7 +13,7 @@ \writestatus{loading}{ConTeXt Tracing Macros / Justification} -\registerctxluafile{trac-jus}{} +\registerctxluafile{trac-jus}{autosuffix} \unprotect diff --git a/tex/context/base/mkxl/typo-adj.lmt b/tex/context/base/mkxl/typo-adj.lmt index 53abe4f1d..31a2c2c78 100644 --- a/tex/context/base/mkxl/typo-adj.lmt +++ b/tex/context/base/mkxl/typo-adj.lmt @@ -52,7 +52,7 @@ local postactions = { } -- function nodes.handlers.adjusters(head,where,tail) --- if where == "pre_adjust" then +-- if where == "preadjust" then -- local a = getattr(tail,a_adjuster) -- if a then -- a = preactions[a] @@ -60,7 +60,7 @@ local postactions = { -- head = a(head,tail) -- end -- end --- elseif where == "post_adjust" then +-- elseif where == "postadjust" then -- local a = getattr(tail,a_adjuster) -- if a then -- a = postactions[a] @@ -75,12 +75,12 @@ local postactions = { -- end function nodes.handlers.adjusters(head,where,tail,index) - if where == "pre_adjust" then + if where == "preadjust" then local a = preactions[index] if a then head = a(head,tail) end - else -- if where == "post_adjust" then + else -- if where == "postadjust" then local a = postactions[index] if a then head = a(head,tail) diff --git a/tex/context/base/mkxl/typo-bld.lmt b/tex/context/base/mkxl/typo-bld.lmt index 31cc0bb59..9c83adede 100644 --- a/tex/context/base/mkxl/typo-bld.lmt +++ b/tex/context/base/mkxl/typo-bld.lmt @@ -231,10 +231,10 @@ end -- the check can go away -- Todo: contrib_head can be any head (kind of) not per se the page one so maybe I will --- intercept that in the engine with page_contribute_head or so. +-- intercept that in the engine with contributehead or so. function builders.buildpage_filter(groupcode) - local head = texlists.contribute_head + local head = texlists.contributehead if head then local done = false -- called quite often ... maybe time to remove timing @@ -246,8 +246,8 @@ function builders.buildpage_filter(groupcode) stoptiming(builders) -- -- doesn't work here (not passed on?) -- texset("pagegoal,texget("vsize") - texgetdimen("d_page_floats_inserted_top") - texgetdimen("d_page_floats_inserted_bottom") - texlists.contribute_head = head or nil -- needs checking - -- tex.setlist("contribute_head",head,head and nodes.tail(head)) + texlists.contributehead = head or nil -- needs checking + -- tex.setlist("contributehead",head,head and nodes.tail(head)) return done and head or true -- no return value needed else -- happens quite often diff --git a/tex/context/base/mkxl/typo-krn.lmt b/tex/context/base/mkxl/typo-krn.lmt index 450194767..bfd50062d 100644 --- a/tex/context/base/mkxl/typo-krn.lmt +++ b/tex/context/base/mkxl/typo-krn.lmt @@ -207,7 +207,7 @@ local function kern_injector(fillup,kern) if fillup then local g = new_glue(kern) setfield(g,"stretch",kern) - setfield(g,"stretch_order",1) + setfield(g,"stretchorder",1) return g else return new_kern(kern) @@ -538,7 +538,7 @@ function kerns.handler(head) elseif id == glue_code then local subtype = getsubtype(start) if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then - local width, stretch, shrink, stretch_order, shrink_order = getglue(start) + local width, stretch, shrink, stretchorder, shrinkorder = getglue(start) if width > 0 then local w = width + gluefactor * width * krn stretch = stretch * w / width @@ -546,10 +546,10 @@ function kerns.handler(head) if fillup then stretch = 2 * stretch shrink = 2 * shrink - stretch_order = 1 - -- shrink_order = 1 ? + stretchorder = 1 + -- shrinkorder = 1 ? end - setglue(start,w,stretch,shrink,stretch_order,shrink_order) + setglue(start,w,stretch,shrink,stretchorder,shrinkorder) end end bound = false diff --git a/tex/context/base/mkxl/typo-mar.lmt b/tex/context/base/mkxl/typo-mar.lmt index f8c135fa7..b590c9ecf 100644 --- a/tex/context/base/mkxl/typo-mar.lmt +++ b/tex/context/base/mkxl/typo-mar.lmt @@ -806,7 +806,7 @@ local function flushed(scope,parent) -- current is hlist return done, continue end --- only when group : vbox|vmode_par +-- only when group : vbox|vmodepar -- only when subtype : line, box (no indent alignment cell) local function handler(scope,head,group) @@ -884,9 +884,9 @@ function margins.globalhandler(head,group) -- check group report_margindata("ignored 1, group %a, stored %s, inhibit %a",group,nofstored,inhibit) end return head - elseif group == "hmode_par" then + elseif group == "hmodepar" then return handler(v_global,head,group) - elseif group == "vmode_par" then -- experiment (for alignments) + elseif group == "vmodepar" then -- experiment (for alignments) return handler(v_global,head,group) -- this needs checking as we then get quite some one liners to process and -- we cannot look ahead then: diff --git a/tex/context/base/mkxl/typo-par.mkxl b/tex/context/base/mkxl/typo-par.mkxl index 22450e76e..077d3566c 100644 --- a/tex/context/base/mkxl/typo-par.mkxl +++ b/tex/context/base/mkxl/typo-par.mkxl @@ -24,7 +24,7 @@ \unprotect %registerctxluafile{node-ltp}{optimize} -\registerctxluafile{node-ltp}{} +\registerctxluafile{node-ltp}{autosuffix} % this one has to be updated! \registerctxluafile{trac-par}{} \registerctxluafile{typo-par}{} diff --git a/tex/context/fonts/mkiv/type-imp-adobegaramond.mkiv b/tex/context/fonts/mkiv/type-imp-adobegaramond.mkiv new file mode 100644 index 000000000..88ad5ed2c --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-adobegaramond.mkiv @@ -0,0 +1,42 @@ +%D \module +%D [ file=type-imp-adobegaramond, +%D version=2021.10.30, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Adobe Garamond, +%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. + + +\starttypescriptcollection[adobegaramond] + + \starttypescript [\s!serif] [adobegaramond] [\s!name] + \setups[font:fallback:serif] + \definefontsynonym [\s!Serif] [\s!file:AGaramondPro-Regular] + \definefontsynonym [\s!SerifItalic] [\s!file:AGaramondPro-Italic] + \definefontsynonym [\s!SerifBold] [\s!file:AGaramondPro-Semibold] + \stoptypescript + + \starttypescript [\s!sans] [frutiger] [\s!name] + \setups[font:fallback:sans] + \definefontsynonym [\s!Sans] [\s!file:FrutigerLTStd-Roman] + \definefontsynonym [\s!SansItalic] [\s!file:FrutigerLTStd-Italic] + \definefontsynonym [\s!SansBold] [\s!file:FrutigerLTStd-Bold] + \stoptypescript + + \starttypescript [\s!math] [garamond-math] [\s!name] + \loadfontgoodies[garamond-math] + \definefontsynonym [\s!MathRoman] [\s!file:garamond-math.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=garamond-math] + \stoptypescript + + \starttypescript[adobegaramond] + \definetypeface [adobegaramond] [\s!rm] [\s!serif] [adobegaramond] [\s!default] + \definetypeface [adobegaramond] [\s!ss] [\s!sans] [frutiger] [\s!default] [\s!rscale=0.85] + \definetypeface [adobegaramond] [\s!mm] [\s!math] [garamond-math] [\s!default] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv index 05ac2f1fa..03bb91989 100644 --- a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv +++ b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv @@ -66,8 +66,8 @@ \stoptypescript \starttypescript [\s!math] [ebgaramond] [\s!name] - \loadfontgoodies[ebgaramond] - \definefontsynonym [\s!MathRoman] [\s!file:garamond-math.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=ebgaramond] + \loadfontgoodies[garamond-math] + \definefontsynonym [\s!MathRoman] [\s!file:garamond-math.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=garamond-math] \stoptypescript \starttypescript[ebgaramond] diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 76f6d8117..70fc55c34 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -1288,6 +1288,7 @@ <cd:constant name='tab' value='تب'/> <cd:constant name='text' value='متن'/> <cd:constant name='textalign' value='textalign'/> + <cd:constant name='textalternative' value='textalternative'/> <cd:constant name='textcolor' value='رنگمتن'/> <cd:constant name='textcommand' value='فرمانمتن'/> <cd:constant name='textdistance' value='فاصلهمتن'/> diff --git a/tex/context/modules/mkiv/s-math-characters.lua b/tex/context/modules/mkiv/s-math-characters.lua index 61b2c8808..fc697cae5 100644 --- a/tex/context/modules/mkiv/s-math-characters.lua +++ b/tex/context/modules/mkiv/s-math-characters.lua @@ -157,8 +157,8 @@ local alllookups = collectalllookups(tfmdata,"math","dflt") -- skip else local next_sizes = char.next - local v_variants = char.vert_variants - local h_variants = char.horiz_variants + local vvariants = char.vvariants or char.vert_variants + local hvariants = char.hvariants or char.horiz_variants local mathclass = info.mathclass local mathspec = info.mathspec local mathsymbol = info.mathsymbol @@ -208,29 +208,29 @@ local alllookups = collectalllookups(tfmdata,"math","dflt") done[next_sizes] = true context.showmathcharactersnextentry(n,f_unicode(next_sizes),next_sizes) next_sizes = characters[next_sizes] - v_variants = next_sizes.vert_variants or v_variants - h_variants = next_sizes.horiz_variants or h_variants + vvariants = next_sizes.vvariants or next_sizes.vert_variants or vvariants + hvariants = next_sizes.hvariants or next_sizes.horiz_variants or hvariants if next_sizes then next_sizes = next_sizes.next end end end context.showmathcharactersstopnext() - if h_variants or v_variants then + if hvariants or vvariants then context.showmathcharactersbetweennextandvariants() end end - if h_variants then + if hvariants then context.showmathcharactersstarthvariants() - for i=1,#h_variants do -- we might go top-down in the original - local vi = h_variants[i] + for i=1,#hvariants do -- we might go top-down in the original + local vi = hvariants[i] context.showmathcharactershvariantsentry(i,f_unicode(vi.glyph),vi.glyph) end context.showmathcharactersstophvariants() - elseif v_variants then + elseif vvariants then context.showmathcharactersstartvvariants() - for i=1,#v_variants do - local vi = v_variants[#v_variants-i+1] + for i=1,#vvariants do + local vi = vvariants[#vvariants-i+1] context.showmathcharactersvvariantsentry(i,f_unicode(vi.glyph),vi.glyph) end context.showmathcharactersstopvvariants() diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 7ac66bfc7..e50c388b9 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-11-30 19:43 +-- merge date : 2021-12-03 15:17 do -- begin closure to overcome local limits and interference |