diff options
93 files changed, 2342 insertions, 996 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 304124df5..1651800e7 100644 --- a/context/data/scite/context/lexers/data/scite-context-data-tex.lua +++ b/context/data/scite/context/lexers/data/scite-context-data-tex.lua @@ -1,9 +1,9 @@ return { ["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" }, ["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "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", "tracingnesting", "unexpanded", "unless", "widowpenalties" }, - ["luatex"]={ "Uabove", "Uabovewithdelims", "Uatop", "Uatopwithdelims", "Uchar", "Udelcode", "Udelimited", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaccentbasedepth", "Umathaccentbaseheight", "Umathaccentbottomovershoot", "Umathaccentbottomshiftdown", "Umathaccentextendmargin", "Umathaccentsuperscriptdrop", "Umathaccentsuperscriptpercent", "Umathaccenttopovershoot", "Umathaccenttopshiftup", "Umathaccentvariant", "Umathadapttoleft", "Umathadapttoright", "Umathaxis", "Umathbottomaccentvariant", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharslot", "Umathclass", "Umathcode", "Umathconnectoroverlapmin", "Umathdegreevariant", "Umathdelimiterovervariant", "Umathdelimiterpercent", "Umathdelimitershortfall", "Umathdelimiterundervariant", "Umathdenominatorvariant", "Umathdict", "Umathdictdef", "Umathdiscretionary", "Umathextrasubpreshift", "Umathextrasubprespace", "Umathextrasubshift", "Umathextrasubspace", "Umathextrasuppreshift", "Umathextrasupprespace", "Umathextrasupshift", "Umathextrasupspace", "Umathflattenedaccentbasedepth", "Umathflattenedaccentbaseheight", "Umathflattenedaccentbottomshiftdown", "Umathflattenedaccenttopshiftup", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathfractionvariant", "Umathhextensiblevariant", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathlimits", "Umathnoaxis", "Umathnolimits", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathnumeratorvariant", "Umathopenupdepth", "Umathopenupheight", "Umathoperatorsize", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervariant", "Umathoverdelimitervgap", "Umathoverlayaccentvariant", "Umathoverlinevariant", "Umathphantom", "Umathpresubshiftdistance", "Umathpresupshiftdistance", "Umathprimeraise", "Umathprimeraisecomposed", "Umathprimeshiftdrop", "Umathprimeshiftup", "Umathprimespaceafter", "Umathprimevariant", "Umathprimewidth", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalextensibleafter", "Umathradicalextensiblebefore", "Umathradicalkern", "Umathradicalrule", "Umathradicalvariant", "Umathradicalvgap", "Umathruledepth", "Umathruleheight", "Umathskeweddelimitertolerance", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathsource", "Umathspaceafterscript", "Umathspacebeforescript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvariant", "Umathstackvgap", "Umathsubscriptvariant", "Umathsubshiftdistance", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsuperscriptvariant", "Umathsupshiftdistance", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathtopaccentvariant", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervariant", "Umathunderdelimitervgap", "Umathunderlinevariant", "Umathuseaxis", "Umathvextensiblevariant", "Umathvoid", "Umathxscale", "Umathyscale", "Umiddle", "Unosubprescript", "Unosubscript", "Unosuperprescript", "Unosuperscript", "Uoperator", "Uover", "Uoverdelimiter", "Uoverwithdelims", "Uprimescript", "Uradical", "Uright", "Uroot", "Urooted", "Ushiftedsubprescript", "Ushiftedsubscript", "Ushiftedsuperprescript", "Ushiftedsuperscript", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustartmathmode", "Ustopdisplaymath", "Ustopmath", "Ustopmathmode", "Ustretched", "Ustretchedwithdelims", "Ustyle", "Usubprescript", "Usubscript", "Usuperprescript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "adjustspacingshrink", "adjustspacingstep", "adjustspacingstretch", "afterassigned", "aftergrouped", "aliased", "aligncontent", "alignmark", "alignmentcellsource", "alignmentwrapsource", "aligntab", "allcrampedstyles", "alldisplaystyles", "allmainstyles", "allmathstyles", "allscriptscriptstyles", "allscriptstyles", "allsplitstyles", "alltextstyles", "alluncrampedstyles", "allunsplitstyles", "amcode", "atendofgroup", "atendofgrouped", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenpenalty", "automigrationmode", "autoparagraphmode", "begincsname", "beginlocalcontrol", "beginmathgroup", "beginsimplegroup", "boundary", "boxadapt", "boxanchor", "boxanchors", "boxattribute", "boxdirection", "boxfreeze", "boxgeometry", "boxorientation", "boxrepack", "boxshift", "boxsource", "boxtarget", "boxtotal", "boxvadjust", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "catcodetable", "cdef", "cdefcsname", "cfcode", "clearmarks", "constant", "copymathatomrule", "copymathparent", "copymathspacing", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csactive", "csstring", "currentloopiterator", "currentloopnesting", "currentmarks", "dbox", "defcsname", "detokenized", "dimensiondef", "dimexpression", "directlua", "dpack", "dsplit", "edefcsname", "efcode", "endlocalcontrol", "endmathgroup", "endsimplegroup", "enforced", "etoks", "etoksapp", "etokspre", "everybeforepar", "everymathatom", "everytab", "exceptionpenalty", "expand", "expandactive", "expandafterpars", "expandafterspaces", "expandcstoken", "expanded", "expandedafter", "expandedloop", "expandtoken", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "flushmarks", "fontcharta", "fontid", "fontmathcontrol", "fontspecdef", "fontspecid", "fontspecifiedname", "fontspecifiedsize", "fontspecscale", "fontspecxscale", "fontspecyscale", "fonttextcontrol", "formatname", "frozen", "futurecsname", "futuredef", "futureexpand", "futureexpandis", "futureexpandisap", "gdefcsname", "gleaders", "glet", "gletcsname", "glettonothing", "gluespecdef", "glyph", "glyphdatafield", "glyphoptions", "glyphscale", "glyphscriptfield", "glyphscriptscale", "glyphscriptscriptscale", "glyphstatefield", "glyphtextscale", "glyphxoffset", "glyphxscale", "glyphxscaled", "glyphyoffset", "glyphyscale", "glyphyscaled", "gtoksapp", "gtokspre", "hccode", "hjcode", "hmcode", "holdingmigrations", "hpack", "hyphenationmin", "hyphenationmode", "ifabsdim", "ifabsnum", "ifarguments", "ifboolean", "ifchkdim", "ifchkdimension", "ifchknum", "ifchknumber", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimexpression", "ifdimval", "ifempty", "ifflags", "ifhaschar", "ifhastok", "ifhastoks", "ifhasxtoks", "ifincsname", "ifinsert", "ifmathparameter", "ifmathstyle", "ifnumexpression", "ifnumval", "ifparameter", "ifparameters", "ifrelax", "iftok", "ifzerodim", "ifzeronum", "ignorearguments", "ignoredepthcriterium", "ignorepars", "immediate", "immutable", "indexofcharacter", "indexofregister", "inherited", "initcatcodetable", "insertbox", "insertcopy", "insertdepth", "insertdistance", "insertheight", "insertheights", "insertlimit", "insertmaxdepth", "insertmode", "insertmultiplier", "insertpenalty", "insertprogress", "insertstorage", "insertstoring", "insertunbox", "insertuncopy", "insertwidth", "instance", "integerdef", "lastarguments", "lastatomclass", "lastboundary", "lastchkdim", "lastchknum", "lastleftclass", "lastloopiterator", "lastnamedcs", "lastnodesubtype", "lastpageextra", "lastparcontext", "lastrightclass", "leftmarginkern", "letcharcode", "letcsname", "letfrozen", "letmathatomrule", "letmathparent", "letmathspacing", "letprotected", "lettonothing", "linebreakcriterium", "linedirection", "localbrokenpenalty", "localcontrol", "localcontrolled", "localcontrolledloop", "localinterlinepenalty", "localleftbox", "localleftboxbox", "localmiddlebox", "localmiddleboxbox", "localrightbox", "localrightboxbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathaccent", "mathatom", "mathatomglue", "mathatomskip", "mathbackwardpenalties", "mathbeginclass", "mathcheckfencesmode", "mathdictgroup", "mathdictproperties", "mathdirection", "mathdisplaymode", "mathdisplayskipmode", "mathdoublescriptmode", "mathendclass", "matheqnogapstep", "mathfenced", "mathfontcontrol", "mathforwardpenalties", "mathfraction", "mathghost", "mathgluemode", "mathgroupingmode", "mathleftclass", "mathlimitsmode", "mathmainstyle", "mathmiddle", "mathnolimitsmode", "mathpenaltiesmode", "mathradical", "mathrightclass", "mathrulesfam", "mathrulesmode", "mathscale", "mathscriptsmode", "mathslackmode", "mathspacingmode", "mathstackstyle", "mathstyle", "mathstylefontid", "mathsurroundmode", "mathsurroundskip", "maththreshold", "meaningasis", "meaningfull", "meaningless", "mugluespecdef", "mutable", "noaligned", "noatomruling", "noboundary", "nohrule", "norelax", "normalizelinemode", "normalizeparmode", "nospaces", "novrule", "numericscale", "numexpression", "orelse", "orphanpenalties", "orphanpenalty", "orunless", "outputbox", "overloaded", "overloadmode", "overshoot", "pageboundary", "pageextragoal", "pagevsize", "parametercount", "parametermark", "parattribute", "pardirection", "permanent", "pettymuskip", "postexhyphenchar", "posthyphenchar", "postinlinepenalty", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "preinlinepenalty", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitloop", "quitvmode", "resetmathspacing", "retokenized", "rightmarginkern", "rpcode", "savecatcodetable", "scaledemwidth", "scaledexheight", "scaledextraspace", "scaledfontdimen", "scaledinterwordshrink", "scaledinterwordspace", "scaledinterwordstretch", "scaledmathstyle", "scaledslantperpoint", "scantextokens", "semiexpand", "semiexpanded", "semiprotected", "setdefaultmathcodes", "setfontid", "setmathatomrule", "setmathdisplaypostpenalty", "setmathdisplayprepenalty", "setmathignore", "setmathoptions", "setmathpostpenalty", "setmathprepenalty", "setmathspacing", "shapingpenaltiesmode", "shapingpenalty", "snapshotpar", "srule", "supmarkmode", "swapcsvalues", "tabsize", "textdirection", "thewithoutunit", "tinymuskip", "todimension", "tohexadecimal", "tointeger", "tokenized", "toksapp", "tokspre", "tolerant", "tomathstyle", "toscaled", "tosparsedimension", "tosparsescaled", "tpack", "tracingadjusts", "tracingalignments", "tracingexpressions", "tracingfonts", "tracingfullboxes", "tracinghyphenation", "tracinginserts", "tracinglevels", "tracinglists", "tracingmarks", "tracingmath", "tracingnodes", "tracingpenalties", "tsplit", "uleaders", "undent", "unexpandedloop", "unhpack", "unletfrozen", "unletprotected", "untraced", "unvpack", "variablefam", "vpack", "wordboundary", "wrapuppar", "xdefcsname", "xtoks", "xtoksapp", "xtokspre" }, + ["luatex"]={ "Uabove", "Uabovewithdelims", "Uatop", "Uatopwithdelims", "Uchar", "Udelcode", "Udelimited", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Uleft", "Umathaccent", "Umathaccentbasedepth", "Umathaccentbaseheight", "Umathaccentbottomovershoot", "Umathaccentbottomshiftdown", "Umathaccentextendmargin", "Umathaccentsuperscriptdrop", "Umathaccentsuperscriptpercent", "Umathaccenttopovershoot", "Umathaccenttopshiftup", "Umathaccentvariant", "Umathadapttoleft", "Umathadapttoright", "Umathaxis", "Umathbottomaccentvariant", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharslot", "Umathclass", "Umathcode", "Umathconnectoroverlapmin", "Umathdegreevariant", "Umathdelimiterovervariant", "Umathdelimiterpercent", "Umathdelimitershortfall", "Umathdelimiterundervariant", "Umathdenominatorvariant", "Umathdict", "Umathdictdef", "Umathdiscretionary", "Umathextrasubpreshift", "Umathextrasubprespace", "Umathextrasubshift", "Umathextrasubspace", "Umathextrasuppreshift", "Umathextrasupprespace", "Umathextrasupshift", "Umathextrasupspace", "Umathflattenedaccentbasedepth", "Umathflattenedaccentbaseheight", "Umathflattenedaccentbottomshiftdown", "Umathflattenedaccenttopshiftup", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathfractionvariant", "Umathhextensiblevariant", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathlimits", "Umathnoaxis", "Umathnolimits", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathnumeratorvariant", "Umathopenupdepth", "Umathopenupheight", "Umathoperatorsize", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervariant", "Umathoverdelimitervgap", "Umathoverlayaccentvariant", "Umathoverlinevariant", "Umathphantom", "Umathpresubshiftdistance", "Umathpresupshiftdistance", "Umathprimeraise", "Umathprimeraisecomposed", "Umathprimeshiftdrop", "Umathprimeshiftup", "Umathprimespaceafter", "Umathprimevariant", "Umathprimewidth", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalextensibleafter", "Umathradicalextensiblebefore", "Umathradicalkern", "Umathradicalrule", "Umathradicalvariant", "Umathradicalvgap", "Umathruledepth", "Umathruleheight", "Umathskeweddelimitertolerance", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathsource", "Umathspaceafterscript", "Umathspacebeforescript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvariant", "Umathstackvgap", "Umathsubscriptvariant", "Umathsubshiftdistance", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsuperscriptvariant", "Umathsupshiftdistance", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathtopaccentvariant", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervariant", "Umathunderdelimitervgap", "Umathunderlinevariant", "Umathuseaxis", "Umathvextensiblevariant", "Umathvoid", "Umathxscale", "Umathyscale", "Umiddle", "Unosubprescript", "Unosubscript", "Unosuperprescript", "Unosuperscript", "Uoperator", "Uover", "Uoverdelimiter", "Uoverwithdelims", "Uprimescript", "Uradical", "Uright", "Uroot", "Urooted", "Ushiftedsubprescript", "Ushiftedsubscript", "Ushiftedsuperprescript", "Ushiftedsuperscript", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustartmathmode", "Ustopdisplaymath", "Ustopmath", "Ustopmathmode", "Ustretched", "Ustretchedwithdelims", "Ustyle", "Usubprescript", "Usubscript", "Usuperprescript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "adjustspacingshrink", "adjustspacingstep", "adjustspacingstretch", "afterassigned", "aftergrouped", "aliased", "aligncontent", "alignmark", "alignmentcellsource", "alignmentwrapsource", "aligntab", "allcrampedstyles", "alldisplaystyles", "allmainstyles", "allmathstyles", "allscriptscriptstyles", "allscriptstyles", "allsplitstyles", "alltextstyles", "alluncrampedstyles", "allunsplitstyles", "amcode", "atendofgroup", "atendofgrouped", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenpenalty", "automigrationmode", "autoparagraphmode", "begincsname", "beginlocalcontrol", "beginmathgroup", "beginsimplegroup", "boundary", "boxadapt", "boxanchor", "boxanchors", "boxattribute", "boxdirection", "boxfreeze", "boxgeometry", "boxorientation", "boxrepack", "boxshift", "boxsource", "boxtarget", "boxtotal", "boxvadjust", "boxxmove", "boxxoffset", "boxymove", "boxyoffset", "catcodetable", "cdef", "cdefcsname", "cfcode", "clearmarks", "constant", "copymathatomrule", "copymathparent", "copymathspacing", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "csactive", "csstring", "currentloopiterator", "currentloopnesting", "currentmarks", "dbox", "defcsname", "detokenized", "dimensiondef", "dimexpression", "directlua", "dpack", "dsplit", "edefcsname", "efcode", "endlocalcontrol", "endmathgroup", "endsimplegroup", "enforced", "etoks", "etoksapp", "etokspre", "everybeforepar", "everymathatom", "everytab", "exceptionpenalty", "expand", "expandactive", "expandafterpars", "expandafterspaces", "expandcstoken", "expanded", "expandedafter", "expandedloop", "expandtoken", "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", "flushmarks", "fontcharta", "fontid", "fontmathcontrol", "fontspecdef", "fontspecid", "fontspecifiedname", "fontspecifiedsize", "fontspecscale", "fontspecxscale", "fontspecyscale", "fonttextcontrol", "formatname", "frozen", "futurecsname", "futuredef", "futureexpand", "futureexpandis", "futureexpandisap", "gdefcsname", "gleaders", "glet", "gletcsname", "glettonothing", "gluespecdef", "glyph", "glyphdatafield", "glyphoptions", "glyphscale", "glyphscriptfield", "glyphscriptscale", "glyphscriptscriptscale", "glyphstatefield", "glyphtextscale", "glyphxoffset", "glyphxscale", "glyphxscaled", "glyphyoffset", "glyphyscale", "glyphyscaled", "gtoksapp", "gtokspre", "hccode", "hjcode", "hmcode", "holdingmigrations", "hpack", "hyphenationmin", "hyphenationmode", "ifabsdim", "ifabsnum", "ifarguments", "ifboolean", "ifchkdim", "ifchkdimension", "ifchknum", "ifchknumber", "ifcmpdim", "ifcmpnum", "ifcondition", "ifcstok", "ifdimexpression", "ifdimval", "ifempty", "ifflags", "ifhaschar", "ifhastok", "ifhastoks", "ifhasxtoks", "ifincsname", "ifinsert", "ifmathparameter", "ifmathstyle", "ifnumexpression", "ifnumval", "ifparameter", "ifparameters", "ifrelax", "iftok", "ifzerodim", "ifzeronum", "ignorearguments", "ignoredepthcriterium", "ignorepars", "immediate", "immutable", "indexofcharacter", "indexofregister", "inherited", "initcatcodetable", "insertbox", "insertcopy", "insertdepth", "insertdistance", "insertheight", "insertheights", "insertlimit", "insertmaxdepth", "insertmode", "insertmultiplier", "insertpenalty", "insertprogress", "insertstorage", "insertstoring", "insertunbox", "insertuncopy", "insertwidth", "instance", "integerdef", "lastarguments", "lastatomclass", "lastboundary", "lastchkdim", "lastchknum", "lastleftclass", "lastloopiterator", "lastnamedcs", "lastnodesubtype", "lastpageextra", "lastparcontext", "lastrightclass", "leftmarginkern", "letcharcode", "letcsname", "letfrozen", "letmathatomrule", "letmathparent", "letmathspacing", "letprotected", "lettonothing", "linebreakcriterium", "linedirection", "localbrokenpenalty", "localcontrol", "localcontrolled", "localcontrolledloop", "localinterlinepenalty", "localleftbox", "localleftboxbox", "localmiddlebox", "localmiddleboxbox", "localrightbox", "localrightboxbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathaccent", "mathatom", "mathatomglue", "mathatomskip", "mathbackwardpenalties", "mathbeginclass", "mathbinary", "mathcheckfencesmode", "mathclose", "mathdictgroup", "mathdictproperties", "mathdirection", "mathdisplaymode", "mathdisplayskipmode", "mathdoublescriptmode", "mathendclass", "matheqnogapstep", "mathfenced", "mathfontcontrol", "mathforwardpenalties", "mathfraction", "mathghost", "mathgluemode", "mathgroupingmode", "mathinner", "mathleftclass", "mathlimitsmode", "mathmainstyle", "mathmiddle", "mathnolimitsmode", "mathopen", "mathoperator", "mathordinary", "mathoverline", "mathpenaltiesmode", "mathpunct", "mathradical", "mathrelation", "mathrightclass", "mathrulesfam", "mathrulesmode", "mathscale", "mathscriptsmode", "mathslackmode", "mathspacingmode", "mathstackstyle", "mathstyle", "mathstylefontid", "mathsurroundmode", "mathsurroundskip", "maththreshold", "mathunderline", "meaningasis", "meaningfull", "meaningless", "mugluespecdef", "mutable", "noaligned", "noatomruling", "noboundary", "nohrule", "norelax", "normalizelinemode", "normalizeparmode", "nospaces", "novrule", "numericscale", "numexpression", "orelse", "orphanpenalties", "orphanpenalty", "orunless", "outputbox", "overloaded", "overloadmode", "overshoot", "pageboundary", "pageextragoal", "pagevsize", "parametercount", "parametermark", "parattribute", "pardirection", "permanent", "pettymuskip", "postexhyphenchar", "posthyphenchar", "postinlinepenalty", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "preinlinepenalty", "prerelpenalty", "protrudechars", "protrusionboundary", "pxdimen", "quitloop", "quitvmode", "resetmathspacing", "retokenized", "rightmarginkern", "rpcode", "savecatcodetable", "scaledemwidth", "scaledexheight", "scaledextraspace", "scaledfontdimen", "scaledinterwordshrink", "scaledinterwordspace", "scaledinterwordstretch", "scaledmathstyle", "scaledslantperpoint", "scantextokens", "semiexpand", "semiexpanded", "semiprotected", "setdefaultmathcodes", "setfontid", "setmathatomrule", "setmathdisplaypostpenalty", "setmathdisplayprepenalty", "setmathignore", "setmathoptions", "setmathpostpenalty", "setmathprepenalty", "setmathspacing", "shapingpenaltiesmode", "shapingpenalty", "snapshotpar", "srule", "supmarkmode", "swapcsvalues", "tabsize", "textdirection", "thewithoutunit", "tinymuskip", "todimension", "tohexadecimal", "tointeger", "tokenized", "toksapp", "tokspre", "tolerant", "tomathstyle", "toscaled", "tosparsedimension", "tosparsescaled", "tpack", "tracingadjusts", "tracingalignments", "tracingexpressions", "tracingfonts", "tracingfullboxes", "tracinghyphenation", "tracinginserts", "tracinglevels", "tracinglists", "tracingmarks", "tracingmath", "tracingnodes", "tracingpenalties", "tsplit", "uleaders", "undent", "unexpandedloop", "unhpack", "unletfrozen", "unletprotected", "untraced", "unvpack", "variablefam", "virtualhrule", "virtualvrule", "vpack", "wordboundary", "wrapuppar", "xdefcsname", "xtoks", "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", "pdfomitinfodict", "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", "advanceby", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "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", "divideby", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "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", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "multiplyby", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillleftskip", "parfillskip", "parindent", "parinitleftskip", "parinitrightskip", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "shownodedetails", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "unboundary", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" }, + ["tex"]={ " ", "-", "/", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "advanceby", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "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", "divideby", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "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", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathcode", "mathop", "mathord", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "multiplyby", "muskip", "muskipdef", "newlinechar", "noalign", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillleftskip", "parfillskip", "parindent", "parinitleftskip", "parinitrightskip", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "radical", "raise", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "shownodedetails", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "unboundary", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "xdef", "xleaders", "xspaceskip", "year" }, ["xetex"]={ "XeTeXversion" }, }
\ No newline at end of file diff --git a/context/data/scite/context/scite-context-data-tex.properties b/context/data/scite/context/scite-context-data-tex.properties index 6db151de8..ecb3187f2 100644 --- a/context/data/scite/context/scite-context-data-tex.properties +++ b/context/data/scite/context/scite-context-data-tex.properties @@ -105,14 +105,16 @@ localleftboxbox localmiddlebox localmiddleboxbox localrightbox localrightboxbox lpcode luabytecode luabytecodecall luacopyinputnodes luadef \ luaescapestring luafunction luafunctioncall luatexbanner luatexrevision \ luatexversion mathaccent mathatom mathatomglue mathatomskip \ -mathbackwardpenalties mathbeginclass mathcheckfencesmode mathdictgroup mathdictproperties \ -mathdirection mathdisplaymode mathdisplayskipmode mathdoublescriptmode mathendclass \ -matheqnogapstep mathfenced mathfontcontrol mathforwardpenalties mathfraction \ -mathghost mathgluemode mathgroupingmode mathleftclass mathlimitsmode \ -mathmainstyle mathmiddle mathnolimitsmode mathpenaltiesmode mathradical \ -mathrightclass mathrulesfam mathrulesmode mathscale mathscriptsmode \ -mathslackmode mathspacingmode mathstackstyle mathstyle mathstylefontid \ -mathsurroundmode mathsurroundskip maththreshold meaningasis meaningfull \ +mathbackwardpenalties mathbeginclass mathbinary mathcheckfencesmode mathclose \ +mathdictgroup mathdictproperties mathdirection mathdisplaymode mathdisplayskipmode \ +mathdoublescriptmode mathendclass matheqnogapstep mathfenced mathfontcontrol \ +mathforwardpenalties mathfraction mathghost mathgluemode mathgroupingmode \ +mathinner mathleftclass mathlimitsmode mathmainstyle mathmiddle \ +mathnolimitsmode mathopen mathoperator mathordinary mathoverline \ +mathpenaltiesmode mathpunct mathradical mathrelation mathrightclass \ +mathrulesfam mathrulesmode mathscale mathscriptsmode mathslackmode \ +mathspacingmode mathstackstyle mathstyle mathstylefontid mathsurroundmode \ +mathsurroundskip maththreshold mathunderline meaningasis meaningfull \ meaningless mugluespecdef mutable noaligned noatomruling \ noboundary nohrule norelax normalizelinemode normalizeparmode \ nospaces novrule numericscale numexpression orelse \ @@ -136,8 +138,9 @@ tracingadjusts tracingalignments tracingexpressions tracingfonts tracingfullboxe tracinghyphenation tracinginserts tracinglevels tracinglists tracingmarks \ tracingmath tracingnodes tracingpenalties tsplit uleaders \ undent unexpandedloop unhpack unletfrozen unletprotected \ -untraced unvpack variablefam vpack wordboundary \ -wrapuppar xdefcsname xtoks xtoksapp xtokspre +untraced unvpack variablefam virtualhrule virtualvrule \ +vpack wordboundary wrapuppar xdefcsname xtoks \ +xtoksapp xtokspre keywordclass.tex.omega=\ Omegaminorversion Omegarevision Omegaversion @@ -200,39 +203,38 @@ lastbox lastkern lastpenalty lastskip lccode \ leaders left lefthyphenmin leftskip leqno \ let limits linepenalty lineskip lineskiplimit \ long looseness lower lowercase mark \ -mathbin mathchar mathchardef mathchoice mathclose \ -mathcode mathinner mathop mathopen mathord \ -mathpunct mathrel mathsurround maxdeadcycles maxdepth \ -meaning medmuskip message middle mkern \ -month moveleft moveright mskip multiply \ -multiplyby muskip muskipdef newlinechar noalign \ -noexpand noindent nolimits nonscript nonstopmode \ -nulldelimiterspace nullfont number omit or \ -outer output outputpenalty over overfullrule \ -overline overwithdelims pagedepth pagefilllstretch pagefillstretch \ -pagefilstretch pagegoal pageshrink pagestretch pagetotal \ -par parfillleftskip parfillskip parindent parinitleftskip \ -parinitrightskip parshape parskip patterns pausing \ -penalty postdisplaypenalty predisplaypenalty predisplaysize pretolerance \ -prevdepth prevgraf radical raise relax \ -relpenalty right righthyphenmin rightskip romannumeral \ -scriptfont scriptscriptfont scriptscriptstyle scriptspace scriptstyle \ -scrollmode setbox setlanguage sfcode shipout \ -show showbox showboxbreadth showboxdepth showlists \ -shownodedetails showthe skewchar skip skipdef \ -spacefactor spaceskip span splitbotmark splitfirstmark \ -splitmaxdepth splittopskip string tabskip textfont \ -textstyle the thickmuskip thinmuskip time \ -toks toksdef tolerance topmark topskip \ -tracingcommands tracinglostchars tracingmacros tracingonline tracingoutput \ -tracingpages tracingparagraphs tracingrestores tracingstats uccode \ -uchyph unboundary underline unhbox unhcopy \ -unkern unpenalty unskip unvbox unvcopy \ -uppercase vadjust valign vbadness vbox \ -vcenter vfil vfill vfilneg vfuzz \ -vrule vsize vskip vsplit vss \ -vtop wd widowpenalty xdef xleaders \ -xspaceskip year +mathbin mathchar mathchardef mathchoice mathcode \ +mathop mathord mathrel mathsurround maxdeadcycles \ +maxdepth meaning medmuskip message middle \ +mkern month moveleft moveright mskip \ +multiply multiplyby muskip muskipdef newlinechar \ +noalign noexpand noindent nolimits nonscript \ +nonstopmode nulldelimiterspace nullfont number omit \ +or outer output outputpenalty over \ +overfullrule overline overwithdelims pagedepth pagefilllstretch \ +pagefillstretch pagefilstretch pagegoal pageshrink pagestretch \ +pagetotal par parfillleftskip parfillskip parindent \ +parinitleftskip parinitrightskip parshape parskip patterns \ +pausing penalty postdisplaypenalty predisplaypenalty predisplaysize \ +pretolerance prevdepth prevgraf radical raise \ +relax relpenalty right righthyphenmin rightskip \ +romannumeral scriptfont scriptscriptfont scriptscriptstyle scriptspace \ +scriptstyle scrollmode setbox setlanguage sfcode \ +shipout show showbox showboxbreadth showboxdepth \ +showlists shownodedetails showthe skewchar skip \ +skipdef spacefactor spaceskip span splitbotmark \ +splitfirstmark splitmaxdepth splittopskip string tabskip \ +textfont textstyle the thickmuskip thinmuskip \ +time toks toksdef tolerance topmark \ +topskip tracingcommands tracinglostchars tracingmacros tracingonline \ +tracingoutput tracingpages tracingparagraphs tracingrestores tracingstats \ +uccode uchyph unboundary underline unhbox \ +unhcopy unkern unpenalty unskip unvbox \ +unvcopy uppercase vadjust valign vbadness \ +vbox vcenter vfil vfill vfilneg \ +vfuzz vrule vsize vskip vsplit \ +vss vtop wd widowpenalty xdef \ +xleaders xspaceskip year keywordclass.tex.xetex=\ XeTeXversion diff --git a/doc/context/sources/general/manuals/luametatex/luametatex.tex b/doc/context/sources/general/manuals/luametatex/luametatex.tex index 5b9844fdb..bb20761bc 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex.tex @@ -2,6 +2,9 @@ % \enabledirectives[backend.pdf.inmemory] +% \setupalign[profile] +% \enabletrackers[profiling.lines.show] + % ------------------------ ------ ------------------ ------------------------ % 2019-12-17 32bit 64bit 2020-01-10 32bit 64bit 2020-11-30 32bit 64bit % ------------------------ ------------------------ ------------------------ diff --git a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex index 498792c8c..b0921c70c 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex @@ -728,13 +728,12 @@ font.setfont(<number> n, <table> f) Note that at the moment, each access to the \type {font.fonts} or call to \type {font.getfont} creates a \LUA\ table for the whole font unless you cached it. -If you want a copy of the internal data you can use \type {font.copyfont}: \startfunctioncall -<table> f = font.copyfont(<number> n) +<table> f = font.getfont(<number> n) \stopfunctioncall -This one will return a table of the parameters as known to \TEX. These can be +So, this one will return a table of the parameters as known to \TEX. These can be different from the ones in the cached table: \startfunctioncall @@ -788,7 +787,7 @@ Within reasonable bounds you can extend a font after it has been defined. Becaus some properties are best left unchanged this is limited to adding characters. \startfunctioncall -font.addcharacters(<number n>, <table> f) +font.addcharacters(<number> n, <table> f) \stopfunctioncall The table passed can have the fields \type {characters} which is a (sub)table diff --git a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex index 72b32908d..a8247c1de 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex @@ -667,6 +667,7 @@ The configuration related registers have become: \edef\pdfomitcidset {\pdfvariable omitcidset} \edef\pdfomitcharset {\pdfvariable omitcharset} \edef\pdfomitinfodict {\pdfvariable omitinfodict} +\edef\pdfomitmediabox {\pdfvariable omitmediabox} \edef\pdfpagebox {\pdfvariable pagebox} \edef\pdfminorversion {\pdfvariable minorversion} \edef\pdfuniqueresname {\pdfvariable uniqueresname} @@ -917,6 +918,7 @@ The engine sets the following defaults. \pdfomitcidset 0 \pdfomitcharset 0 \pdfomitinfodict 0 +\pdfomitmediabox 0 \pdfpagebox 0 \pdfminorversion 4 \pdfuniqueresname 0 diff --git a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex index e8a1701a3..5f8c2582c 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex @@ -1250,9 +1250,9 @@ This converts a single type name to its internal numeric representation. \libindex {type} \libindex {subtype} -In the argument is a number, then the next function converts an internal numeric -representation to an external string representation. Otherwise, it will return -the string \type {node} if the object represents a node, and \type {nil} +In the argument is a number, then the \type {type} function converts an internal +numeric representation to an external string representation. Otherwise, it will +return the string \type {node} if the object represents a node, and \type {nil} otherwise. \startfunctioncall diff --git a/doc/context/sources/general/manuals/musings/musings-toocomplex.tex b/doc/context/sources/general/manuals/musings/musings-toocomplex.tex new file mode 100644 index 000000000..103dd1906 --- /dev/null +++ b/doc/context/sources/general/manuals/musings/musings-toocomplex.tex @@ -0,0 +1,389 @@ +% language=us runpath=texruns:manuals/musings + +\useMPlibrary[dum] + +% Extending Darwin's Revolution – David Sloan Wilson & Robert Sapolsky + +\startcomponent musings-toocomplex + +\environment musings-style + +\startchapter[title={False promises}] + +\startsection[title={Introduction}] + +\startlines \setupalign[flushright] +Hans Hagen +Hasselt NL +July 2019 (public 2023) +\stoplines + +The \TEX\ typesetting system is pretty powerful, and even more so when you +combine it with \METAPOST\ and \LUA. Add an \XML\ parser, a whole lot of handy +macros, provide support for fonts and advanced \PDF\ output and you have a hard +to beat tool. We're talking \CONTEXT. + +Such a system is very well suited for fully automated typesetting. There are +\TEX\ lovers who claim that \TEX\ can do anything better than the competition but +that's not true. Automated typesetting is quite doable when you accept the +constraints. When the input is unpredictable you need to play safe! + +Some things are easy: turning complex \XML\ into \PDF\ with adaptive graphics, +fast data processing, colorful layouts, conditional processing, extensive cross +referencing, you can safely say that it can be done. But in practice there is +some design involved and those are often specified by people who manipulate a +layout on the fly and tweak and cheat in an interactive \WYSIWYG\ program. That is +however not an option in automated typesetting. Traditional thinking with manual +intervention has to make place for systematic and consistent solutions. +Limitations can be compensated by clever designs and getting the maximum out of +the system used. + +Unfortunately in practice some habits are hard to get rid of. Inconsistent use of +colors, fonts, sectioning, image placements are just a few aspects that come to +mind. When you typeset educational documents you also have to deal with strong +opinions about how something should be presented and what students can't~(!) +handle, like for instance cross references. One of the most dominant demands in +typesetting such documents are so called side floats. In (for instance) +scientific publishing references to content typeset elsewhere (formulas, +graphics) is acceptable but in educational documents this is often not an option +(don't ask me why). + +In the next sections I will mention a few aspects of side floats. I will not +discuss the options because these are covered in manuals. Here we stick to the +challenges and the main question that you have to ask yourself is: \quotation +{How would I solve that if it can be solved at all?}. It might make you a bit +more tolerant for suboptimal outcome. + +\stopsection + +\startsection[title={The basics}] + +We start with a simple example. The result is shown in \in {figure} [demo-1a]. We +have figures, put at the left, with enough text alongside so that we don't have a +problem running into the next figure. + +\startbuffer[demo-1a] +\dorecurse {8} { + \useMPlibrary[dum] + \setuplayout[middle] + \setupbodyfont[plex] + \startplacefigure[location=left] + \externalfigure[dummy][width=3cm] + \stopplacefigure + \samplefile{sapolsky} + \par +} +\stopbuffer + +\typebuffer[demo-1a] + +\startplacefigure[reference=demo-1a,title={A simple example with enough text in a single paragraph.}] + \startcombination + {\typesetbuffer[demo-1a][width=5cm,frame=on,page=1]} {} + {\typesetbuffer[demo-1a][width=5cm,frame=on,page=2]} {} + \stopcombination +\stopplacefigure + +Challenge: Anchor some boxed material to the running text and make sure that the +text runs around that material. When there is not enough room available on the +page, enforce a page break and move the lot to the next page. + +But more often than not, the following paragraph is not long enough to go around +the insert. The worst case is of course when we end up with one word below the +insert, for which the solution is to adapt the text or make the insert wider or +narrower. Forgetting about this for now, we move to the case where there is not +enough text: \in {figure} [demo-1b]. + +\startbuffer[demo-1b] +\dorecurse {8} { + \useMPlibrary[dum] + \setuplayout[middle] + \setupbodyfont[plex] + \startplacefigure[location=left] + \externalfigure[dummy][width=3cm] + \stopplacefigure + \samplefile{ward} \par \samplefile{ward} + \par +} +\stopbuffer + +\typebuffer[demo-1b] + +\startplacefigure[reference=demo-1b,title={A simple example with enough text but multiple paragraphs.}] + \startcombination + {\typesetbuffer[demo-1b][width=5cm,frame=on,page=1]} {} + {\typesetbuffer[demo-1b][width=5cm,frame=on,page=2]} {} + \stopcombination +\stopplacefigure + +Challenge: At every new paragraph, check if we're still not done with the blob +we're typesetting around and carry on till we are behind the insert. + +\startbuffer[demo-1c] +\dorecurse {8} { + \useMPlibrary[dum] + \setuplayout[middle] + \setupbodyfont[plex] + \startplacefigure[location=left] + \externalfigure[dummy][width=3cm] + \stopplacefigure + \samplefile{ward} + \par +} +\stopbuffer + +The next example, shown in \in {figure} [demo-1c], has less text. However, the +running text is still alongside the figure, so this means that white space need +to be added till we're beyond. + +\typebuffer[demo-1c] + +\startplacefigure[reference=demo-1c,title={A simple example with less text}] + \startcombination + {\typesetbuffer[demo-1c][width=5cm,frame=on,page=1]} {} + {\typesetbuffer[demo-1c][width=5cm,frame=on,page=2]} {} + \stopcombination +\stopplacefigure + +Challenge: When there is not enough content, and the next insert is coming, we +add enough whitespace to go around the insert and then start the new one. This is +typically something that can also be enforced by an option. + +Before we move on to the next challenge, let's explain how we run around the +insert. When \TEX\ typesets a paragraph, it uses dimensions like \typ {\leftskip} +and \typ {\rightskip} (margins) and shape directives like \typ {\hangindent} and +\typ {\hangafter}. There is also the possibility to define a \typ {\parshape} but +we will leave that for now. The with of the image is reflected in the indent and +the height gets divided by the line height and becomes the \typ {\hangafter}. +Whenever a new paragraph is started, these parameters have to be set again. +\footnote {I still consider playing with a third parameter representing hang +height and add that to the line break routine, but I have to admit that tweaking +that is tricky. Do I really understand what is going on there?} In \CONTEXT\ +hanging is also available as basic feature. + +\startbuffer +\starthanging[location=left] + {\blackrule[color=maincolor,width=3cm,height=1cm]} + \samplefile{carrol} +\stophanging +\stopbuffer + +\typebuffer {\setupalign[tolerant,stretch]\getbuffer} + +\startbuffer +\starthanging[location=right] + {\blackrule[color=maincolor,width=10cm,height=1cm]} + \samplefile{jojomayer} +\stophanging +\stopbuffer + +\typebuffer {\setupalign[tolerant,stretch]\getbuffer} + +The hanging floats are not implemented this way but are hooked into the +paragraph start routines. The original approach was a variant of +the macros by Daniel Comenetz as published in TUGBoat Volume 14 (1993), +No.~1: Anchored Figures at Either Margin. In the meantime they are far +from that, so \CONTEXT\ users can safely blame me for any issues. + +\stopsection + +\startsection[title={Unpredictable dimensions}] + +In an ideal world images will be sort of consistent but in practice the dimension +will differ, even fonts used in graphics can be different, and they can have +white space around them. When testing a layout it helps to use mockups with a +clear border. If these look okay, one can argue that worse looking assemblies +(more visual whitespace above of below) is a matter of making better images. In +\in {figure} [demo-2a] we demonstrate how different dimensions influence the space +below the placement. + +\startbuffer[demo-2a] +\dostepwiserecurse {2} {8} {1} { + \useMPlibrary[dum] + \setuplayout[middle] + \setupbodyfont[plex] + \setupalign[tolerant,stretch] + \startplacefigure[location=left] + \externalfigure[dummy][width=#1cm] + \stopplacefigure + \samplefile{sapolsky} + \par +} +\stopbuffer + +\typebuffer[demo-2a] + +\startplacefigure[reference=demo-2a,title={Spacing relates to dimensions.}] + \startcombination[3*1] + {\typesetbuffer[demo-2a][width=5cm,frame=on,page=1]} {} + {\typesetbuffer[demo-2a][width=5cm,frame=on,page=2]} {} + {\typesetbuffer[demo-2a][width=5cm,frame=on,page=3]} {} + \stopcombination +\stopplacefigure + +In \CONTEXT\ there are plenty of options to add more space above or below the +image. You can anchor the image to the first line in different ways and you can +move it some lines down, either or not with text flowing around it. But here we +stick to simple cases, we only discuss the challenges. + +Challenge: Adapt the wrapping to the right dimensions and make sure that the +(optional) caption doesn't overlap with the text below. + +\stopsection + +\startsection[title={Moving forward}] + +When the insert doesn't fit it has to move, which is why it's called a float. One +solution is do take it out of the page stream and turn it into a regular +placement, normally centered horizontally somewhere on the page, and in this case +probably at the top of one of the next pages. Because we can cross reference this +is a quite okay solution. But, in educational documents, where authors refer to +the graphic (picture) on the left or right, that doesn't work out well. The +following content is bound to the image. + +Calculating the amount of available space is a bit tricky due to the way \TEX\ +works. But let's assume that this can be done, in \CONTEXT\ we have seen several +strategies for this, we then end up at the top of the next page and there +different spacing rules apply, like: no spacing at the top at all. In our +examples no whitespace between paragraphs is present. The final solutions are +complicated by the fact that we need to take this into account. + +Challenge: Make sure that we never run off the page but also that we +don't end up with weird situations at the top of the next page. + +Another possibility is that images so tightly fit a whole number of lines, that a +next one can come too close to a previous one. Again, this demands some analysis. +Here we use examples with captions but when there are no captions, there is also +less visual space (no depth in lines). + +Challenge: Make sure that a following insert never runs too close to a previous +insert. + +Solutions can be made better when we use multi|-|pass information. Because in a +typical \TEX\ run there is only looking back, storing information can actually +make us look forward. But, as in science fiction: when you act upon the future, +the past becomes different and therefore also the future (after that particular +future). This means that you can only go forward. Say you have 10 cases: when +case 5 changes because of some feedback, then case 6 upto 10 also can change. So, +you might need more than 10 runs to get things right. In a workflow where users +are waiting for a result, and a few hundred side floats are used this doesn't +sell well: processing 400 pages with a 20 page per second rate takes 20 seconds +per run. Normally one needs a few runs to get the references right. Assuming a +worst case of 60 seconds, 10 extra runs will bring you close to 15 minutes. No +deal. + +Of course one can argue for some load|-|in|-|memory and optimize in one go, but +although \TEX\ can do that well for paragraphs, it won't work for complex +documents. Sure, it's a nice academic exercise to explore limited cases but +those are not what we encounter. + +\stopsection + +\startsection[title={Cooperation}] + +When discussing (on YouTube) \quotation {Extending Darwin's Revolution} David +Sloan Wilson and Robert Sapolsky touch on the fact that in some disciplines (like +economics) evolutionary principles are applied. One can apply for instance the +concept of a \quote {selfish gene}. However, they argue that when doing that, one +actually lags behind the now accepted group selection (which goes beyond the +individual benefits). An example is given where aggressive behavior on the short +term can turn one in a winner (who takes it all) but which can lead to self +destructive in the long run: cooperating seems to works better than terminal +competition. + +In \TEX\ we have glues and penalties. The machinery likes to break at a glue but +a severe penalty can prohibit that. The fact that we have penalties and no +rewards is interesting: a break can be stimulated by a negative penalty. I've +forgotten most of what I learned about cognitive psychology but I do remember +that penalty vs reward discussions could get somewhat out of hand. + +So, when we have in the node list a mix of glue (you can break here), penalties +(better not break here) and rewards (consider breaking here) you can imagine that +these nodes compete. The optimal solution is not really a group process but +basically a rather selfish game. Building a system around that kind of +cooperation is not easy. In \CONTEXT\ a lot of attention always went into +consistent vertical spacing. In \MKII\ there were some \quote {look back} and +\quote {control forward} mechanisms in place, and in \MKIV\ we use a model of +weighted glue: a combination of penalties and skips. Again we look back and again +we also try to control the future. This works reasonable well but what if we end +up in a real competition? + +A section head should not end up at the bottom of a page. Because when it gets +typeset it is unknown what follows, it does some checking and then tries to make +sure that there is no page break following. Of course there needs to be a +provision for the cases that there are many (sub)heads and of course when there +are only heads on a page (in a concept for instance) you don't want to run of the +page. + +Similar situations arise with for instance itemized lists and the tabulate +mechanism. There we have some heuristics that keep content together in a way that +makes sense given the construct: no single table line at the bottom of a page +etc. But then comes the side float. The available space is checked. When doing +that the whitespace following the section head has to collapse with the space +around the image, but of course at the top of a page spacing is different. So, +calculations are done, but even a small difference between what is possible and +what is needed can eventually still trigger an unwanted page break. This is +because you cannot really ask how much has been accumulated so far: the space +used is influenced by what comes next (like whitespace, maybe interline space, +the previous depth correction, etc). That in turn means that you have to (sort +of) trigger these future space related items to be applied already. + +Challenge: Let the side float mechanism nicely cooperate with other mechanisms +that have their own preferences for crossing pages, adding whitespace and being +bound to following content. + +\stopsection + +\startsection[title={Easy bits}] + +Of course, once there is such a mechanism in place, user demands will trigger +more features. Most of these are actually not that hard to deal with: renumbering +due to moved content, automatic anchoring to the inner or outer margin, +horizontal placement and shifting into margins, etc. Everything that doesn't +relate to vertical placement is rather trivial to deal with, especially when the +whole infrastructure for that is already present (as in \CONTEXT). The problem +with such extensions is that one can easily forget what is possible because most +are rarely used. + +Challenge: Make sure that all fits into an understandable model and is easy to +control. + +\stopsection + +\startsection[title={Conclusion}] + +The side float mechanism in \CONTEXT\ is complex, has many low level options, and +its code doesn't look pretty. It is probably the mechanism that has been +overhauled and touched most in the code base. It is also the mechanism that +(still) can behave in ways you don't expect when combined with other mechanisms. +The way we deal with this (if needed) is to add directives to (in our case) \XML\ +files that tells the engine what to do. Because that is a last resort it is only +needed when making the final product. So in the end, we're still have the +benefits of automated typesetting. + +Of course we can come up with a different model (basically re|-|implement the +page builder) but apart from much else falling apart, it will just introduce +other constraints and side effects. Thinking in terms of selfish nodes, glues and +penalties, works ok for a specific document where one can also impose usage +rules. If you know that a section head is always followed by regular text, things +become easier. But in a system like \CONTEXT\ you need to update your thinking to +group selection: mechanisms have to work together and that can be pretty +complicated. Some mechanisms can do that better than others. One outcome can be +that for instance side floats are not really group players, so eventually they +might become less popular and fade away. Of course, as often, years later they +get rediscovered and the cycle starts again. Maybe a string argument can be made +that in fully automated typesetting concepts like side floats should not be used +anyway. + +If I have to summarize this wrap up, the conclusion is that we should be +realistic: we're not dealing with an expert system, but with a bunch of +heuristics. You need an intelligent system to help you out of deadlock and +oscillating solutions. Given the different preferences you need a multiple +personality system. You might actually need a system that wraps your expectations +and solutions and that adapts to changes in those over time. But if there is such +a system (some day) it probably doesn't need you. In fact, maybe even typesetting +is not needed any more by then. + +\stopsection + +\stopchapter diff --git a/doc/context/sources/general/manuals/musings/musings-whytex.tex b/doc/context/sources/general/manuals/musings/musings-whytex.tex index 6186c4a0f..97dc06285 100644 --- a/doc/context/sources/general/manuals/musings/musings-whytex.tex +++ b/doc/context/sources/general/manuals/musings/musings-whytex.tex @@ -6,6 +6,12 @@ \startchapter[title={Why use \TEX ?}] +\startlines \setupalign[flushright] +Hans Hagen +Hasselt NL +July 2021 (public 2023) +\stoplines + \startsection[title={Introduction}] Let's assume that you know what \TEX\ is: a program that interprets a language @@ -15,16 +21,17 @@ a button and get some typeset result in return. After a while you start tweaking this black box, meet other users (on the web), become more fluent and stick to it forever. -But now let's assume that you don't know \TEX\ and are in search of a system -that helps you create beautiful documents in an efficient way. When your -documents have a complex structure you are probably willing to spend some time on -figuring out what the best tool is. Even if a search lets you end up with -something called \TEX, a three letter word with a dropped E, you still don't -know what it is. Advertisement for \TEX\ is often pretty weak. It's rather easy -to point to the numerous documents that can be found on the web. But what exactly -does \TEX\ do and what are its benefits? In order to answer this we need to know -who you are: an author, editor, an organization that deals with documents or needs -to generate readable output, like publishers do. +But now let's assume that you don't know \TEX\ and are in search of a system that +helps you create beautiful documents in an efficient way. When your documents +have a complex structure you are probably willing to spend some time on figuring +out what the best tool is. Even if a search lets you end up with something called +\TEX, a three letter word with a dropped E, you still don't know what it is. It +helps to search for \type {\TeX} which is pronounced as \type {tech}. +Advertisement for \TEX\ is often pretty weak. It's rather easy to point to the +numerous documents that can be found on the web. But what exactly does \TEX\ do +and what are its benefits? In order to answer this we need to know who you are: +an author, editor, an organization that deals with documents or needs to generate +readable output, like publishers do. \stopsection @@ -37,7 +44,6 @@ by \TEX\ look great.} but they do advocate that for rendering math it is a prett good system. The source code of these documents often look rather messy and unattractive and for a non|-|math user it can be intimidating. Choosing some lightweight click|-|and|-|ping alternative looks attractive. -lightweight click|-|and|-|ping alternative looks attractive. Making \TEX\ popular is not going to happen by convincing those who have to write an occasional letter or report. They should just use whatever suits them. On the @@ -79,7 +85,7 @@ an obvious choice, but if you're a bit able to use it it's hard to beat in quality, flexibility and efficiency. I'm often surprised that companies are willing to pay a fortune for functionality that basically comes for free. Programmers are accustomed to running commands and working in a code editor with -syntax highlighting so that helps too. They too recognize when something can be +syntax highlighting so that helps too. They also recognize when something can be done more efficiently. When you need to go from some kind of input (document source, database, @@ -222,17 +228,17 @@ philosophy and we like the community. It is actually not really giving us an advantage commercially: it costs way more to develop, support and keep up|-|to|-|date than it will ever return. We can come up with better, faster and easier solutions and in the end we pay the price because it takes less time to -cook up styles. So there is some backslash involved because commercially a +cook up styles. So there is some back slash involved because commercially a difficult solution leads to more billable hours. Luckily we tend to avoid wasting time so we improve when possible and then it ends up in the distributed code. And, once the solution is there, anyone can use it. Basically also for us it's -just a tool, like the operating system, editor and viewer are. So, what keep +just a tool, like the operating system, editor and viewer are. So, what keeps development going is mostly the interaction with the community. This also means -that a customer can't really demand functionality for free: either wait for it to -show up or pay for it (which seldom happens). Open source is not equivalent with -\quotation {You get immediately what you want because someone out there writes -the code.}. There has to be a valid reason and often it's just users and meetings -or just some challenge that drives it. +that a customer can't really demand functionality for free: either do it +yourself, wait for it to show up, or pay for it (which seldom happens). Open +source is not equivalent with \quotation {You get immediately what you want +because someone out there writes the code.}. There has to be a valid reason and +often it's just users and meetings or just some challenge that drives it. This being said, it is hard to convince a company to use \TEX. It has to come from users in the organization. Or, what we sometimes see with publishers, it @@ -307,17 +313,18 @@ message. The \TEX\ ecosystem was among the first in supporting for instance \OPENTYPE, and the community even made sure that there were free fonts available. A format like -\PDF\ was supported as soon as it shows up and \TEX\ was the first to demonstrate -what advanced features were there and how way it was to adapt to changes. -Processing \XML\ using \TEX\ has never been a big deal and if that is a reason to -look at this already old and mature technology, then an organization can wonder -if years and opportunities (for instance for publishing on demand or easy -updating of manuals) have been lost. Of course there are (and have been) -alternative tools but the arguments for using \TEX\ or not are not much different -now. It can be bad marketing of open and free software. It can be that \TEX\ has -been around too long. It can also be that its message was not understood yet. On -the other hand, in software development it's quite common to reinvent wheels and -present old as new. It's never to late to catch on. +\PDF\ was supported as soon as it showed up and \TEX\ was the first to +demonstrate what advanced features were there and it shows again how it is +possible to adapt \TEX\ to changes in its environment. Processing \XML\ using +\TEX\ has never been a big deal and if that is a reason to look at this already +old and mature technology, then an organization can wonder if years and +opportunities (for instance for publishing on demand or easy updating of manuals) +have been lost. Of course there are (and have been) alternative tools but the +arguments for using \TEX\ or not are not much different now. It can be bad +marketing of open and free software. It can be that \TEX\ has been around too +long. It can also be that its message was not understood yet. On the other hand, +in software development it's quite common to reinvent wheels and present old as +new. It's never too late to catch on. \stopsection diff --git a/doc/context/sources/general/manuals/musings/musings.tex b/doc/context/sources/general/manuals/musings/musings.tex index 3e3b35ea0..13bf4f4ef 100644 --- a/doc/context/sources/general/manuals/musings/musings.tex +++ b/doc/context/sources/general/manuals/musings/musings.tex @@ -20,14 +20,14 @@ \component musings-roadmap \component musings-names \component musings-plain - % \component musings-toocomplex + \component musings-toocomplex % \component musings-manuals - % \component musings-performance + \component musings-performance % \component musings-history % \component musings-treasures % \component musings-whytex-again \component musings-dontusetex - % \component musings-speed + \component musings-speed \stopbodymatter \stopproduct diff --git a/source/luametatex/source/libraries/miniz/miniz.c b/source/luametatex/source/libraries/miniz/miniz.c index c197c181c..8d0032f9e 100644 --- a/source/luametatex/source/libraries/miniz/miniz.c +++ b/source/luametatex/source/libraries/miniz/miniz.c @@ -3068,7 +3068,7 @@ static WCHAR* mz_utf8z_to_widechar(const char* str) { int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); WCHAR* wStr = (WCHAR*)malloc(reqChars * sizeof(WCHAR)); - MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, sizeof(WCHAR) * reqChars); + MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars); return wStr; } diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h index f5fd10900..c3ea2a184 100644 --- a/source/luametatex/source/lua/lmtinterface.h +++ b/source/luametatex/source/lua/lmtinterface.h @@ -488,18 +488,7 @@ make_lua_key(L, bend_tolerance);\ make_lua_key(L, bestinsert);\ make_lua_key(L, bestpagebreak);\ make_lua_key(L, bestsize);\ -make_lua_key(L, bin);\ -make_lua_key(L, binbinspacing);\ -make_lua_key(L, binclosespacing);\ -make_lua_key(L, binfracspacing);\ -make_lua_key(L, bininnerspacing);\ -make_lua_key(L, binmiddlespacing);\ -make_lua_key(L, binopenspacing);\ -make_lua_key(L, binopspacing);\ -make_lua_key(L, binordspacing);\ -make_lua_key(L, binpunctspacing);\ -make_lua_key(L, binradspacing);\ -make_lua_key(L, binrelspacing);\ +make_lua_key(L, binary);\ make_lua_key(L, boolean);\ make_lua_key(L, bothflexible);\ make_lua_key(L, bottom);\ @@ -536,17 +525,6 @@ make_lua_key(L, choice);\ make_lua_key(L, class);\ make_lua_key(L, cleaders);\ make_lua_key(L, close);\ -make_lua_key(L, closebinspacing);\ -make_lua_key(L, closeclosespacing);\ -make_lua_key(L, closefracspacing);\ -make_lua_key(L, closeinnerspacing);\ -make_lua_key(L, closemiddlespacing);\ -make_lua_key(L, closeopenspacing);\ -make_lua_key(L, closeopspacing);\ -make_lua_key(L, closeordspacing);\ -make_lua_key(L, closepunctspacing);\ -make_lua_key(L, closeradspacing);\ -make_lua_key(L, closerelspacing);\ make_lua_key(L, clubpenalties);\ make_lua_key(L, clubpenalty);\ make_lua_key(L, cmd);\ @@ -697,17 +675,6 @@ make_lua_key(L, force);\ make_lua_key(L, forcecheck);\ make_lua_key(L, forcehandler);\ make_lua_key(L, forcerulethickness);\ -make_lua_key(L, fracbinspacing);\ -make_lua_key(L, fracclosespacing);\ -make_lua_key(L, fracfracspacing);\ -make_lua_key(L, fracinnerspacing);\ -make_lua_key(L, fracmiddlespacing);\ -make_lua_key(L, fracopenspacing);\ -make_lua_key(L, fracopspacing);\ -make_lua_key(L, fracordspacing);\ -make_lua_key(L, fracpunctspacing);\ -make_lua_key(L, fracradspacing);\ -make_lua_key(L, fracrelspacing);\ make_lua_key(L, fraction);\ make_lua_key(L, FractionDelimiterDisplayStyleSize);\ make_lua_key(L, FractionDelimiterSize);\ @@ -782,18 +749,7 @@ make_lua_key(L, index);\ make_lua_key(L, info);\ make_lua_key(L, Info);\ make_lua_key(L, inner);\ -make_lua_key(L, innerbinspacing);\ -make_lua_key(L, innerclosespacing);\ -make_lua_key(L, innerfracspacing);\ -make_lua_key(L, innerinnerspacing);\ make_lua_key(L, innerlocation);\ -make_lua_key(L, innermiddlespacing);\ -make_lua_key(L, inneropenspacing);\ -make_lua_key(L, inneropspacing);\ -make_lua_key(L, innerordspacing);\ -make_lua_key(L, innerpunctspacing);\ -make_lua_key(L, innerradspacing);\ -make_lua_key(L, innerrelspacing);\ make_lua_key(L, innerxoffset);\ make_lua_key(L, inneryoffset);\ make_lua_key(L, input);\ @@ -931,18 +887,7 @@ make_lua_key(L, mathtextchar);\ make_lua_key(L, medmuskip);\ make_lua_key(L, message);\ make_lua_key(L, middle);\ -make_lua_key(L, middlebinspacing);\ make_lua_key(L, middlebox);\ -make_lua_key(L, middleclosespacing);\ -make_lua_key(L, middlefracspacing);\ -make_lua_key(L, middleinnerspacing);\ -make_lua_key(L, middlemiddlespacing);\ -make_lua_key(L, middleopenspacing);\ -make_lua_key(L, middleopspacing);\ -make_lua_key(L, middleordspacing);\ -make_lua_key(L, middlepunctspacing);\ -make_lua_key(L, middleradspacing);\ -make_lua_key(L, middlerelspacing);\ make_lua_key(L, MinConnectorOverlap);\ make_lua_key(L, mirror);\ make_lua_key(L, mkern);\ @@ -991,47 +936,13 @@ make_lua_key(L, nucleus);\ make_lua_key(L, number);\ make_lua_key(L, numerator);\ make_lua_key(L, numeratorvariant);\ -make_lua_key(L, op);\ -make_lua_key(L, opbinspacing);\ -make_lua_key(L, opclosespacing);\ make_lua_key(L, open);\ -make_lua_key(L, openbinspacing);\ -make_lua_key(L, openclosespacing);\ -make_lua_key(L, openfracspacing);\ -make_lua_key(L, openinnerspacing);\ -make_lua_key(L, openmiddlespacing);\ -make_lua_key(L, openopenspacing);\ -make_lua_key(L, openopspacing);\ -make_lua_key(L, openordspacing);\ -make_lua_key(L, openpunctspacing);\ -make_lua_key(L, openradspacing);\ -make_lua_key(L, openrelspacing);\ make_lua_key(L, openupdepth);\ make_lua_key(L, openupheight);\ make_lua_key(L, operator);\ make_lua_key(L, operatorsize);\ -make_lua_key(L, opfracspacing);\ -make_lua_key(L, opinnerspacing);\ -make_lua_key(L, opmiddlespacing);\ -make_lua_key(L, opopenspacing);\ -make_lua_key(L, opopspacing);\ -make_lua_key(L, opordspacing);\ -make_lua_key(L, oppunctspacing);\ -make_lua_key(L, opradspacing);\ -make_lua_key(L, oprelspacing);\ make_lua_key(L, options);\ -make_lua_key(L, ord);\ -make_lua_key(L, ordbinspacing);\ -make_lua_key(L, ordclosespacing);\ -make_lua_key(L, ordfracspacing);\ -make_lua_key(L, ordinnerspacing);\ -make_lua_key(L, ordmiddlespacing);\ -make_lua_key(L, ordopenspacing);\ -make_lua_key(L, ordopspacing);\ -make_lua_key(L, ordordspacing);\ -make_lua_key(L, ordpunctspacing);\ -make_lua_key(L, ordradspacing);\ -make_lua_key(L, ordrelspacing);\ +make_lua_key(L, ordinary);\ make_lua_key(L, orientation);\ make_lua_key(L, original);\ make_lua_key(L, orphanpenalties);\ @@ -1134,22 +1045,8 @@ make_lua_key(L, semi_protected_call);\ make_lua_key(L, protrudechars);\ make_lua_key(L, protrusion);\ make_lua_key(L, ptr);\ -make_lua_key(L, punct);\ -make_lua_key(L, punctbinspacing);\ -make_lua_key(L, punctclosespacing);\ -make_lua_key(L, punctfracspacing);\ -make_lua_key(L, punctinnerspacing);\ -make_lua_key(L, punctmiddlespacing);\ -make_lua_key(L, punctopenspacing);\ -make_lua_key(L, punctopspacing);\ -make_lua_key(L, punctordspacing);\ -make_lua_key(L, punctpunctspacing);\ -make_lua_key(L, punctradspacing);\ -make_lua_key(L, punctrelspacing);\ +make_lua_key(L, punctuation);\ make_lua_key(L, quad);\ -make_lua_key(L, radbinspacing);\ -make_lua_key(L, radclosespacing);\ -make_lua_key(L, radfracspacing);\ make_lua_key(L, radical);\ make_lua_key(L, radicaldegreeafter);\ make_lua_key(L, radicaldegreebefore);\ @@ -1169,14 +1066,6 @@ make_lua_key(L, RadicalRuleThickness);\ make_lua_key(L, radicalvariant);\ make_lua_key(L, RadicalVerticalGap);\ make_lua_key(L, radicalvgap);\ -make_lua_key(L, radinnerspacing);\ -make_lua_key(L, radmiddlespacing);\ -make_lua_key(L, radopenspacing);\ -make_lua_key(L, radopspacing);\ -make_lua_key(L, radordspacing);\ -make_lua_key(L, radpunctspacing);\ -make_lua_key(L, radradspacing);\ -make_lua_key(L, radrelspacing);\ make_lua_key(L, reader);\ make_lua_key(L, register);\ make_lua_key(L, register_attribute);\ @@ -1198,19 +1087,8 @@ make_lua_key(L, registergluespec);\ make_lua_key(L, registerinteger);\ make_lua_key(L, registermugluespec);\ make_lua_key(L, regular);\ -make_lua_key(L, rel);\ +make_lua_key(L, relation);\ make_lua_key(L, relax);\ -make_lua_key(L, relbinspacing);\ -make_lua_key(L, relclosespacing);\ -make_lua_key(L, relfracspacing);\ -make_lua_key(L, relinnerspacing);\ -make_lua_key(L, relmiddlespacing);\ -make_lua_key(L, relopenspacing);\ -make_lua_key(L, relopspacing);\ -make_lua_key(L, relordspacing);\ -make_lua_key(L, relpunctspacing);\ -make_lua_key(L, relradspacing);\ -make_lua_key(L, relrelspacing);\ make_lua_key(L, remove_item);\ make_lua_key(L, repeat);\ make_lua_key(L, replace);\ @@ -1450,6 +1328,7 @@ make_lua_key(L, vertical);\ make_lua_key(L, verticalmathkern);\ make_lua_key(L, vextensible);\ make_lua_key(L, vextensiblevariant);\ +make_lua_key(L, virtual);\ make_lua_key(L, vlist);\ make_lua_key(L, vmode);\ make_lua_key(L, vmodepar);\ diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index 116860f85..6a07e3454 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -2902,6 +2902,27 @@ static int nodelib_direct_getlistdimensions(lua_State *L) return 0; } +static int nodelib_direct_getruledimensions(lua_State *L) +{ + halfword n = nodelib_valid_direct_from_index(L, 1); + if (n && node_type(n) == rule_node) { + if (node_subtype(n) == virtual_rule_subtype) { + lua_pushinteger(L, rule_data(n)); + lua_pushinteger(L, rule_left(n)); + lua_pushinteger(L, rule_right(n)); + lua_pushboolean(L, 1); + } else { + lua_pushinteger(L, rule_width(n)); + lua_pushinteger(L, rule_height(n)); + lua_pushinteger(L, rule_depth(n)); + lua_pushboolean(L, 0); + } + return 4; + } else { + return 0; + } +} + /* node.direct.getlist */ static int nodelib_direct_getlist(lua_State *L) @@ -3541,32 +3562,45 @@ static int nodelib_direct_setlink(lua_State *L) and the nodes themselves can have old values for prev and next, so ... only single nodes are looked at! */ - if (lua_type(L, i) == LUA_TNUMBER) { - halfword c = nodelib_valid_direct_from_index(L, i); /* current node */ - if (c) { - if (c != t) { - if (t) { - node_next(t) = c; - node_prev(c) = t; - } else if (i > 1) { - /* we assume that the first node is a kind of head */ - node_prev(c) = null; - } - t = c; - if (! h) { - h = t; + switch (lua_type(L, i)) { + case LUA_TNUMBER: + { + halfword c = nodelib_valid_direct_from_index(L, i); /* current node */ + if (c) { + if (c != t) { + if (t) { + node_next(t) = c; + node_prev(c) = t; + } else if (i > 1) { + /* we assume that the first node is a kind of head */ + node_prev(c) = null; + } + t = c; + if (! h) { + h = t; + } + } else { + /* we ignore duplicate nodes which can be tails or the previous */ + } + } else { + /* we ignore bad nodes, but we could issue a message */ } - } else { - /* we ignore duplicate nodes which can be tails or the previous */ } - } else { - /* we ignore bad nodes, but we could issue a message */ - } - } else if (t) { - /* safeguard: a nil in the list can be meant as end so we nil the next of tail */ - node_next(t) = null; - } else { - /* we just ignore nil nodes and have no tail yet */ + break; + case LUA_TBOOLEAN: + if (lua_toboolean(L, i)) { + /*tex Just skip this one. */ + break; + } else { + /* fall through */ + } + default: + if (t) { + /* safeguard: a nil in the list can be meant as end so we nil the next of tail */ + node_next(t) = null; + } else { + /* we just ignore nil nodes and have no tail yet */ + } } } nodelib_push_direct_or_nil(L, h); @@ -9758,7 +9792,8 @@ static const struct luaL_Reg nodelib_direct_function_list[] = { { "rangedimensions", nodelib_direct_rangedimensions }, /* maybe get... */ { "getglyphdimensions", nodelib_direct_getglyphdimensions }, { "getkerndimension", nodelib_direct_getkerndimension }, - { "getlistdimensions", nodelib_direct_getlistdimensions }, + { "getlistdimensions", nodelib_direct_getlistdimensions }, + { "getruledimensions", nodelib_direct_getruledimensions }, { "patchattributes", nodelib_direct_patchattributes }, { "remove", nodelib_direct_remove }, { "removefromlist", nodelib_direct_remove_from_list }, diff --git a/source/luametatex/source/luarest/lmtoslibext.c b/source/luametatex/source/luarest/lmtoslibext.c index 0dc5fb940..e49edd5a5 100644 --- a/source/luametatex/source/luarest/lmtoslibext.c +++ b/source/luametatex/source/luarest/lmtoslibext.c @@ -115,15 +115,21 @@ static int oslib_sleep(lua_State *L) osver.dwOSVersionInfoSize = sizeof(osver); GetSystemInfo(&sysinfo); strcpy(uts->sysname, "Windows"); - /* When |GetVersionEx| becomes obsolete the version and release fields will be set to "". */ - GetVersionEx(&osver); - sprintf(uts->version, "%ld.%02ld", osver.dwMajorVersion, osver.dwMinorVersion); - if (osver.szCSDVersion[0] != '\0' && (strlen(osver.szCSDVersion) + strlen(uts->version) + 1) < sizeof(uts->version)) { - strcat(uts->version, " "); - strcat(uts->version, osver.szCSDVersion); - } - sprintf(uts->release, "build %ld", osver.dwBuildNumber & 0xFFFF); - /* So far for the fragile and actually not that relevant part of |uts|. */ + /*tex When |GetVersionEx| becomes obsolete the version and release fields will be set to "". */ + // if (0) { + // GetVersionEx(&osver); + // sprintf(uts->version, "%ld.%02ld", osver.dwMajorVersion, osver.dwMinorVersion); + // if (osver.szCSDVersion[0] != '\0' && (strlen(osver.szCSDVersion) + strlen(uts->version) + 1) < sizeof(uts->version)) { + // strcat(uts->version, " "); + // strcat(uts->version, osver.szCSDVersion); + // } + // sprintf(uts->release, "build %ld", osver.dwBuildNumber & 0xFFFF); + // } else { + /*tex I can't motivate myself to figure this out. */ + strcpy(uts->version, ""); + strcpy(uts->release, ""); + // } + /*tex So far for the fragile and actually not that relevant part of |uts|. */ switch (sysinfo.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_AMD64: strcpy(uts->machine, "x86_64"); diff --git a/source/luametatex/source/mp/mpc/mp.c b/source/luametatex/source/mp/mpc/mp.c index d171e07a6..2d0320868 100644 --- a/source/luametatex/source/mp/mpc/mp.c +++ b/source/luametatex/source/mp/mpc/mp.c @@ -9028,11 +9028,21 @@ static mp_knot mp_path_intersection(MP mp, mp_knot h, mp_knot hh, int path, mp_k number_add(nn, unity_t); ll = pp; pp = mp_next_knot(pp); +if (pp != hh && mp_knotstate(pp) == mp_end_knot) { + number_add(nn, unity_t); + ll = pp; + pp = mp_next_knot(pp); +} } while (pp != hh); } number_add(n, unity_t); l = p; p = mp_next_knot(p); +if (p != hh && mp_knotstate(p) == mp_end_knot) { + number_add(n, unity_t); + l = p; + p = mp_next_knot(p); +} } while (p != h); mp->tol_step = mp->tol_step + 3; if (done) { diff --git a/source/luametatex/source/mp/mpw/mp.w b/source/luametatex/source/mp/mpw/mp.w index 5fb24250c..f4bdb58ca 100644 --- a/source/luametatex/source/mp/mpw/mp.w +++ b/source/luametatex/source/mp/mpw/mp.w @@ -13827,11 +13827,25 @@ static mp_knot mp_path_intersection(MP mp, mp_knot h, mp_knot hh, int path, mp_k number_add(nn, unity_t); ll = pp; pp = mp_next_knot(pp); +/* begin experiment HH/MS, maybe a loop */ +if (pp != hh && mp_knotstate(pp) == mp_end_knot) { + number_add(nn, unity_t); + ll = pp; + pp = mp_next_knot(pp); +} +/* end experiment HH/MS */ } while (pp != hh); } number_add(n, unity_t); l = p; p = mp_next_knot(p); +/* begin experiment HH/MS, maybe a loop */ +if (p != hh && mp_knotstate(p) == mp_end_knot) { + number_add(n, unity_t); + l = p; + p = mp_next_knot(p); +} +/* end experiment HH/MS */ } while (p != h); mp->tol_step = mp->tol_step + 3; if (done) { diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 03bcc34d1..13357a141 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -495,10 +495,12 @@ void tex_initialize_commands(void) tex_primitive(tex_command, "vrule", vrule_cmd, normal_rule_code, 0); tex_primitive(luatex_command, "novrule", vrule_cmd, empty_rule_code, 0); + tex_primitive(luatex_command, "virtualvrule", vrule_cmd, virtual_rule_code, 0); tex_primitive(luatex_command, "srule", vrule_cmd, strut_rule_code, 0); tex_primitive(tex_command, "hrule", hrule_cmd, normal_rule_code, 0); tex_primitive(luatex_command, "nohrule", hrule_cmd, empty_rule_code, 0); + tex_primitive(luatex_command, "virtualhrule", hrule_cmd, virtual_rule_code, 0); tex_primitive(tex_command, "count", register_cmd, int_val_level, 0); tex_primitive(luatex_command, "attribute", register_cmd, attr_val_level, 0); diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index a9f1a3ed9..4979c1a23 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -1691,20 +1691,27 @@ int tex_check_active_math_char(int character) case alignment_tab_cmd: case superscript_cmd: case subscript_cmd: - cur_cmd = code; - cur_chr = character; - cur_tok = token_val(cur_cmd, cur_chr); - if (tracing_commands_par >= 4) { - tex_aux_report_active(4, "control", code, character); - } - return 1; case letter_cmd: case other_char_cmd: + case active_char_cmd: cur_cmd = code; cur_chr = character; cur_tok = token_val(cur_cmd, cur_chr); if (tracing_commands_par >= 4) { - tex_aux_report_active(4, "inject", code, character); + switch (code) { + case alignment_tab_cmd: + case superscript_cmd: + case subscript_cmd: + tex_aux_report_active(4, "control", code, character); + break; + case letter_cmd: + case other_char_cmd: + tex_aux_report_active(4, "inject", code, character); + break; + case active_char_cmd: + tex_aux_report_active(4, "active", code, character); + break; + } } return 1; default: @@ -1754,6 +1761,21 @@ static int tex_aux_scan_active_math_char(mathcodeval *mval, int where) tex_aux_report_active(where, "inject", code, character); } return 0; + case active_char_cmd: + /*tex + We reset the code so that we don't get a loop, whuich means that the macro that + gets invoked has to set the amcode again if needed. + */ + tex_set_am_code(character, other_char_cmd, 0); + cur_cs = tex_active_to_cs(cur_chr, 1); + cur_cmd = eq_type(cur_cs); + cur_chr = eq_value(cur_cs); + tex_x_token(); + tex_back_input(cur_tok); + if (tracing_commands_par >= 4) { + tex_aux_report_active(where, "active", code, character); + } + return 1; default: if (tracing_commands_par >= 4) { tex_aux_report_active(where, "ignore", code, character); @@ -1761,6 +1783,7 @@ static int tex_aux_scan_active_math_char(mathcodeval *mval, int where) return 1; } } else if (mval->class_value == active_math_class_value) { + /*tex We might eventually drop tthis feature in favor of the amcode. */ cur_cs = tex_active_to_cs(cur_chr, 1); cur_cmd = eq_type(cur_cs); cur_chr = eq_value(cur_cs); diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 79ab490e7..b3f8cf294 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -1326,14 +1326,14 @@ static halfword register_extensible(halfword fnt, halfword chr, int size, halfwo { int callback_id = lmt_callback_defined(register_extensible_callback); if (callback_id > 0) { - halfword b = null; - lmt_run_callback(lmt_lua_state.lua_instance, callback_id, "dddN->N", fnt, chr, size, result, &b); - if (b) { - switch (node_type(b)) { + halfword boxed = null; + lmt_run_callback(lmt_lua_state.lua_instance, callback_id, "dddN->N", fnt, chr, size, result, &boxed); + if (boxed) { + switch (node_type(boxed)) { case hlist_node: case vlist_node: - tex_attach_attribute_list_attribute(b, att); - return b; + tex_attach_attribute_list_attribute(boxed, att); /* yes or no */ + return boxed; default: tex_formatted_error("fonts", "invalid extensible character %U registered for font %F, [h|v]list expected", chr, fnt); break; @@ -1425,10 +1425,12 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int goto FOUND; } } - if (tex_char_has_tag_from_font(curfnt, curchr, extensible_tag)) { - fnt = curfnt; - chr = curchr; - do_parts = 1; + if (tex_char_has_tag_from_font(curfnt, curchr, extensible_tag)) { + if (flat ? tex_char_has_tag_from_font(curfnt, curchr, horizontal_tag) : tex_char_has_tag_from_font(curfnt, curchr, vertical_tag)) { + fnt = curfnt; + chr = curchr; + do_parts = 1; + } goto FOUND; } else if (count > 1000) { tex_formatted_warning("fonts", "endless loop in extensible character %U of font %F", curchr, curfnt); @@ -2142,7 +2144,6 @@ static void tex_aux_make_over(halfword target, halfword style, halfword size, ha extensibles. The order is: kern, rule, gap, content. */ - halfword result; scaled thickness = tex_get_math_y_parameter_checked(style, math_parameter_overbar_rule); scaled vgap = tex_get_math_y_parameter_checked(style, math_parameter_overbar_vgap); scaled kern = tex_get_math_y_parameter_checked(style, math_parameter_overbar_kern); @@ -2152,14 +2153,16 @@ static void tex_aux_make_over(halfword target, halfword style, halfword size, ha thickness = t; } } - result = tex_aux_overbar( - tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_over_line_variant), style, math_nucleus_list, 0, NULL), - vgap, thickness, kern, - get_attribute_list(noad_nucleus(target)), math_over_rule_subtype, size, fam - ); - node_subtype(result) = math_over_list; - kernel_math_list(noad_nucleus(target)) = result; - node_type(noad_nucleus(target)) = sub_box_node; + { + halfword result = tex_aux_overbar( + tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_over_line_variant), style, math_nucleus_list, 0, NULL), + vgap, thickness, kern, + get_attribute_list(noad_nucleus(target)), math_over_rule_subtype, size, fam + ); + node_subtype(result) = math_over_list; + kernel_math_list(noad_nucleus(target)) = result; + node_type(noad_nucleus(target)) = sub_box_node; + } } static void tex_aux_make_under(halfword target, halfword style, halfword size, halfword fam) @@ -2171,7 +2174,6 @@ static void tex_aux_make_under(halfword target, halfword style, halfword size, h rule, kern. */ - halfword result; scaled thickness = tex_get_math_y_parameter_checked(style, math_parameter_underbar_rule); scaled vgap = tex_get_math_y_parameter_checked(style, math_parameter_underbar_vgap); scaled kern = tex_get_math_y_parameter_checked(style, math_parameter_underbar_kern); @@ -2181,14 +2183,16 @@ static void tex_aux_make_under(halfword target, halfword style, halfword size, h thickness = t; } } - result = tex_aux_underbar( - tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_under_line_variant), style, math_nucleus_list, 0, NULL), - vgap, thickness, kern, - get_attribute_list(noad_nucleus(target)), math_under_rule_subtype, size, fam - ); - node_subtype(result) = math_over_list; - kernel_math_list(noad_nucleus(target)) = result; - node_type(noad_nucleus(target)) = sub_box_node; + { + halfword result = tex_aux_underbar( + tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_under_line_variant), style, math_nucleus_list, 0, NULL), + vgap, thickness, kern, + get_attribute_list(noad_nucleus(target)), math_under_rule_subtype, size, fam + ); + node_subtype(result) = math_over_list; + kernel_math_list(noad_nucleus(target)) = result; + node_type(noad_nucleus(target)) = sub_box_node; + } } /*tex diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index 27b9520e3..625a4346b 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -204,6 +204,7 @@ void lmt_nodelib_initialize(void) { set_value_entry_key(subtypes_rule, math_radical_rule_subtype, radical) set_value_entry_key(subtypes_rule, box_rule_subtype, box) set_value_entry_key(subtypes_rule, image_rule_subtype, image) + set_value_entry_key(subtypes_rule, virtual_rule_subtype, virtual) subtypes_glyph = lmt_aux_allocate_value_info(glyph_math_accent_subtype); @@ -212,13 +213,13 @@ void lmt_nodelib_initialize(void) { set_value_entry_key(subtypes_glyph, glyph_ligature_subtype, ligature) set_value_entry_key(subtypes_glyph, glyph_math_delimiter_subtype, delimiter); set_value_entry_key(subtypes_glyph, glyph_math_extensible_subtype, extensible); - set_value_entry_key(subtypes_glyph, glyph_math_ordinary_subtype, ord); - set_value_entry_key(subtypes_glyph, glyph_math_operator_subtype, op); - set_value_entry_key(subtypes_glyph, glyph_math_binary_subtype, bin); - set_value_entry_key(subtypes_glyph, glyph_math_relation_subtype, rel); + set_value_entry_key(subtypes_glyph, glyph_math_ordinary_subtype, ordinary); + set_value_entry_key(subtypes_glyph, glyph_math_operator_subtype, operator); + set_value_entry_key(subtypes_glyph, glyph_math_binary_subtype, binary); + set_value_entry_key(subtypes_glyph, glyph_math_relation_subtype, relation); set_value_entry_key(subtypes_glyph, glyph_math_open_subtype, open); set_value_entry_key(subtypes_glyph, glyph_math_close_subtype, close); - set_value_entry_key(subtypes_glyph, glyph_math_punctuation_subtype, punct); + set_value_entry_key(subtypes_glyph, glyph_math_punctuation_subtype, punctuation); set_value_entry_key(subtypes_glyph, glyph_math_variable_subtype, variable); set_value_entry_key(subtypes_glyph, glyph_math_active_subtype, active); set_value_entry_key(subtypes_glyph, glyph_math_inner_subtype, inner); @@ -307,13 +308,13 @@ void lmt_nodelib_initialize(void) { subtypes_noad = lmt_aux_allocate_value_info(vcenter_noad_subtype); // last_noad_subtype - set_value_entry_key(subtypes_noad, ordinary_noad_subtype, ord) - set_value_entry_key(subtypes_noad, operator_noad_subtype, op) - set_value_entry_key(subtypes_noad, binary_noad_subtype, bin) - set_value_entry_key(subtypes_noad, relation_noad_subtype, rel) + set_value_entry_key(subtypes_noad, ordinary_noad_subtype, ordinary) + set_value_entry_key(subtypes_noad, operator_noad_subtype, operator) + set_value_entry_key(subtypes_noad, binary_noad_subtype, binary) + set_value_entry_key(subtypes_noad, relation_noad_subtype, relation) set_value_entry_key(subtypes_noad, open_noad_subtype, open) set_value_entry_key(subtypes_noad, close_noad_subtype, close) - set_value_entry_key(subtypes_noad, punctuation_noad_subtype, punct) + set_value_entry_key(subtypes_noad, punctuation_noad_subtype, punctuation) set_value_entry_key(subtypes_noad, variable_noad_subtype, variable) set_value_entry_key(subtypes_noad, active_noad_subtype, active) set_value_entry_key(subtypes_noad, inner_noad_subtype, inner) diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 093978c4e..113de8f40 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -79,6 +79,13 @@ - radical - boundary + Before we went on with \LUAMETATEX\ already quite a bit was added to \LUATEX\ (granularity in + subtypes, more of them, etc.) but here we add more. Some day I might make a list of difference + just for historic reasons. Don't assume equivalence: some in \LUATEX\ was sort of experimental + and improved over time and maybe should not have been added to \LUATEX\ at all and been delayed + for \LUAMETATEX\ instead (as it's probably not used), so that core \LUATEX\ stayed closer the + other engines. + */ typedef enum node_types { @@ -966,6 +973,7 @@ typedef enum rule_subtypes { empty_rule_subtype, strut_rule_subtype, outline_rule_subtype, + virtual_rule_subtype, user_rule_subtype, math_over_rule_subtype, math_under_rule_subtype, @@ -978,7 +986,8 @@ typedef enum rule_subtypes { typedef enum rule_codes { normal_rule_code, empty_rule_code, - strut_rule_code, + virtual_rule_code, + strut_rule_code } rule_codes; # define last_rule_subtype image_rule_subtype diff --git a/source/luametatex/source/tex/texrules.c b/source/luametatex/source/tex/texrules.c index b3d069ad3..db993585b 100644 --- a/source/luametatex/source/tex/texrules.c +++ b/source/luametatex/source/tex/texrules.c @@ -4,19 +4,19 @@ # include "luametatex.h" -halfword tex_aux_scan_rule_spec(rule_types t, halfword s) +halfword tex_aux_scan_rule_spec(rule_types type, halfword code) { /*tex |width|, |depth|, and |height| all equal |null_flag| now */ - halfword rule = tex_new_rule_node((quarterword) s); + halfword rule = tex_new_rule_node((quarterword) code); halfword attr = node_attr(rule); - switch (t) { + switch (type) { case h_rule_type: rule_height(rule) = default_rule; rule_depth(rule) = 0; break; case v_rule_type: case m_rule_type: - if (s == strut_rule_code) { + if (code == strut_rule_code) { rule_width(rule) = 0; node_subtype(rule) = strut_rule_subtype; } else { @@ -124,9 +124,18 @@ halfword tex_aux_scan_rule_spec(rule_types t, halfword s) } DONE: node_attr(rule) = attr; - if (t == v_rule_type && s == strut_rule_code) { + if (type == v_rule_type && code == strut_rule_code) { tex_aux_check_text_strut_rule(rule, text_style); } + if (code == virtual_rule_code) { + rule_data(rule) = rule_width(rule); + rule_left(rule) = rule_height(rule); + rule_right(rule) = rule_depth(rule); + rule_width(rule) = 0; + rule_height(rule) = 0; + rule_depth(rule) = 0; + node_subtype(rule) = virtual_rule_subtype; + } return rule; } diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index be7fd9234..0766c82c3 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{2023.01.15 13:53} +\newcontextversion{2023.01.24 13:47} %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 407cde6ad..3234da7b6 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{2023.01.15 13:53} +\edef\contextversion{2023.01.24 13:47} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index 3526f81f1..d9a553cea 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -450,6 +450,7 @@ \setinterfacevariable{printable}{stampabile} \setinterfacevariable{process}{process} \setinterfacevariable{product}{prodotto} +\setinterfacevariable{profile}{profile} \setinterfacevariable{program}{programma} \setinterfacevariable{project}{progetto} \setinterfacevariable{protected}{protetto} @@ -719,6 +720,7 @@ \setinterfaceconstant{bookmark}{segnalibro} \setinterfaceconstant{bottom}{fondo} \setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottomalign}{bottomalign} \setinterfaceconstant{bottombefore}{bottombefore} \setinterfaceconstant{bottomcolor}{bottomcolor} \setinterfaceconstant{bottomcommand}{bottomcommand} @@ -1333,6 +1335,7 @@ \setinterfaceconstant{toffset}{toffset} \setinterfaceconstant{tolerance}{tolleranza} \setinterfaceconstant{top}{cima} +\setinterfaceconstant{topalign}{topalign} \setinterfaceconstant{topcolor}{topcolor} \setinterfaceconstant{topcommand}{topcommand} \setinterfaceconstant{topdistance}{distanzacima} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index f08babafd..914ea076f 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -450,6 +450,7 @@ \setinterfacevariable{printable}{tiparibil} \setinterfacevariable{process}{process} \setinterfacevariable{product}{produs} +\setinterfacevariable{profile}{profile} \setinterfacevariable{program}{program} \setinterfacevariable{project}{proiect} \setinterfacevariable{protected}{protejat} @@ -719,6 +720,7 @@ \setinterfaceconstant{bookmark}{semncarte} \setinterfaceconstant{bottom}{jos} \setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottomalign}{bottomalign} \setinterfaceconstant{bottombefore}{bottombefore} \setinterfaceconstant{bottomcolor}{bottomcolor} \setinterfaceconstant{bottomcommand}{bottomcommand} @@ -1333,6 +1335,7 @@ \setinterfaceconstant{toffset}{toffset} \setinterfaceconstant{tolerance}{toleranta} \setinterfaceconstant{top}{sus} +\setinterfaceconstant{topalign}{topalign} \setinterfaceconstant{topcolor}{topcolor} \setinterfaceconstant{topcommand}{topcommand} \setinterfaceconstant{topdistance}{distantasus} diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua index 4f29e09d6..1abe9164a 100644 --- a/tex/context/base/mkiv/back-exp.lua +++ b/tex/context/base/mkiv/back-exp.lua @@ -3438,8 +3438,8 @@ end for n, subtype in nexthlist, head do if subtype == linelist_code then setattr(n,a_textblock,noftextblocks) - elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns - setattr(n,a_textblock,0) +-- elseif subtype == glue_code or subtype == kern_code then -- weird, no list +-- setattr(n,a_textblock,0) end end return false diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index de319be46..136f5b435 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -889,7 +889,7 @@ local function formatcolor(ca,separator) end return concat(c,separator) else - return format("%0.3f",0) + return "0.000" -- format("%0.3f",0) end end @@ -1365,3 +1365,55 @@ implement { context((s < 0 and 0) or (s > 1 and 1) or s) end } + +-- playground for MS and HH + +do + + -- https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio + -- https://www.w3.org/TR/WCAG21/#dfn-relative-luminance + + local function crap(v) + return v <= 0.03928 and v/12.92 or (v+0.055/1.055)^2.4 + end + + local function luminance(color) + color = values[color] + if color then + return (0.2126 * crap(color[2]) + 0.7152 * crap(color[3]) + 0.0722 * crap(color[4])) + 0.05 + end + end + + local function formatluminance(color) + local l = luminance(color) + if l then + return format("%0.3f",l) + end + end + + local function formatluminanceratio(one,two) + local one = luminance(one) + local two = luminance(two) + if one and two then + return format("%0.3f",one > two and one/two or two/one) + end + end + + colors.formatluminance = formatluminance + colors.formatluminanceratio = formatluminanceratio + + implement { + name = "formatluminance", + -- protected = true, + arguments = "integer", + actions = { formatluminance, context }, + } + + implement { + name = "formatluminanceratio", + -- protected = true, + arguments = { "integer", "integer" }, + actions = { formatluminanceratio, context }, + } + +end diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 05a4a397c..34d9b4ed0 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{2023.01.15 13:53} +\newcontextversion{2023.01.24 13:47} %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 a48bbf9cd..9e556a542 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{2023.01.15 13:53} +\edef\contextversion{2023.01.24 13:47} %D Kind of special: diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index f73d41e93..4ac851371 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -17894,6 +17894,10 @@ return { ["pe"]="Ù…Øصول", ["ro"]="produs", }, + ["profile"]={ + ["en"]="profile", + ["fr"]="profil", + }, ["program"]={ ["cs"]="program", ["de"]="programm", diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 410d67a69..14035ad5a 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -509,7 +509,9 @@ return { "mathatomskip", "mathbackwardpenalties", "mathbeginclass", + "mathbinary", "mathcheckfencesmode", + "mathclose", "mathdictgroup", "mathdictproperties", "mathdirection", @@ -525,13 +527,20 @@ return { "mathghost", "mathgluemode", "mathgroupingmode", + "mathinner", "mathleftclass", "mathlimitsmode", "mathmainstyle", "mathmiddle", "mathnolimitsmode", + "mathopen", + "mathoperator", + "mathordinary", + "mathoverline", "mathpenaltiesmode", + "mathpunct", "mathradical", + "mathrelation", "mathrightclass", "mathrulesfam", "mathrulesmode", @@ -545,6 +554,7 @@ return { "mathsurroundmode", "mathsurroundskip", "maththreshold", + "mathunderline", "meaningasis", "meaningfull", "meaningless", @@ -665,6 +675,8 @@ return { "untraced", "unvpack", "variablefam", + "virtualhrule", + "virtualvrule", "vpack", "wordboundary", "wrapuppar", @@ -957,13 +969,9 @@ return { "mathchar", "mathchardef", "mathchoice", - "mathclose", "mathcode", - "mathinner", "mathop", - "mathopen", "mathord", - "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex d1ff492f2..10fca5828 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 a28499680..45f201541 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/strc-doc.lua b/tex/context/base/mkiv/strc-doc.lua index 7a79a7121..0592ad7d5 100644 --- a/tex/context/base/mkiv/strc-doc.lua +++ b/tex/context/base/mkiv/strc-doc.lua @@ -526,26 +526,76 @@ end -- this one will become: return catcode, d (etc) +-- function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: spec table and then also depth +-- if depth then +-- depth = levelmap[depth] or tonumber(depth) +-- end +-- if not depth or depth == 0 then +-- depth = data.depth +-- end +-- local data = data.status[depth] +-- local d +-- if data then +-- if find(key,".",1,true) then +-- d = accesstable(key,data) +-- else +-- d = data.titledata +-- d = d and d[key] +-- end +-- end +-- if d and type(d) ~= "table" then +-- if honorcatcodetable == true or honorcatcodetable == v_auto then +-- local metadata = data.metadata +-- local catcodes = metadata and metadata.catcodes +-- if catcodes then +-- ctx_sprint(catcodes,d) +-- else +-- context(d) +-- end +-- elseif not honorcatcodetable or honorcatcodetable == "" then +-- context(d) +-- else +-- local catcodes = catcodenumbers[honorcatcodetable] +-- if catcodes then +-- ctx_sprint(catcodes,d) +-- else +-- context(d) +-- end +-- end +-- elseif default then +-- context(default) +-- end +-- end + function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: spec table and then also depth + local detail = false + if type(depth) == "string" then + depth, detail = string.splitup(depth,":") + end if depth then depth = levelmap[depth] or tonumber(depth) end if not depth or depth == 0 then depth = data.depth end - local data = data.status[depth] + local useddata + if detail == "+" then + useddata = structures.lists.collected[#structures.lists.tobesaved+1] + else + useddata = data.status[depth] + end local d - if data then + if useddata then if find(key,".",1,true) then - d = accesstable(key,data) + d = accesstable(key,useddata) else - d = data.titledata + d = useddata.titledata d = d and d[key] end end if d and type(d) ~= "table" then if honorcatcodetable == true or honorcatcodetable == v_auto then - local metadata = data.metadata + local metadata = useddata.metadata local catcodes = metadata and metadata.catcodes if catcodes then ctx_sprint(catcodes,d) @@ -567,20 +617,50 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp end end +-- function sections.userdata(depth,key,default) +-- if depth then +-- depth = levelmap[depth] or tonumber(depth) +-- end +-- if not depth or depth == 0 then +-- depth = data.depth +-- end +-- if depth > 0 then +-- local userdata = data.status[depth] +-- userdata = userdata and userdata.userdata +-- userdata = (userdata and userdata[key]) or default +-- if userdata then +-- context(userdata) +-- end +-- end +-- end + function sections.userdata(depth,key,default) + local detail = false + if type(depth) == "string" then + depth, detail = string.splitup(depth,":") + end if depth then - depth = levelmap[depth] or tonumber(depth) + depth = levelmap[depth] + end + if not depth then + depth = tonumber(depth) end if not depth or depth == 0 then depth = data.depth end - if depth > 0 then - local userdata = data.status[depth] - userdata = userdata and userdata.userdata - userdata = (userdata and userdata[key]) or default + local userdata + if detail == "+" then + userdata = structures.lists.collected[#structures.lists.tobesaved+1] if userdata then - context(userdata) + userdata = userdata.userdata end + elseif depth > 0 then + userdata = data.status[depth] + userdata = userdata and userdata.userdata + end + userdata = (userdata and userdata[key]) or default + if userdata then + context(userdata) end end diff --git a/tex/context/base/mkxl/back-exp-imp-mth.lmt b/tex/context/base/mkxl/back-exp-imp-mth.lmt index 5f1554e65..4df109b54 100644 --- a/tex/context/base/mkxl/back-exp-imp-mth.lmt +++ b/tex/context/base/mkxl/back-exp-imp-mth.lmt @@ -175,9 +175,8 @@ do maxsize = 1 } end - elseif roottg == "msubsup" then - -- kind of tricky: we have a diufferent order in display mode + -- kind of tricky: we have a different order in display mode local nucleus, superscript, subscript if ndata > 3 then -- error @@ -263,7 +262,7 @@ do local tg = d.tg if automathrows and (roottg == "mrow" or roottg == "mtext") then -- maybe just always ! check spec first - -- or we can have chesks.* for each as we then can flatten + -- or we can have checks.* for each as we then can flatten if no_mrow[tg] then root.skip = "comment" end diff --git a/tex/context/base/mkxl/back-exp.lmt b/tex/context/base/mkxl/back-exp.lmt index 622aae435..e5e2e9dab 100644 --- a/tex/context/base/mkxl/back-exp.lmt +++ b/tex/context/base/mkxl/back-exp.lmt @@ -1880,18 +1880,25 @@ local collectresults do -- too many locals otherwise end end + local enabled = true + + updaters.register("tagging.state.disable",function() enabled = false end) + updaters.register("tagging.state.enable", function() enabled = true end) + function nodes.handlers.export(head) -- hooks into the page builder - starttiming(treehash) - if trace_export then - report_export("%w<!-- start flushing page -->",currentdepth) - end - -- continueexport() - restart = true - collectresults(head) - if trace_export then - report_export("%w<!-- stop flushing page -->",currentdepth) + if enabled then + starttiming(treehash) + if trace_export then + report_export("%w<!-- start flushing page -->",currentdepth) + end + -- continueexport() + restart = true + collectresults(head) + if trace_export then + report_export("%w<!-- stop flushing page -->",currentdepth) + end + stoptiming(treehash) end - stoptiming(treehash) return head end @@ -1900,13 +1907,15 @@ local collectresults do -- too many locals otherwise return p end + -- needs checking! + function builders.paragraphs.tag(head) noftextblocks = noftextblocks + 1 for n, subtype in nexthlist, head do if subtype == linelist_code then setattr(n,a_textblock,noftextblocks) - elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns - setattr(n,a_textblock,0) + -- elseif subtype == glue_code or subtype == kern_code then -- weird, no list + -- setattr(n,a_textblock,0) end end return false diff --git a/tex/context/base/mkxl/catc-def.mkxl b/tex/context/base/mkxl/catc-def.mkxl index e24aa9cb3..1bde98774 100644 --- a/tex/context/base/mkxl/catc-def.mkxl +++ b/tex/context/base/mkxl/catc-def.mkxl @@ -281,4 +281,9 @@ \amcode \barasciicode \othercatcode \amcode \tildeasciicode \othercatcode +% \amcode "002C \activecatcode % comma +% \amcode "002E \activecatcode % period +% \amcode "003A \activecatcode % colon +% \amcode "003B \activecatcode % semicolon + \endinput diff --git a/tex/context/base/mkxl/colo-ini.mkxl b/tex/context/base/mkxl/colo-ini.mkxl index 6b9b8a5f8..807fdfad1 100644 --- a/tex/context/base/mkxl/colo-ini.mkxl +++ b/tex/context/base/mkxl/colo-ini.mkxl @@ -1300,6 +1300,9 @@ \permanent\def\colorvalue #1{\clf_formatcolor\rawcolorattribute{#1}{\colorformatseparator}} \permanent\def\grayvalue #1{\clf_formatgray \rawcolorattribute{#1}{\colorformatseparator}} +\permanent\def\colorluminance #1{\clf_formatluminance \rawcolorattribute{#1} } +\permanent\def\colorluminanceratio #1#2{\clf_formatluminanceratio\rawcolorattribute{#1} \rawcolorattribute{#2} } + \permanent\def\doifelseblack #1{\clf_doifelseblack\rawcolorattribute{#1}} \permanent\def\doifelsedrawingblack {\clf_doifelsedrawingblack} diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 26913598c..ac65d70cc 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{2023.01.15 13:53} +\newcontextversion{2023.01.24 13:47} %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 38c897e6d..ec204055b 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{2023.01.15 13:53} +\immutable\edef\contextversion{2023.01.24 13:47} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt index 7bc2f54c5..2a2b14850 100644 --- a/tex/context/base/mkxl/driv-shp.lmt +++ b/tex/context/base/mkxl/driv-shp.lmt @@ -49,6 +49,7 @@ local getfont = nuts.getfont local getglyphdimensions = nuts.getglyphdimensions local getkerndimension = nuts.getkerndimension local getlistdimensions = nuts.getlistdimensions +local getruledimensions = nuts.getruledimensions local setdirection = nuts.setdirection local setlink = nuts.setlink @@ -85,6 +86,8 @@ local math_code = nodecodes.math local rule_code = nodecodes.rule local whatsit_code = nodecodes.whatsit +local virtualrule_code = nodes.rulecodes.virtual + local leaders_code = gluecodes.leaders local cleaders_code = gluecodes.cleaders local xleaders_code = gluecodes.xleaders @@ -1132,7 +1135,7 @@ local hlist_out, vlist_out do end end elseif id == rule_code then - local width, height, depth = getwhd(current) + local width, height, depth, virtual = getruledimensions(current) if width > 0 then if height == runningrule then height = boxheight @@ -1147,18 +1150,22 @@ local hlist_out, vlist_out do pos_h = pos_h - width xoffset = - xoffset end - if top ~= 0 then - -- height = height - top - total = total - top - end - if bottom ~= 0 then - depth = depth - bottom - total = total - bottom + if not virtual then + if top ~= 0 then + -- height = height - top + total = total - top + end + if bottom ~= 0 then + depth = depth - bottom + total = total - bottom + end end pos_v = pos_v - depth flushrule(current,pos_h + xoffset,pos_v + yoffset,pos_r,width,total,subtype) end - cur_h = cur_h + width + if not virtual then + cur_h = cur_h + width + end end elseif id == math_code then -- local kern = getkern(current) @@ -1518,7 +1525,7 @@ local hlist_out, vlist_out do elseif id == kern_code then cur_v = cur_v + getkern(current) elseif id == rule_code then - local width, height, depth = getwhd(current) + local width, height, depth, virtual = getruledimensions(current) local total = height + depth if total > 0 then if width == runningrule then @@ -1526,19 +1533,23 @@ local hlist_out, vlist_out do end if width > 0 then local xoffset, yoffset, left, right = getoffsets(current) - if left ~= 0 then - width = width - left - xoffset = left - end - if right ~= 0 then - width = width - right + if not virtual then + if left ~= 0 then + width = width - left + xoffset = left + end + if right ~= 0 then + width = width - right + end end if pos_r == righttoleft_code then xoffset = - xoffset - width end flushrule(current,pos_h + xoffset,pos_v - total - yoffset,pos_r,width,total,subtype) end - cur_v = cur_v + total + if not virtual then + cur_v = cur_v + total + end end elseif id == whatsit_code then flushwhatsit[subtype](current,pos_h,pos_v) diff --git a/tex/context/base/mkxl/file-job.lmt b/tex/context/base/mkxl/file-job.lmt index be2886fba..e117b914e 100644 --- a/tex/context/base/mkxl/file-job.lmt +++ b/tex/context/base/mkxl/file-job.lmt @@ -397,6 +397,8 @@ end local textlevel = 0 -- inaccessible for user, we need to define counter textlevel at the tex end +local c_textlevel = tex.iscount("textlevel") + local function dummyfunction() end local function startstoperror() @@ -414,7 +416,7 @@ local function starttext() context.dostarttext() end textlevel = textlevel + 1 - texsetcount("global","textlevel",textlevel) + texsetcount("global",c_textlevel,textlevel) end local function stoptext() @@ -424,7 +426,7 @@ local function stoptext() elseif textlevel > 0 then textlevel = textlevel - 1 end - texsetcount("global","textlevel",textlevel) + texsetcount("global",c_textlevel,textlevel) if textlevel <= 0 then if trace_jobfiles then report_jobfiles("stopping text") diff --git a/tex/context/base/mkxl/file-job.mklx b/tex/context/base/mkxl/file-job.mklx index 6272b551f..76b679bd6 100644 --- a/tex/context/base/mkxl/file-job.mklx +++ b/tex/context/base/mkxl/file-job.mklx @@ -18,6 +18,8 @@ %D This module delegates most of the work to \LUA\ and therefore also let it %D define the commands, which is more efficient. +\ifdefined\textlevel \else \newinteger\textlevel \fi % used at lua end + \registerctxluafile{data-hsh}{autosuffix} \registerctxluafile{file-job}{autosuffix} @@ -78,7 +80,6 @@ % document structure -\ifdefined\textlevel \else \newinteger\textlevel \fi % might go away \ifdefined\strc_pagenumbers_flush_final_page \else \let\strc_pagenumbers_flush_final_page\relax \fi % ugly \permanent\protected\def\dostarttext diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt index 117e81a66..073af7d2e 100644 --- a/tex/context/base/mkxl/font-con.lmt +++ b/tex/context/base/mkxl/font-con.lmt @@ -415,6 +415,7 @@ function constructors.scale(tfmdata,specification) if extendfactor ~= 0 and extendfactor ~= 1 then hdelta = hdelta * extendfactor target.extend = extendfactor * 1000 +-- target.extend = round(target.extend) else target.extend = 1000 -- extent ? end @@ -423,6 +424,7 @@ function constructors.scale(tfmdata,specification) if squeezefactor ~= 0 and squeezefactor ~= 1 then vdelta = vdelta * squeezefactor target.squeeze = squeezefactor * 1000 +-- target.squeeze = round(target.squeeze) else target.squeeze = 1000 -- extent ? end diff --git a/tex/context/base/mkxl/font-imp-effects.lmt b/tex/context/base/mkxl/font-imp-effects.lmt index 8dce81087..f366bc89e 100644 --- a/tex/context/base/mkxl/font-imp-effects.lmt +++ b/tex/context/base/mkxl/font-imp-effects.lmt @@ -121,6 +121,28 @@ local effects = { hidden = 3, } +local rules = { + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", +} + +-- radicals are not yet ok + +local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + -- hm, this was "if delta ~= 0 then" but delta was gone + if dy ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dy) + end + end + end +end + local function initializeeffect(tfmdata,value) local spec if type(value) == "number" then @@ -170,7 +192,7 @@ local function initializeeffect(tfmdata,value) if squeeze then initializesqueeze(tfmdata,squeeze) end - properties.effect = { + effect = { effect = effect, width = width, factor = factor, @@ -184,28 +206,7 @@ local function initializeeffect(tfmdata,value) extend = tfmdata.parameters.extendfactor, squeeze = tfmdata.parameters.squeezefactor, } - end -end - -local rules = { - "RadicalRuleThickness", - "OverbarRuleThickness", - "FractionRuleThickness", - "UnderbarRuleThickness", -} - --- radicals are not yet ok - -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) - -- hm, this was "if delta ~= 0 then" but delta was gone - if dy ~= 0 then - for i=1,#rules do - local name = rules[i] - local value = mathparameters[name] - if value then - mathparameters[name] = (squeeze or 1) * (value + dy) - end - end + properties.effect = effect end end @@ -237,6 +238,21 @@ local function manipulateeffect(tfmdata) local vfactor = (1 + effect.vfactor) * vfactor parameters.hshift = hshift parameters.vshift = vshift + -- + -- For now we assume that the properties of parts wrt advance and such still + -- apply and that the extensible piece kicks in if needed. Beware of creating + -- virtual extensibles because these could get squeeze twice. + -- + -- local allparts = { } + -- for unicode, character in next, characters do + -- local parts = character.parts + -- if parts then + -- for i=1,#parts do + -- allparts[parts[i].glyph] = true + -- end + -- end + -- end + -- for unicode, character in next, characters do local oldwidth = character.width local oldheight = character.height diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx index 33a9f3623..942c2fecd 100644 --- a/tex/context/base/mkxl/font-mat.mklx +++ b/tex/context/base/mkxl/font-mat.mklx @@ -384,10 +384,12 @@ \to \everymathematics \protected\def\font_helpers_synchronize_math_family_mr - {\c_attr_mathfamily\zerocount} + {\c_attr_mathfamily\zerocount + \font_helpers_synchronize_math_parameters_normal} \protected\def\font_helpers_synchronize_math_family_mb - {\c_attr_mathfamily\ifconditional\c_font_pseudo_bold_math_state\plussix\else\plusthree\fi} + {\c_attr_mathfamily\ifconditional\c_font_pseudo_bold_math_state\plussix\else\plusthree\fi + \font_helpers_synchronize_math_parameters_bold} \installcorenamespace{fontmathsynchronizer} \installcorenamespace{fontmathstoredstrategy} @@ -535,15 +537,21 @@ %D This is nasty, as the engine only stores the last set family parameters (per style) which %D in our case can be bold. -\def\font_helpers_synchronize_math_parameters +\def\font_helpers_synchronize_math_parameters_normal {\c_math_last_family_used\mathstylefontid\textstyle\zerocount - \textfont \zerocount\textfont \zerocount - \scriptfont \zerocount\scriptfont \zerocount - \scriptscriptfont\zerocount\scriptscriptfont\zerocount} + \textfont \c_font_fam_mr\textfont \c_font_fam_mr + \scriptfont \c_font_fam_mr\scriptfont \c_font_fam_mr + \scriptscriptfont\c_font_fam_mr\scriptscriptfont\c_font_fam_mr} + +\def\font_helpers_synchronize_math_parameters_bold + {\c_math_last_family_used\mathstylefontid\textstyle\zerocount + \textfont \c_attr_mathfamily\textfont \c_attr_mathfamily + \scriptfont \c_attr_mathfamily\scriptfont \c_attr_mathfamily + \scriptscriptfont\c_attr_mathfamily\scriptscriptfont\c_attr_mathfamily} \appendtoks \ifnum\c_math_last_family_used=\mathstylefontid\textstyle\zerocount\else - \font_helpers_synchronize_math_parameters + \font_helpers_synchronize_math_parameters_normal \fi \to\everybodyfont diff --git a/tex/context/base/mkxl/grph-rul.lmt b/tex/context/base/mkxl/grph-rul.lmt index b1de3a6a6..c33319658 100644 --- a/tex/context/base/mkxl/grph-rul.lmt +++ b/tex/context/base/mkxl/grph-rul.lmt @@ -56,7 +56,7 @@ interfaces.implement { { "radius", "dimension" }, { "corner", "string" }, } } , - actions = function(t,...) + actions = function(t) local rule = userrule(t) if t.type == "mp" then t.ma = getattribute(a_colormodel) or 1 @@ -65,22 +65,23 @@ interfaces.implement { else setattrlist(rule,true) end - context(nuts.tonode(rule)) + context(tonode(rule)) end } interfaces.implement { - name = "outlinerule", - public = true, + name = "roundedoutline", protected = true, - arguments = { { - { "width", "dimension" }, - { "height", "dimension" }, - { "depth", "dimension" }, - { "line", "dimension" }, - } } , - actions = function(t) - local rule = outlinerule(t.width,t.height,t.depth,t.line) + arguments = { "dimension", "dimension", "dimension", "dimension", "dimension", "string" }, + actions = function(w,h,d,l,r,c) + local rule = userrule { + width = w, + height = h, + depth = d, + line = l, + radius = r, + corner = c, + } setattrlist(rule,true) context(tonode(rule)) end diff --git a/tex/context/base/mkxl/grph-trf.lmt b/tex/context/base/mkxl/grph-trf.lmt index f68d6a6a8..7ca15e2a0 100644 --- a/tex/context/base/mkxl/grph-trf.lmt +++ b/tex/context/base/mkxl/grph-trf.lmt @@ -10,8 +10,19 @@ if not modules then modules = { } end modules ['grph-trf'] = { local sind, cosd, tand, abs = math.sind, math.cosd, math.tand, math.abs +local isdimen = tex.isdimen local setdimension = tex.setdimensionvalue +local d_grph_rotate_x_size = isdimen("d_grph_rotate_x_size") +local d_grph_rotate_y_size = isdimen("d_grph_rotate_y_size") +local d_grph_rotate_x_position = isdimen("d_grph_rotate_x_position") +local d_grph_rotate_y_position = isdimen("d_grph_rotate_y_position") +local d_grph_rotate_x_offset = isdimen("d_grph_rotate_x_offset") +local d_grph_rotate_y_offset = isdimen("d_grph_rotate_y_offset") +local d_grph_rotate_new_width = isdimen("d_grph_rotate_new_width") +local d_grph_rotate_new_height = isdimen("d_grph_rotate_new_height") +local d_grph_rotate_new_depth = isdimen("d_grph_rotate_new_depth") + local function analyzerotate(rotation,width,height,depth,total,notfit,obeydepth) -- -- print(rotation,width,height,depth,notfit,obeydepth) diff --git a/tex/context/base/mkxl/grph-trf.mkxl b/tex/context/base/mkxl/grph-trf.mkxl index 4cac29282..53080b6a1 100644 --- a/tex/context/base/mkxl/grph-trf.mkxl +++ b/tex/context/base/mkxl/grph-trf.mkxl @@ -26,6 +26,19 @@ \registerctxluafile{grph-trf}{autosuffix} +% See below + +\newdimension\d_grph_rotate_x_size +\newdimension\d_grph_rotate_y_size +\newdimension\d_grph_rotate_x_offset +\newdimension\d_grph_rotate_y_offset +\newdimension\d_grph_rotate_x_position +\newdimension\d_grph_rotate_y_position + +\newdimension\d_grph_rotate_new_width +\newdimension\d_grph_rotate_new_height +\newdimension\d_grph_rotate_new_depth + % local: \newdimension\d_grph_scale_x_size @@ -758,16 +771,16 @@ %D register and these are actually kind of constants not used in further %D calculations): -\mutable\dimendef\d_grph_rotate_x_size \zeropoint -\mutable\dimendef\d_grph_rotate_y_size \zeropoint -\mutable\dimendef\d_grph_rotate_x_offset \zeropoint -\mutable\dimendef\d_grph_rotate_y_offset \zeropoint -\mutable\dimendef\d_grph_rotate_x_position\zeropoint -\mutable\dimendef\d_grph_rotate_y_position\zeropoint - -\mutable\dimendef\d_grph_rotate_new_width \zeropoint -\mutable\dimendef\d_grph_rotate_new_height\zeropoint -\mutable\dimendef\d_grph_rotate_new_depth \zeropoint +% mutable\dimendef\d_grph_rotate_x_size \zeropoint +% mutable\dimendef\d_grph_rotate_y_size \zeropoint +% mutable\dimendef\d_grph_rotate_x_offset \zeropoint +% mutable\dimendef\d_grph_rotate_y_offset \zeropoint +% mutable\dimendef\d_grph_rotate_x_position\zeropoint +% mutable\dimendef\d_grph_rotate_y_position\zeropoint +% +% mutable\dimendef\d_grph_rotate_new_width \zeropoint +% mutable\dimendef\d_grph_rotate_new_height\zeropoint +% mutable\dimendef\d_grph_rotate_new_depth \zeropoint %D These aren't: diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt index a8608cc7b..784654c06 100644 --- a/tex/context/base/mkxl/lpdf-lmt.lmt +++ b/tex/context/base/mkxl/lpdf-lmt.lmt @@ -1124,6 +1124,7 @@ local flushimage do local fractionrule_code = rulecodes.fraction local radicalrule_code = rulecodes.radical local outlinerule_code = rulecodes.outline + ----- virtualrule_code = rulecodes.virtual local processrule = nodes.rules.process diff --git a/tex/context/base/mkxl/lpdf-rul.lmt b/tex/context/base/mkxl/lpdf-rul.lmt index dfa5d1a89..391fd0ad1 100644 --- a/tex/context/base/mkxl/lpdf-rul.lmt +++ b/tex/context/base/mkxl/lpdf-rul.lmt @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['lpdf-rul'] = { -- todo: split backend and pdf local tonumber, next, type = tonumber, next, type -local concat = table.concat +local concat, setmetatableindex = table.concat, table.setmetatableindex local attributes = attributes local nodes = nodes @@ -34,11 +34,20 @@ local getrandom = utilities.randomizer.get local formatters = string.formatters local setdimen = tex.setdimen -local setcount = tex.setcount +local isdimen = tex.isdimen local setmacro = tokens.setters.macro local codeinjections = backends.registered.pdf.codeinjections +local d_rule_width = isdimen("d_rule_width") +local d_rule_height = isdimen("d_rule_height") +local d_rule_depth = isdimen("d_rule_depth") +local d_rule_h = isdimen("d_rule_h") +local d_rule_v = isdimen("d_rule_v") +local d_rule_line = isdimen("d_rule_line") +local d_rule_offset = isdimen("d_rule_offset") +local d_rule_factor = isdimen("d_rule_factor") + -- This is very pdf specific. Maybe move some to lpdf-rul.lua some day. local pdfprint ; pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end @@ -54,7 +63,7 @@ do -- local maxcachesize = 8*1024 -- local cachethreshold = 1024/2 - local cache = table.setmetatableindex(function(t,k) + local cache = setmetatableindex(function(t,k) local v = simplemetapost("rulefun",k) -- w, h, d cachesize = cachesize + #v if cachesize > maxcachesize then @@ -178,178 +187,212 @@ do -- course one can use mp instead. It could be improved but at the cost of more -- code than I'm willing to add for something hardly used. - local function round(p,kind) - local method = tonumber(p.corner) or 0 - if method < 0 or method > 27 then - method = 0 - end + local linemapping = { + [interfaces.variables.round] = "ltrb", + ["0"] = "ltrb", ["trbl"] = "ltrb", ["rblt"] = "ltrb", ["bltr"] = "ltrb", + -- + ["1"] = "ltrb", ["2"] = "ltrb", ["3"] = "ltrb", ["4"] = "ltrb", + ["5"] = "ltrb", ["6"] = "ltrb", ["7"] = "ltrb", ["8"] = "ltrb", + -- + [ "9"] = "lbr", ["rbl"] = "lbr", + ["10"] = "tlb", ["blt"] = "tlb", + ["11"] = "ltr", ["rtl"] = "lrt", + ["12"] = "lbr", ["rbl"] = "lbr", + -- + ["13"] = "rt", ["tr"] = "rt", + ["14"] = "rb", ["br"] = "rb", + ["15"] = "bl", ["lb"] = "bl", + ["16"] = "tl", ["lt"] = "tl", + -- + ["32"] = "lr", ["rl"] = "lr", + ["33"] = "tb", ["bt"] = "tb", + -- + ["28"] = "l", + ["29"] = "r", + ["30"] = "b", + ["31"] = "t", + } + + local roundmapping = { + [interfaces.variables.round] = "ltrb", + [ "0"] = "ltrb", ["trbl"] = "ltrb", ["rblt"] = "ltrb", ["bltr"] = "ltrb", + -- + [ "9"] = "lbr", ["rbl"] = "lbr", + ["10"] = "tlb", ["blt"] = "tlb", + ["11"] = "ltr", ["rtl"] = "lrt", + ["12"] = "lbr", ["rbl"] = "lbr", + -- + ["13"] = "rt", ["tr"] = "rt", + ["14"] = "rb", ["br"] = "rb", + ["15"] = "bl", ["lb"] = "bl", + ["16"] = "tl", ["lt"] = "tl", + -- + ["32"] = "lr", ["rl"] = "lr", + ["33"] = "tb", ["bt"] = "tb", + -- + ["28"] = "l", + ["29"] = "r", + ["30"] = "b", + ["31"] = "t", + } + + setmetatableindex(linemapping,function(t,k) + local v = tonumber(k) and k or "ltrb" + t[k] = v + return v + end) + + setmetatableindex(roundmapping,function(t,k) + local v = tonumber(k) and k or "ltrb" + t[k] = v + return v + end) + + local function round(p,kind,corner) local width = p.width or 0 local height = p.height or 0 local depth = p.depth or 0 - local total = height + depth local radius = p.radius or 655360 - local line = p.line or 65536 - local how = (method > 8 or kind ~= "fill") and "S" or "f" + local line = (p.line or 65536) * bpfactor local half = line / 2 - local xmin = half * bpfactor - local xmax = ( width - half) * bpfactor - local ymax = ( height - half) * bpfactor - local ymin = (-depth + half) * bpfactor - local full = ( radius + half) - local xxmin = full * bpfactor - local xxmax = ( width - full) * bpfactor - local yymax = ( height - full) * bpfactor - local yymin = (-depth + full) * bpfactor - line = line * bpfactor - if xxmin <= xxmax and yymin <= yymax then - local list = nil - if method == 0 then - list = { - "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", - xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y", xxmin, ymax, "l", xmin, ymax, - xmin, yymax, "y", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", "h", how, "Q", - } - elseif method == 1 then - list = { - "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", - xmax, ymax, "l", xmin, ymax, "l", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", - "h", how, "Q", - } - elseif method == 2 then - list = { - "q", line, "w", xxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxmin, ymax, - "l", xmin, ymax, xmin, yymax, "y", xmin, yymin, "l", xmin, ymin, xxmin, ymin, - "y", "h", how, "Q", - } - elseif method == 3 then - list = { - "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yymax, "l", xmax, ymax, - xxmax, ymax, "y", xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y", xmin, ymin, - "l", "h", how, "Q", - } - - elseif method == 4 then - list = { - "q", line, "w", xmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", - xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l", - "h", how, "Q", - } - elseif method == 5 then - list = { - "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yymax, "l", xmax, ymax, - xxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l", "h", how, "Q", - } - elseif method == 6 then - list = { - "q", line, "w", xmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", - xmax, ymax, "l", xmin, ymax, "l", xmin, ymin, "l", "h", how, "Q", - } - elseif method == 7 then - list = { - "q", line, "w", xxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xmin, ymax, - "l", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", "h", how, "Q", - } - elseif method == 8 then + local xxmin = 0 + local xxmax = width * bpfactor + local yymax = height * bpfactor + local yymin = -depth * bpfactor + local xmin = xxmin + half + local xmax = xxmax - half + local ymax = yymax - half + local ymin = yymin + half + local list = nil + if radius == 0 then + local method = linemapping[corner] + if method == "ltrb" then list = { - "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxmin, ymax, - "l", xmin, ymax, xmin, yymax, "y", xmin, ymin, "l", "h", how, "Q", + "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xmin, ymax, + kind == "fill" and "l h f Q" or "l h S Q" } - elseif method == 9 then - list = { - "q", line, "w", xmin, ymax, "m", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", - xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", xmax, ymax, "l", how, "Q", - } - elseif method == 10 then - list = { - "q", line, "w", xmax, ymax, "m", xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y", - xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", xmax, ymin, "l", how, "Q", - } - elseif method == 11 then - list = { - "q", line, "w", xmax, ymin, "m", xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y", - xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y", xmin, ymin, "l", how, "Q", - } - elseif method == 12 then - list = { - "q", line, "w", xmin, ymax, "m", xxmax, ymax, "l", xmax, ymax, xmax, yymax, "y", - xmax, yymin, "l", xmax, ymin, xxmax, ymin, "y", xmin, ymin, "l", how, "Q", - } - elseif method == 13 then - list = { - "q", line, "w", xmin, ymax, "m", xxmax, ymax, "l", xmax, ymax, xmax, yymax, "y", - xmax, ymin, "l", how, "Q", - } - elseif method == 14 then - list = { - "q", line, "w", xmax, ymax, "m", xmax, yymin, "l", xmax, ymin, xxmax, ymin, "y", - xmin, ymin, "l", how, "Q", - } - elseif method == 15 then - list = { - "q", line, "w", xmax, ymin, "m", xxmin, ymin, "l", xmin, ymin, xmin, yymin, "y", - xmin, ymax, "l", how, "Q", - } - elseif method == 16 then - list = { - "q", line, "w", xmin, ymin, "m", xmin, yymax, "l", xmin, ymax, xxmin, ymax, "y", - xmax, ymax, "l", how, "Q", - } - elseif method == 17 then - list = { - "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", how, "Q", - } - elseif method == 18 then - list = { - "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", how, "Q", - } - elseif method == 19 then - list = { - "q", line, "w", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y", how, "Q", - } - elseif method == 20 then - list = { - "q", line, "w", xmin, yymax, "m", xmin, ymax, xxmin, ymax, "y", how, "Q", - } - elseif method == 21 then - list = { - "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmin, yymax, "m", - xmin, ymax, xxmin, ymax, "y", how, "Q", - } - elseif method == 22 then - list = { - "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmax, yymin, "m", - xmax, ymin, xxmax, ymin, "y", how, "Q", - } - elseif method == 23 then - list = { - "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", xxmin, ymin, "m", - xmin, ymin, xmin, yymin, "y", how, "Q", - } - elseif method == 24 then - list = { - "q", line, "w", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y", xmin, yymax, "m", - xmin, ymax, xxmin, ymax, "y", how, "Q", - } - elseif method == 25 then - list = { - "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmax, yymin, "m", - xmax, ymin, xxmax, ymin, "y", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y", - xmin, yymax, "m", xmin, ymax, xxmin, ymax, "y", how, "Q", - } - elseif method == 26 then + elseif method == "l" then + list = { "q", line, "w", xmin, yymin, "m", xmin, yymax, "l S Q" } + elseif method == "r" then + list = { "q", line, "w", xmax, yymin, "m", xmax, yymax, "l S Q" } + elseif method == "b" then + list = { "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l S Q" } + elseif method == "t" then + list = { "q", line, "w", xxmin, ymax, "m", xxmax, ymax, "l S Q" } + elseif method == "lr" then + list = { "q", line, "w", xmin, yymin, "m", xmin, yymax, "l", xmax, yymin, "m", xmax, yymax, "l S Q" } + elseif method == "tb" then + list = { "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l", xxmin, ymax, "m", xxmax, ymax, "l S Q" } + elseif method == "lbr" then + list = { "q", line, "w", xmin, yymax, "m", xmin, ymin, "l", xmax, ymin, "l", xmax, yymax, "l S Q" } + elseif method == "tlb" then + list = { "q", line, "w", xxmax, ymax, "m", xmin, ymax, "l", xmin, ymin, "l", xxmax, ymin, "l S Q" } + elseif method == "ltr" then + list = { "q", line, "w", xmin, yymin, "m", xmin, ymax, "l", xmax, ymax, "l", xmax, yymin, "l S Q" } + elseif method == "lbr" then + list = { "q", line, "w", xxmin, ymax, "m", xmax, ymax, "l", xmax, ymin, "l", xxmin, ymin, "l S Q" } + elseif method == "rt" then + list = { "q", line, "w", xxmin, ymax, "m", xmax, ymax, "l", xmax, yymin, "l S Q" } + elseif method == "rb" then + list = { "q", line, "w", xmax, yymax, "m", xmax, ymin, "l", xxmin, ymin, "l S Q" } + elseif method == "bl" then + list = { "q", line, "w", xxmax, ymin, "m", xmin, ymin, "l", xmin, yymax, "l S Q" } + elseif method == "tl" then + list = { "q", line, "w", xmin, yymin, "m", xmin, ymax, "l", xxmax, ymax, "l S Q" } + else + return + end + else + local method = roundmapping[corner] + local done = kind ~= "fill" and "h S Q" or "h f Q" -- todo + local full = ( radius + half) + local xxxmin = full * bpfactor + local xxxmax = ( width - full) * bpfactor + local yyymax = ( height - full) * bpfactor + local yyymin = (-depth + full) * bpfactor + if xxxmin > xxxmax or yyymin > yyymax then + return + elseif method == "ltrb" then list = { - "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", xmin, yymax, "m", - xmin, ymax, xxmin, ymax, "y", how, "Q", + "q", line, "w", xxxmin, ymin, "m", xxxmax, ymin, "l", xmax, ymin, xmax, yyymin, "y", xmax, yyymax, "l", xmax, ymax, xxxmax, ymax, "y", + xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", done, } - - elseif method == 27 then + elseif method == "1" then -- ll lr + list = { "q", line, "w", xxxmin, ymin, "m", xxxmax, ymin, "l", xmax, ymin, xmax, yyymin, "y", xmax, ymax, "l", xmin, ymax, "l", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", done } + elseif method == "2" then -- ll ul + list = { "q", line, "w", xxxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", done } + elseif method == "3" then -- ul ur + list = { "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yyymax, "l", xmax, ymax, xxxmax, ymax, "y", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, ymin, "l", done } + elseif method == "4" then -- ur lr + list = { "q", line, "w", xmin, ymin, "m", xxxmax, ymin, "l", xmax, ymin, xmax, yyymin, "y", xmax, yyymax, "l", xmax, ymax, xxxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l", done } + elseif method == "5" then -- ur + list = { "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yyymax, "l", xmax, ymax, xxxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l", done } + elseif method == "6" then -- lr + list = { "q", line, "w", xmin, ymin, "m", xxxmax, ymin, "l", xmax, ymin, xmax, yyymin, "y", xmax, ymax, "l", xmin, ymax, "l", xmin, ymin, "l", done } + elseif method == "7" then -- + list = { "q", line, "w", xxxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xmin, ymax, "l", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", done } -- outlier + elseif method == "8" then -- ul + list = { "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, ymin, "l", done } + elseif method == "lbr" then + list = { "q", line, "w", xmin, yymax, "m", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", xxxmax, ymin, "l", xmax, ymin, xmax, yyymin, "y", xmax, yymax, "l S Q" } + elseif method == "tlb" then + list = { "q", line, "w", xxmax, ymax, "m", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, yyymin, "l", xmin, ymin, xxxmin, ymin, "y", xxmax, ymin, "l S Q" } + elseif method == "ltr" then + list = { "q", line, "w", xmax, yymin, "m", xmax, yyymax, "l", xmax, ymax, xxxmax, ymax, "y", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y", xmin, yymin, "l S Q" } + elseif method == "lbr" then + list = { "q", line, "w", xxmin, ymax, "m", xxxmax, ymax, "l", xmax, ymax, xmax, yyymax, "y", xmax, yyymin, "l", xmax, ymin, xxxmax, ymin, "y", xxmin, ymin, "l S Q" } + elseif method == "lr" then + list = { "q", line, "w", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y", xmin, yyymax, "l", xmin, ymax, xxxmin, ymax, "y", + xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y", xmax, yyymin, "l", xmax, ymin, xxxmax, ymin, "y S Q" } + elseif method == "tb" then + list = { "q", line, "w", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y", xxxmin, ymin, "l", xmin, ymin, xmin, yyymin, "y", + xmax, yyymax, "m", xmax, ymax, xxxmax, ymax, "y", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y S Q" } + elseif method == "rt" then + list = { "q", line, "w", xxmin, ymax, "m", xxxmax, ymax, "l", xmax, ymax, xmax, yyymax, "y", xmax, yymin, "l S Q" } + elseif method == "rb" then + list = { "q", line, "w", xmax, yymax, "m", xmax, yyymin, "l", xmax, ymin, xxxmax, ymin, "y", xxmin, ymin, "l S Q" } + elseif method == "bl" then + list = { "q", line, "w", xxmax, ymin, "m", xxxmin, ymin, "l", xmin, ymin, xmin, yyymin, "y", xmin, yymax, "l S Q" } + elseif method == "tl" then + list = { "q", line, "w", xmin, yymin, "m", xmin, yyymax, "l", xmin, ymax, xxxmin, ymax, "y", xxmax, ymax, "l S Q" } + elseif method == "17" then -- urx + list = { "q", line, "w", xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y S Q" } + elseif method == "18" then -- lrt + list = { "q", line, "w", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y S Q" } + elseif method == "19" then -- llx + list = { "q", line, "w", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y S Q" } + elseif method == "20" then -- urx + list = { "q", line, "w", xmin, yyymax, "m", xmin, ymax, xxxmin, ymax, "y S Q" } + elseif method == "21" then -- ulx urx + list = { "q", line, "w", xmax, yyymax, "m", xmax, ymax, xxxmax, ymax, "y", xxxmin, ymax, "m", xmin, ymax, xmin, yyymax, "y S Q" } + elseif method == "22" then -- urt lrt + list = { "q", line, "w", xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y S Q" } + elseif method == "23" then -- llx lrx + list = { "q", line, "w", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y S Q" } + elseif method == "24" then -- ulx llx + list = { "q", line, "w", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y", xmin, yyymax, "m", xmin, ymax, xxxmin, ymax, "y S Q" } + elseif method == "25" then -- llx lrx urx ulx list = { - "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xxmin, ymin, "m", - xmin, ymin, xmin, yymin, "y", how, "Q", + "q", line, "w", xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y", xxxmin, ymin, "m", + xmin, ymin, xmin, yyymin, "y", xmin, yyymax, "m", xmin, ymax, xxxmin, ymax, "y S Q", } + elseif method == "26" then + list = { "q", line, "w", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y", xmin, yyymax, "m", xmin, ymax, xxxmin, ymax, "y S Q" } + elseif method == "27" then + list = { "q", line, "w", xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y S Q" } + elseif method == "l" then + list = { "q", line, "w", xxxmin, ymin, "m", xmin, ymin, xmin, yyymin, "y", xmin, yyymax, "l", xmin, ymax, xxxmin, ymax, "y S Q" } + elseif method == "r" then + list = { "q", line, "w", xxxmax, ymax, "m", xmax, ymax, xmax, yyymax, "y", xmax, yyymin, "l", xmax, ymin, xxxmax, ymin, "y S Q" } + elseif method == "b" then + list = { "q", line, "w", xmax, yyymin, "m", xmax, ymin, xxxmax, ymin, "y", xxxmin, ymin, "l", xmin, ymin, xmin, yyymin, "y S Q" } + elseif method == "t" then + list = { "q", line, "w", xmax, yyymax, "m", xmax, ymax, xxxmax, ymax, "y", xxxmin, ymax, "l", xmin, ymax, xmin, yyymax, "y S Q" } + else + return end - pdfprint("direct",concat(list," ")) end + pdfprint("direct",concat(list," ")) end local f_rectangle = formatters["q %.6N w %.6N %.6N %.6N %.6N re %s Q"] @@ -366,8 +409,9 @@ h %s Q]] ] local rule_any = function(p,h,v,i,n) - if p.corner then - return round(p,i) + local corner = p.corner + if corner then + return round(p,i,corner) else local l = (p.line or 65536)*bpfactor local r = p and (p.radius or 0)*bpfactor or 0 diff --git a/tex/context/base/mkxl/lpdf-tag.lmt b/tex/context/base/mkxl/lpdf-tag.lmt index 7aa9edb9b..f6a881208 100644 --- a/tex/context/base/mkxl/lpdf-tag.lmt +++ b/tex/context/base/mkxl/lpdf-tag.lmt @@ -134,6 +134,12 @@ end -- mostly the same as the annotations tree +local usenamespace = false experiments.register("structures.tags.namespaces", function(v) usenamespace = v end) + +local namespaceurls = { + mathml = "http://www.w3.org/1998/Math/MathML", +} + local function finishstructure() if root and #structure_kids > 0 then local nums = pdfarray() @@ -152,11 +158,35 @@ local function finishstructure() } local idtree = pdfmakenametree(names) -- - local rolemap = pdfdictionary() + local rolemaps = usenamespace and { } + local rolemap = pdfdictionary() -- main one for k, v in next, usedmapping do k = usedlabels[k] or k local p = properties[k] - rolemap[k] = pdfconstant(p and p.pdf or "Span") -- or "Div" + if not p then + print("UNDEFINED", k) + end + local n = p and p.namespace + if rolemaps and n then + local r = rolemaps[n] + if not r then + r = pdfdictionary() + rolemaps[n] = r + end + r[k] = pdfconstant(k) -- maybe other tag + else + rolemap[k] = pdfconstant(p and p.pdf or "Span") -- or "Div" + end + end + local namespaces = rolemaps and next(rolemaps) and pdfarray { } or nil + if namespaces then + for k, v in table.sortedhash(rolemaps) do + namespaces[#namespaces+1] = pdfdictionary { + Type = pdfconstant("Namespace"), + NS = pdfunicode(namespaceurls[k] or k), + RoleMapNS = v, + } + end end local structuretree = pdfdictionary { Type = pdfconstant("StructTreeRoot"), @@ -164,6 +194,7 @@ local function finishstructure() ParentTree = pdfreference(pdfflushobject(parent_ref,parenttree)), IDTree = idtree, RoleMap = rolemap, -- sorted ? + Namespaces = namespaces, } pdfflushobject(structure_ref,structuretree) addtocatalog("StructTreeRoot",pdfreference(structure_ref)) @@ -406,15 +437,25 @@ end local EMCliteral = nil local visualize = nil +local enabled = true + +updaters.register("tagging.state.disable",function() enabled = false end) +updaters.register("tagging.state.enable", function() enabled = true end) + function nodeinjections.addtags(head) + if not enabled then + return + end + if not EMCliteral then EMCliteral = register(setstate("EMC")) end - local last = nil - local ranges = { } - local range = nil + local last = nil + local ranges = { } + local range = nil + local nofranges = 0 if not root then structure_kids = pdfarray() @@ -430,12 +471,10 @@ function nodeinjections.addtags(head) -- maybe also disc if getchar(n) ~= 0 then local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact - -- if not at then - -- range = nil - -- elseif ... if last ~= at then range = { at, "glyph", n, n, list } -- attr id start stop list - ranges[#ranges+1] = range + nofranges = nofranges + 1 + ranges[nofranges] = range last = at elseif range then range[4] = n -- stop @@ -445,11 +484,8 @@ function nodeinjections.addtags(head) local at = getattr(n,a_image) if at then local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact - -- if not at then - -- range = nil - -- else - ranges[#ranges+1] = { at, "image", n, n, list } -- attr id start stop list - -- end + nofranges = nofranges + 1 + ranges[nofranges] = { at, "image", n, n, list } -- attr id start stop list last = nil else local list = getlist(n) @@ -469,7 +505,7 @@ function nodeinjections.addtags(head) -- inspect(ranges) if trace_tags then - for i=1,#ranges do + for i=1,nofranges do local range = ranges[i] local attr = range[1] local id = range[2] @@ -511,7 +547,12 @@ function nodeinjections.addtags(head) end end - for i=1,#ranges do +-- local function inject(start,stop,list,literal,left,right) +-- setlink(getprev(start) or list or true,literal,left or true,start) +-- setlink(stop,right or true,copy_node(EMCliteral),getnext(stop)) +-- end + + for i=1,nofranges do local range = ranges[i] local attr = range[1] diff --git a/tex/context/base/mkxl/math-acc.mklx b/tex/context/base/mkxl/math-acc.mklx index 9d51ba697..6e25c413f 100644 --- a/tex/context/base/mkxl/math-acc.mklx +++ b/tex/context/base/mkxl/math-acc.mklx @@ -157,6 +157,8 @@ \definemathtopaccent[\v!top:\v!stretch][widetilde]["0303] \definemathtopaccent[\v!top:\v!stretch][widedddot]["20DB] +\definemathtopaccent[\v!top:\v!stretch][vec] ["20D7] % clumsy notation for vectors + \aliased\let\mathring\ring % for a while \popoverloadmode diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt index adfb5712c..a55331c46 100644 --- a/tex/context/base/mkxl/math-act.lmt +++ b/tex/context/base/mkxl/math-act.lmt @@ -33,6 +33,7 @@ local context = context local commands = commands local mathematics = mathematics local texsetdimen = tex.setdimen +local texisdimen = tex.isdimen local abs = math.abs local blocks = characters.blocks @@ -55,6 +56,9 @@ local fontproperties = fonts.hashes.properties local mathgaps = mathematics.gaps +local d_scratchleftoffset = texisdimen("scratchleftoffset") +local d_scratchrightoffset = texisdimen("scratchrightoffset") + local use_math_goodies = true directives.register("math.nogoodies", function(v) use_math_goodies = not v end) local checkitalics = false trackers .register("math.checkitalics", function(v) checkitalics = v end) @@ -136,6 +140,11 @@ local how = { AccentBottomOvershoot = "unscaled", AccentSuperscriptPercent = "unscaled", DelimiterPercent = "unscaled", + -- + RadicalRuleThickness = "vertical", + OverbarRuleThickness = "vertical", + FractionRuleThickness = "vertical", + UnderbarRuleThickness = "vertical", } local function scaleparameters(mathparameters,parameters) @@ -149,7 +158,7 @@ local function scaleparameters(mathparameters,parameters) -- kept elseif h == "horizontal" then value = value * hfactor - elseif h == "vertical"then + elseif h == "vertical" then value = value * vfactor else value = value * factor @@ -3744,8 +3753,8 @@ interfaces.implement { -- can be public with two times "integerargument" arguments = { "integer", "integer" }, actions = function(family,unicode) local kind, loffset, roffset = horizontalcode(family,unicode) - texsetdimen("scratchleftoffset", loffset) - texsetdimen("scratchrightoffset",roffset) + texsetdimen(d_scratchleftoffset, loffset) + texsetdimen(d_scratchrightoffset,roffset) context(kind) end } diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl index 7789dcb60..20ea1d279 100644 --- a/tex/context/base/mkxl/math-ali.mkxl +++ b/tex/context/base/mkxl/math-ali.mkxl @@ -2112,8 +2112,8 @@ %D $<\limits^a$ %D \stoptyping -\permanent\protected\def\overset #1#2{#2\limits\normalsuperscript{#1}} -\permanent\protected\def\underset#1#2{#2\limits\normalsubscript {#1}} +\permanent\protected\def\overset #1#2{\mathrel{#2}\limits\normalsuperscript{#1}} +\permanent\protected\def\underset#1#2{\mathrel{#2}\limits\normalsubscript {#1}} %D The following code comes from \type {math-str.mkiv}. %D @@ -2133,13 +2133,14 @@ \def\strc_math_flush_number_box{\box\b_strc_formulas_number} +% \newdimension \d_strc_math_display_width +% \newdimension \d_strc_math_indent +% \newconditional\c_strc_math_indent + \newconditional\c_strc_math_display_overflow \newconstant \c_strc_math_number_location \newconstant \c_strc_math_number_variant -\newdimension \d_strc_math_display_width \newconstant \c_strc_formulas_frame_mode -\newdimension \d_strc_math_indent -\newconditional\c_strc_math_indent \newdimension \d_strc_math_framed_width \defcsname\??formulaoption\v!frame\endcsname diff --git a/tex/context/base/mkxl/math-fnt.lmt b/tex/context/base/mkxl/math-fnt.lmt index cd4976900..af180b6e4 100644 --- a/tex/context/base/mkxl/math-fnt.lmt +++ b/tex/context/base/mkxl/math-fnt.lmt @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['math-fnt'] = { license = "see context related readme files" } +local round = math.round + local nuts = nodes.nuts local tonut = nodes.tonut local tonode = nodes.tonode @@ -33,7 +35,9 @@ local addcharacters = font.addcharacters local function register_extensible(font,char,style,box) -- We don't share (yet)! local bx = tonut(box) + updaters.apply("tagging.state.disable") -- fast enough nodes.handlers.finalizelist(bx) + updaters.apply("tagging.state.enable") local id = getid(bx) local al = getattrlst(bx) local wd, ht, dp = getwhd(bx) @@ -49,10 +53,24 @@ local function register_extensible(font,char,style,box) -- local private = fonts.helpers.setboxdirectly(font,unicode,box) -- we saved a scaled glyph stream so we now use an unscaled one ... - local g = new_glyph(font,private,al) - if fonts.hashes.properties[font].compactmath then - nuts.setscales(g,1000,1000,1000) - end + local p = fonts.hashes.parameters[font] + local g = new_glyph(font,private,al) +-- if fonts.hashes.properties[font].compactmath then +-- nuts.setscales(g,1000,1000,1000) +-- end + -- nasty, testcase: bold math sqrt extensible + local sx = round(1000/p.extendfactor) + local sy = round(1000/p.squeezefactor) + nuts.setscales(g,1000,sx,sy) + -- horrible +if sx ~= 1000 then + wd = wd * 7200/7227 +end +if sy ~= 1000 then + ht = ht * 7200/7227 + dp = dp * 7200/7227 +end + -- local n = new_hlist(g) -- if newcommands then diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt index fb98ce35b..f26f24c93 100644 --- a/tex/context/base/mkxl/math-ini.lmt +++ b/tex/context/base/mkxl/math-ini.lmt @@ -30,7 +30,6 @@ local context = context local commands = commands local implement = interfaces.implement -local ctx_sprint = context.sprint local ctx_doifelsesomething = commands.doifelsesomething local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) @@ -287,12 +286,12 @@ local lastengineclass = 0 local lastprivateclass = maxengineclass for k, v in next, nodes.noadcodes do - if type(k) == "string"then + if type(k) == "string" then classes[k] = v - local n = classnames[v] - if not n or #k < #n then - classnames[v] = k - end +-- local n = classnames[v] +-- if not n or #k < #n then +-- classnames[v] = k +-- end elseif k > lastengineclass then lastengineclass = k end @@ -314,6 +313,8 @@ local over_class = classes.over local fenced_class = classes.fenced local ghost_class = classes.ghost +-- these will go + classes.ord = ordinary_class classes.op = operator_class classes.bin = binary_class @@ -326,6 +327,8 @@ classes.rad = radical_class classes.fen = fenced_class classes.gst = ghost_class +-- these will go too + classes.limop = operator_class classes.limoperator = operator_class classes.nolop = operator_class @@ -333,7 +336,7 @@ classes.nolimoperator = operator_class classes.large = operator_class classes.largeoperator = operator_class --- special in the engine : variable active inner vcenter +-- special in the engine : variable active inner vcenter local function registerengineclass(name,short) local class = classes[name] @@ -345,11 +348,38 @@ local function registerengineclass(name,short) else class = ordinary_class end - classes[name] = class + else + classnames[class] = short or name end + classes[class] = name + classes[name] = class return class end +-- predefined classes + +registerengineclass("ordinary", "ord") +registerengineclass("operator", "ope") +registerengineclass("binary", "bin") +registerengineclass("relation", "rel") +registerengineclass("open", "ope") +registerengineclass("close", "clo") +registerengineclass("punctuation", "pun") +registerengineclass("variable", "var") -- not used +registerengineclass("active", "act") -- not used +registerengineclass("inner", "inn") -- not used +registerengineclass("middle", "mid") +registerengineclass("accent", "acc") +registerengineclass("radical", "rad") +registerengineclass("fraction", "fra") +registerengineclass("under", "und") +registerengineclass("over", "ove") +registerengineclass("fenced", "fen") +registerengineclass("ghost", "gho") +registerengineclass("vcenter", "vce") -- not used + +-- additional classes + registerengineclass("explicit", "xpl") registerengineclass("imaginary", "img") registerengineclass("differential", "dif") @@ -365,19 +395,19 @@ registerengineclass("construct", "con") registerengineclass("dimension", "dim") registerengineclass("unary", "una") registerengineclass("textpunctuation", "tpu") -registerengineclass("unspaced") -registerengineclass("experimental") -registerengineclass("fake") +registerengineclass("unspaced", "uns") +registerengineclass("experimental", "exp") +registerengineclass("fake", "fak") registerengineclass("numbergroup", "ngr") -registerengineclass("maybeordinary") -registerengineclass("mayberelation") -registerengineclass("maybebinary") +registerengineclass("maybeordinary", "mor") +registerengineclass("mayberelation", "mre") +registerengineclass("maybebinary", "mbi") local specialclasses = tex.specialmathclasscodes classes["all"] = specialclasses["all"] classnames[specialclasses["all"] ] = "all" -classes["begin"] = specialclasses["begin"] classnames[specialclasses["begin"]] = "begin" +classes["begin"] = specialclasses["begin"] classnames[specialclasses["begin"]] = "beg" classes["end"] = specialclasses["end"] classnames[specialclasses["end"] ] = "end" callback.register("get_noad_class", function(n) return classnames[n] end) @@ -506,6 +536,16 @@ mathematics.virtualized = virtualized do + local skip = { + [accent_class] = true, + [topaccent_class] = true, + [bottomaccent_class] = true, + [over_class] = true, + [under_class] = true, + [radical_class] = true, + [root_class] = true, + } + local registercharacter = mathematics.dictionaries.registercharacter local groupnames = mathematics.dictionaries.names @@ -514,10 +554,10 @@ do setmathcode("global",slot,class,family,unicode) mset = false end - if dset and (class == open_class or class == close_class or class == middle_class or class == division_class) then - setdelcode("global",slot,family,unicode,0,0) - dset = false - end + -- if dset and (class == open_class or class == close_class or class == middle_class or class == division_class) then + -- setdelcode("global",slot,family,unicode,0,0) + -- dset = false + -- end if group then group = groupnames[group] or 0 if group ~= 0 then @@ -540,47 +580,36 @@ do end end - -- local f_accent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ] - -- local f_fixedtopaccent = formatters[ [[\defUmathfixedtopaccent \%s{%X}{%X}{%X}]] ] - -- local f_fixedbottomaccent = formatters[ [[\defUmathfixedbottomaccent \%s{%X}{%X}{%X}]] ] - -- local f_topaccent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ] - -- local f_bottomaccent = formatters[ [[\defUmathbottomaccent \%s{%X}{%X}{%X}]] ] - -- local f_over = formatters[ [[\defUdelimiterover \%s{%X}{%X}{%X}]] ] - -- local f_under = formatters[ [[\defUdelimiterunder\%s{%X}{%X}{%X}]] ] - -- local f_fence = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ] - -- local f_delimiter = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ] - -- local f_radical = formatters[ [[\defUradical \%s{%X}{%X}]] ] - -- local f_root = formatters[ [[\defUroot \%s{%X}{%X}]] ] - -- local f_char = formatters[ [[\defUmathchar \%s{%X}{%X}{%X}]] ] - local texmathchardef = tex.mathchardef + -- local setmathsymbol = function(name,class,family,slot,stretch,group) -- hex is nicer for tracing + -- if skip[class] then + -- return -- only in mkiv + -- elseif class == open_class or class == close_class or class == middle_class then + -- setdelcode("global",slot,family,slot,0,0) -- can go + -- elseif class == delimiter_class then -- open close or middle (bars) + -- setdelcode("global",slot,family,slot,0,0) -- can go + -- class = 0 + -- else + -- if group then + -- group = groupnames[group] or 0 + -- if group ~= 0 then + -- texmathchardef(name,class,family,slot,"permanent",0x1,group,slot) + -- return + -- end + -- end + -- end + -- texmathchardef(name,class,family,slot,"permanent") + -- end + local setmathsymbol = function(name,class,family,slot,stretch,group) -- hex is nicer for tracing - if class == accent_class then - -- ctx_sprint(f_accent(name,0,family,slot)) - elseif class == topaccent_class then - -- ctx_sprint((stretch and f_topaccent or f_fixedtopaccent)(name,0,family,slot)) - elseif class == bottomaccent_class then - -- ctx_sprint((stretch and f_bottomaccent or f_fixedbottomaccent)(name,0,family,slot)) - elseif class == over_class then -- only in mkiv - -- ctx_sprint(f_over(name,0,family,slot)) - elseif class == under_class then -- only in mkiv - -- ctx_sprint(f_under(name,0,family,slot)) - elseif class == open_class or class == close_class or class == middle_class then - setdelcode("global",slot,family,slot,0,0) -- can go - -- ctx_sprint(f_fence(name,class,family,slot)) - -- ctx_sprint(f_char(name,class,family,slot)) - texmathchardef(name,class,family,slot,"permanent") - elseif class == delimiter_class then -- open close or middle (bars) - setdelcode("global",slot,family,slot,0,0) -- can go - -- ctx_sprint(f_delimiter(name,0,family,slot)) - -- ctx_sprint(f_char(name,0,family,slot)) - texmathchardef(name,0,family,slot,"permanent") - elseif class == radical_class then -- only in mkiv - -- ctx_sprint(f_radical(name,family,slot)) - elseif class == root_class then -- only in mkiv - -- ctx_sprint(f_root(name,family,slot)) - elseif texmathchardef then + if skip[class] then + return -- only in mkiv + -- elseif class == open_class or class == close_class or class == middle_class then + else + if class == delimiter_class then -- open close or middle (bars) + class = ordinary_class + end if group then group = groupnames[group] or 0 if group ~= 0 then diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl index dfa8a18ef..901d187b0 100644 --- a/tex/context/base/mkxl/math-ini.mkxl +++ b/tex/context/base/mkxl/math-ini.mkxl @@ -51,33 +51,19 @@ \unprotect -\newdimension\mathstrutht -\newdimension\mathstrutdp -\newinteger \mathnestinglevel - -% For now: - -%protected\def\Umathaccent_top {\Umathaccent top } -%protected\def\Umathaccent_bottom {\Umathaccent bottom } -%protected\def\Umathaccent_top_fixed {\Umathaccent top fixed } -%protected\def\Umathaccent_bottom_fixed{\Umathaccent bottom fixed } - -%permanent\protected\def\defUmathfixedtopaccent #1#2#3#4{\global\immutable\protected\def#1{\Umathaccent_top_fixed "#2 "#3 "#4 }} -%permanent\protected\def\defUmathfixedbottomaccent#1#2#3#4{\global\immutable\protected\def#1{\Umathaccent_bottom_fixed "#2 "#3 "#4 }} -%permanent\protected\def\defUmathtopaccent #1#2#3#4{\global\immutable\protected\def#1{\Umathaccent_top "#2 "#3 "#4 }} -%permanent\protected\def\defUmathbottomaccent #1#2#3#4{\global\immutable\protected\def#1{\Umathaccent_bottom "#2 "#3 "#4 }} - -%permanent\protected\def\defUmathchar #1#2#3#4{\global\immutable\Umathchardef #1 "#2 "#3 "#4 } -%permanent\protected\def\defUdelimiter #1#2#3#4{\global\immutable\protected\def#1{\Udelimiter "#2 "#3 "#4 }} -%permanent\protected\def\defUdelimiter #1#2#3#4{\global\immutable\Umathchardef #1 "#2 "#3 "#4 } - -%permanent\protected\def\defUradical #1#2#3{\global\immutable\protected\def#1{\Uradical "#2 "#3 }} -%permanent\protected\def\defUroot #1#2#3{\global\immutable\protected\def#1{\Uroot "#2 "#3 }} - -%permanent\protected\def\defUdelimiterover #1#2#3#4{\global\immutable\protected\def#1{\Udelimiterover "#2 "#3 }} % radicals -%permanent\protected\def\defUdelimiterunder #1#2#3#4{\global\immutable\protected\def#1{\Udelimiterunder "#2 "#3 }} % radicals - -% So: +\newdimension \mathstrutht +\newdimension \mathstrutdp +\newinteger \mathnestinglevel + +\newcount \c_strc_math_n_of_lines +\newdimension \d_strc_math_max_width +\newdimension \d_strc_math_first_width +\newdimension \d_strc_math_last_width +\newdimension \d_strc_math_first_height +\newdimension \d_strc_math_last_depth +\newdimension \d_strc_math_display_width +\newdimension \d_strc_math_indent +\newconditional\c_strc_math_indent \registerctxluafile{math-ini}{autosuffix} \registerctxluafile{math-dim}{autosuffix} @@ -2682,6 +2668,15 @@ % todo: use \Umathclass\c_math_comma\mathpunctcode etc for temporary switching +%D This is a dirty trick. In order to prevent a loop due to reinjection, when a +%D active one is seen, the amcode is set to other. So, afterwards we need to +%D reactivate. Eventually this feature will be dropped in favor of a more modern +%D mechanism. + +\def\math_activeate_comma {\amcode\c_math_comma \activecatcode} +\def\math_activeate_period {\amcode\c_math_period \activecatcode} +\def\math_activeate_semicolon{\amcode\c_math_semicolon\activecatcode} + \def\math_set_o_comma {\Umathcode\c_math_comma \mathordinarycode \zerocount\c_math_comma} \def\math_set_p_comma {\Umathcode\c_math_comma \mathpunctuationcode\zerocount\c_math_comma} \def\math_set_o_period {\Umathcode\c_math_period \mathordinarycode \zerocount\c_math_period} @@ -2692,9 +2687,9 @@ \edef\math_set_o_both {\math_set_o_period\math_set_o_comma} \edef\math_set_p_both {\math_set_p_period\math_set_p_comma} -\protected\def\math_punctuation_nop_comma {\begingroup\math_set_p_comma ,\endgroup} -\protected\def\math_punctuation_nop_period {\begingroup\math_set_o_period .\endgroup} -\protected\def\math_punctuation_nop_semicolon{\begingroup\math_set_p_semicolon;\endgroup} +\protected\def\math_punctuation_nop_comma {\begingroup\math_set_p_comma ,\endgroup\math_activeate_comma } +\protected\def\math_punctuation_nop_period {\begingroup\math_set_o_period .\endgroup\math_activeate_period } +\protected\def\math_punctuation_nop_semicolon{\begingroup\math_set_p_semicolon;\endgroup\math_activeate_semicolon} % todo: use new lookahead stuff @@ -2706,9 +2701,9 @@ \let\math_punctuation_yes_period \math_punctuation_nop_period \let\math_punctuation_yes_semicolon\math_punctuation_all_semicolon -\def\math_punctuation_comma_next {\begingroup\Umathcode\c_math_comma \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_comma ,\endgroup} -\def\math_punctuation_period_next {\begingroup\Umathcode\c_math_period \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_period .\endgroup} -\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_semicolon;\endgroup} +\def\math_punctuation_comma_next {\begingroup\Umathcode\c_math_comma \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_comma ,\endgroup\math_activeate_comma } +\def\math_punctuation_period_next {\begingroup\Umathcode\c_math_period \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_period .\endgroup\math_activeate_period } +\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_semicolon;\endgroup\math_activeate_semicolon} \installcorenamespace {mathautopunctuation} @@ -2725,12 +2720,6 @@ \let.\math_punctuation_nop_period \let;\math_punctuation_nop_semicolon} - % more efficient list: - % - % \gdefcsname\??mathautopunctuation\v!no\endcsname - % {\Umathcode\c_math_period\mathordcode \zerocount\c_math_period - % \Umathcode\c_math_comma \mathpunctcode\zerocount\c_math_comma } - \gdefcsname\??mathautopunctuation\v!yes\endcsname {\let,\math_punctuation_yes_comma \let.\math_punctuation_yes_period @@ -2773,10 +2762,17 @@ % \activatemathcharacter\c_math_period % \activatemathcharacter\c_math_semicolon +% \appendtoks +% \mathcode\c_math_comma \c_math_special +% \mathcode\c_math_period \c_math_special +% \mathcode\c_math_semicolon\c_math_special +% \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname +% \to \everymathematics + \appendtoks - \mathcode\c_math_comma \c_math_special - \mathcode\c_math_period \c_math_special - \mathcode\c_math_semicolon\c_math_special + \math_activeate_comma + \math_activeate_period + \math_activeate_semicolon \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname \to \everymathematics diff --git a/tex/context/base/mkxl/math-spa.lmt b/tex/context/base/mkxl/math-spa.lmt index 5fa1a3742..9840a6aef 100644 --- a/tex/context/base/mkxl/math-spa.lmt +++ b/tex/context/base/mkxl/math-spa.lmt @@ -49,11 +49,21 @@ local nextnode = nuts.traversers.node local texgetdimen = tex.getdimen local texsetdimen = tex.setdimen local texsetcount = tex.setcount +local texisdimen = tex.isdimen +local texiscount = tex.iscount local boundary = tex.boundaries.system("mathalign") local stages = { } local initial = { } +local c_strc_math_n_of_lines = texiscount("c_strc_math_n_of_lines") +local d_strc_math_max_width = texisdimen("d_strc_math_max_width") +local d_strc_math_first_width = texisdimen("d_strc_math_first_width") +local d_strc_math_last_width = texisdimen("d_strc_math_last_width") +local d_strc_math_first_height = texisdimen("d_strc_math_first_height") +local d_strc_math_last_depth = texisdimen("d_strc_math_last_depth") +local d_strc_math_indent = texisdimen("d_strc_math_indent") + stages[1] = function(specification,stage) local box = getbox(specification.box) local head = getlist(box) @@ -91,7 +101,7 @@ stages[1] = function(specification,stage) break end end - texsetdimen("global","d_strc_math_indent",distance) + texsetdimen("global",d_strc_math_indent,distance) if align == 2 then for n in nextglue, head do setglue(n,getwidth(n),0,0,0,0) @@ -149,12 +159,12 @@ stages[2] = function(specification,stage) end end end - texsetcount("global","c_strc_math_n_of_lines",cnt) - texsetdimen("global","d_strc_math_max_width",maxwidth) - texsetdimen("global","d_strc_math_first_width",firstwidth) - texsetdimen("global","d_strc_math_last_width",lastwidth) - texsetdimen("global","d_strc_math_first_height",firstheight) - texsetdimen("global","d_strc_math_last_depth",lastdepth) + texsetcount("global",c_strc_math_n_of_lines,cnt) + texsetdimen("global",d_strc_math_max_width,maxwidth) + texsetdimen("global",d_strc_math_first_width,firstwidth) + texsetdimen("global",d_strc_math_last_width,lastwidth) + texsetdimen("global",d_strc_math_first_height,firstheight) + texsetdimen("global",d_strc_math_last_depth,lastdepth) end stages[3] = stages[2] diff --git a/tex/context/base/mkxl/math-tag.lmt b/tex/context/base/mkxl/math-tag.lmt index 128b85249..eaba1ea54 100644 --- a/tex/context/base/mkxl/math-tag.lmt +++ b/tex/context/base/mkxl/math-tag.lmt @@ -26,6 +26,7 @@ local nuts = nodes.nuts local tonut = nuts.tonut local getchar = nuts.getchar +local getprev = nuts.getprev local getcharspec = nuts.getcharspec local getdata = nuts.getdata local getlist = nuts.getlist @@ -105,11 +106,15 @@ local restart_tagged = tags.restart local stop_tagged = tags.stop local taglist = tags.taglist -local chardata = characters.data +----- chardata = characters.data -local getmathcodes = tex.getmathcodes -local mathcodes = mathematics.codes -local ordinary_mathcode = mathcodes.ordinary +local getmathcodes = tex.getmathcodes +----- mathcodes = mathematics.codes +local mathcodes = mathematics.classes +local ordinary_mathcode = mathcodes.ordinary +local digit_mathcode = mathcodes.digit +local punctuation_mathcode = mathcodes.punctuation +local active_mathcode = mathcodes.active local fromunicode16 = fonts.mappings.fromunicode16 local fontcharacters = fonts.hashes.characters @@ -223,7 +228,7 @@ end -- only focus on structure and let the engine deal with the details. Another reason -- to update this is that we can add some tracing (lmtx only). --- This has been working ok for quite but in 2023 it's tiem to have a look at it +-- This has been working ok for quite but in 2023 it's time to have a look at it -- again and see to what extend we need to adapt to new features. Around the time -- PG's Panopticom was put on youtube. @@ -245,19 +250,32 @@ process = function(start) -- we cannot use the processor as we have no finalizer if id == mathchar_code then local char = getchar(start) local code = getmathcodes(char) - local ch = chardata[char] - local mc = ch and ch.mathclass +-- local ch = chardata[char] +-- local mc = ch and ch.mathclass local tag - local properties= { class = mc } + local properties= { class = code } + -- we're a bit early so we can have active here and no rules get applied + -- so maybe we have to correct some later on -- todo: we have way more now +-- if code == ordinary_mathcode then +-- if mc == "number" then +-- tag = "mn" +-- elseif mc == "variable" or not mc then -- variable is default +-- tag = "mi" +-- else +-- tag = "mo" +-- end +-- else +-- tag = "mo" +-- end +-- print(code,mathematics.classes[code]) +-- print(ordinary_mathcode,digit_mathcode,active_mathcode) if code == ordinary_mathcode then - if mc == "number" then - tag = "mn" - elseif mc == "variable" or not mc then -- variable is default - tag = "mi" - else - tag = "mo" - end + tag = "mi" + elseif code == digit_mathcode then + tag = "mn" +-- elseif code == punctuation_mathcode or code == active_mathcode then +-- tag = "mo" else tag = "mo" end @@ -316,7 +334,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer process(list) end else - if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then +if tag ~= "mtable" and tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then +-- if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then tag = "mtext" end local text = start_tagged(tag) @@ -343,12 +362,12 @@ process = function(start) -- we cannot use the processor as we have no finalizer -- local keep = { } -- win case we might need to move keep outside for n, id, subtype in nextnode, list do local mth = id == math_code and subtype - if mth == 0 then -- hm left_code - -- insert(keep,text) - keep = text - text = start_tagged("mrow") - common = common + 1 - end +if mth == 0 then -- begin in line + -- insert(keep,text) + keep = text + text = start_tagged("mrow") + common = common + 1 +end local aa = getattr(n,a_tagged) if aa then local ac = cache[aa] @@ -392,12 +411,12 @@ process = function(start) -- we cannot use the processor as we have no finalizer runner(replace,depth+1) end end - if mth == 1 then - stop_tagged() - -- text = remove(keep) - text = keep - common = common - 1 - end +if mth == 1 then -- end in line + stop_tagged() + -- text = remove(keep) + text = keep + common = common - 1 +end end end runner(list,0) @@ -488,6 +507,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer end elseif id == fence_code then local delimiter = getdelimiter(start) +-- print(subtype,fencecodes[subtype],delimiter) if subtype == leftfence_code then local properties = { } insert(fencesstack,properties) @@ -623,7 +643,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer end stop_tagged() else - setattr(start,a_tagged,start_tagged("merror", { detail = nodecodes[i] })) + --rule boundary + setattr(start,a_tagged,start_tagged("merror", { detail = nodecodes[id] })) stop_tagged() end end diff --git a/tex/context/base/mkxl/node-fin.lmt b/tex/context/base/mkxl/node-fin.lmt index 7093638de..88050af8a 100644 --- a/tex/context/base/mkxl/node-fin.lmt +++ b/tex/context/base/mkxl/node-fin.lmt @@ -44,6 +44,7 @@ local rulecodes = nodes.rulecodes local boxrule_code = rulecodes.box local imagerule_code = rulecodes.image local emptyrule_code = rulecodes.empty +local virtualrule_code = rulecodes.virtual local container_code = nodes.listcodes.container @@ -211,7 +212,7 @@ local function process(attribute,head,inheritance,default) -- one attribute setlist(stack,list) end elseif id == rule_code then - check = hasdimensions(stack) + check = subtype == virtualrule_code or hasdimensions(stack) end -- much faster this way than using a check() and nested() function if check then @@ -291,7 +292,7 @@ local function simple(attribute,head) setlist(stack,list) end elseif id == rule_code then - check = hasdimensions(stack) + check = subtype == virtualrule_code or hasdimensions(stack) end if check then local c = getattr(stack,attribute) @@ -386,7 +387,9 @@ local function selective(attribute,head,inheritance,default) -- two attributes setlist(stack,list) end elseif id == rule_code then - if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then + if subtype == virtualrule_code then + check = true + elseif subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then -- so no redundant color stuff (only here, layers for instance should obey) check = false else @@ -494,7 +497,7 @@ local function stacked(attribute,head,default) -- no inheritance, but list-wise end end elseif id == rule_code then - check = hasdimensions(stack) + check = subtype == virtualrule_code or hasdimensions(stack) end if check then local a = getattr(stack,attribute) @@ -576,7 +579,9 @@ local function stacker(attribute,head,default) -- no inheritance, but list-wise end end elseif id == rule_code then - if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then + if subtype == virtualrule_code then + check = true + elseif subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then -- so no redundant color stuff (only here, layers for instance should obey) check = false else diff --git a/tex/context/base/mkxl/node-ini.lmt b/tex/context/base/mkxl/node-ini.lmt index 34028fa2e..f1b9bb452 100644 --- a/tex/context/base/mkxl/node-ini.lmt +++ b/tex/context/base/mkxl/node-ini.lmt @@ -245,7 +245,8 @@ nodes.specialskipcodes = { table.setmetatableindex(listcodes,function(t,k) -- fully qualified as yet unknown - local v = mathematics.classnames[k - 0x100] or listcodes.unknown +-- local v = mathematics.classnames[k - 0x100] or listcodes.unknown + local v = mathematics.classes[k - 0x100] or mathematics.classnames[k - 0x100] or listcodes.unknown t[k] = v return v end) diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt index 89c1fbac6..f17c5ce7a 100644 --- a/tex/context/base/mkxl/node-nut.lmt +++ b/tex/context/base/mkxl/node-nut.lmt @@ -138,6 +138,7 @@ local nuts = { getreplace = direct.getreplace, getrightdelimiter = direct.getrightdelimiter, getruledata = direct.getdata, -- obsolete when we have the split + getruledimensions = direct.getruledimensions, getscale = direct.getscale, getscales = direct.getscales, getscript = direct.getscript, diff --git a/tex/context/base/mkxl/node-ref.lmt b/tex/context/base/mkxl/node-ref.lmt index 36715c067..15c35cba9 100644 --- a/tex/context/base/mkxl/node-ref.lmt +++ b/tex/context/base/mkxl/node-ref.lmt @@ -42,6 +42,7 @@ local report_reference = logs.reporter("backend","references") local report_destination = logs.reporter("backend","destinations") local report_area = logs.reporter("backend","areas") +local texiscount = tex.iscount local texsetcount = tex.setcount ----- texsetattribute = tex.setattribute @@ -55,6 +56,8 @@ updaters.register("backends.injections.latebindings",function() prerollreference = backends.codeinjections.prerollreference end) +local c_lastreferenceattribute = texiscount("lastreferenceattribute") + local nuts = nodes.nuts local nodepool = nuts.pool @@ -246,7 +249,7 @@ local inject_areas do end end - -- Setting these once and not passign them each nested call is faster and this injector is + -- Setting these once and not passing them each nested call is faster and this injector is -- actually one of the more costly calls in a run (when we have lots of references to -- check) and it's also a bti less code. @@ -313,7 +316,7 @@ local inject_areas do local function inject(head,skip,parent,pardir,txtdir) local first, last, firstdir, reference local current = head - while current do + while current do -- tod: check with loop local id = getid(current) if id == hlist_code or id == vlist_code then local r = getattr(current,attribute) @@ -366,6 +369,7 @@ local inject_areas do end goto NEXT elseif id == glue_code then + -- local skiptype = ... 0=regular 1=left 2=right local subtype = getsubtype(current) if subtype == leftskip_code or subtype == lefthang_code or subtype == parfillleftskip_code then goto NEXT @@ -402,8 +406,8 @@ local inject_areas do -- print("!!!!!!!!") end else - -- todo: safeguard when we have a glyph or dics or ... so we might as well - -- then scan for all possibel content nodes + -- todo: safeguard when we have a glyph or disc or ... so we might as well + -- then scan for all possible content nodes reference = r first = current last = current @@ -456,6 +460,7 @@ local colorize, justadd do str = str .. " " shift = (shift or 2) * exheight end + -- todo: virtual rule, zero width hbox, offsets local text = typesetters.tohpack(str,infofont) local rule = new_rule(emwidth/5,4*exheight,3*exheight) setshift(text,shift) @@ -493,12 +498,12 @@ local colorize, justadd do height = 65536/2 depth = height end + -- todo: use virtual rules local rule = setcoloring(new_rule(width,height,depth),1,u_color,u_transparency) -- gray color model if width < 0 then local kern = new_kern(width) setwidth(rule,-width) - setnext(kern,rule) - setprev(rule,kern) + setlink(kern,rule) return kern elseif sr and sr ~= "" then local text = addstring(what,sr,shift) @@ -549,7 +554,7 @@ do -- so some part of the backend work is already done here stack[topofstack] = { r, h or false, d or false, codeinjections.prerollreference(r) } -- texsetattribute(attribute,topofstack) -- todo -> at tex end - texsetcount("lastreferenceattribute",topofstack) + texsetcount(c_lastreferenceattribute,topofstack) end function references.get(n) -- not public so functionality can change @@ -761,7 +766,7 @@ do if result then setlink(current,annot) else - result = annot + result = annot end current = find_node_tail(annot) end diff --git a/tex/context/base/mkxl/node-res.lmt b/tex/context/base/mkxl/node-res.lmt index daf0187e8..6fed08b63 100644 --- a/tex/context/base/mkxl/node-res.lmt +++ b/tex/context/base/mkxl/node-res.lmt @@ -77,7 +77,7 @@ local setleader = nuts.setleader local setclass = nuts.setclass local setdata = nuts.setdata -local setruledata = nuts.setruledata +local setoffsets = nuts.setoffsets local setvalue = nuts.setvalue local copy_nut = nuts.copyonly @@ -188,6 +188,7 @@ local userrule = register_nut(new_nut(rule_code,rulecodes.user)) -- local outlinerule = register_nut(new_nut(rule_code,rulecodes.outline)) -- setdirection(rule, lefttoright_code) local imagerule = register_nut(new_nut(rule_code,rulecodes.image)) -- setdirection(rule, lefttoright_code) local boxrule = register_nut(new_nut(rule_code,rulecodes.box)) -- setdirection(rule, lefttoright_code) +local virtualrule = register_nut(new_nut(rule_code,rulecodes.virtual)) -- setdirection(rule, lefttoright_code) local hlist = register_nut(new_nut(nodecodes.hlist)) setdirection(hlist,lefttoright_code) local vlist = register_nut(new_nut(nodecodes.vlist)) setdirection(vlist,lefttoright_code) @@ -382,7 +383,7 @@ function nutpool.outlinerule(width,height,depth,line) -- w/h/d == nil will let t setwhd(n,width,height,depth) end if line then - setruledata(n,round(line)) -- has to be an integer + setdata(n,round(line)) -- has to be an integer end return n end @@ -403,6 +404,15 @@ function nutpool.boxrule(width,height,depth) -- w/h/d == nil will let them adapt return n end +function nutpool.virtualrule(width,height,depth) -- w/h/d == nil will let them adapt + local n = copy_nut(virtualrule) + if width or height or depth then + setdata(n,width) + setoffsets(n,nil,nil,height,depth) + end + return n +end + local function new_leader(width,list) local n = copy_nut(cleader) if width then diff --git a/tex/context/base/mkxl/node-rul.mkxl b/tex/context/base/mkxl/node-rul.mkxl index 24b7d5ef0..5253c8008 100644 --- a/tex/context/base/mkxl/node-rul.mkxl +++ b/tex/context/base/mkxl/node-rul.mkxl @@ -71,6 +71,20 @@ %definesystemattribute[ruled] %definesystemattribute[shifted] +\newdimension\d_rule_width +\newdimension\d_rule_height +\newdimension\d_rule_depth +\newdimension\d_rule_h +\newdimension\d_rule_v +\newdimension\d_rule_line +\newdimension\d_rule_offset +\newdimension\d_rule_factor + +\mutable\lettonothing\m_rule_direction +%mutable\lettonothing\m_rule_factor +\mutable\lettonothing\m_rule_option +\mutable\lettonothing\m_rule_color + \registerctxluafile{node-rul}{autosuffix,optimize} \installcorenamespace{bar} @@ -289,20 +303,6 @@ %D %D \typebuffer \getbuffer -\newdimension\d_rule_width -\newdimension\d_rule_height -\newdimension\d_rule_depth -\newdimension\d_rule_h -\newdimension\d_rule_v -\newdimension\d_rule_line -\newdimension\d_rule_offset -\newdimension\d_rule_factor - -\mutable\lettonothing\m_rule_direction -%mutable\lettonothing\m_rule_factor -\mutable\lettonothing\m_rule_option -\mutable\lettonothing\m_rule_color - \startuseMPgraphic{rules:under:random} draw ((0,RuleDepth) ... (RuleWidth,RuleDepth)) randomized (4*RuleThickness) diff --git a/tex/context/base/mkxl/node-shp.lmt b/tex/context/base/mkxl/node-shp.lmt index 7d73d9390..fc149330b 100644 --- a/tex/context/base/mkxl/node-shp.lmt +++ b/tex/context/base/mkxl/node-shp.lmt @@ -38,7 +38,7 @@ function handlers.finalizebox(box) actions(getbox(box)) -- nut end -function handlers.finalizelist(list) +function handlers.finalizelist(list) -- beware of export: block it if needed actions(list) -- nut end diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl index 9b87d95b0..baaab17a5 100644 --- a/tex/context/base/mkxl/pack-rul.mkxl +++ b/tex/context/base/mkxl/pack-rul.mkxl @@ -273,32 +273,56 @@ corner {\p_framed_backgroundcorner} \relax}} +% we keep this as reference (should still work when uncommented) +% +% \def\pack_framed_stroked_box +% {\edef\p_framed_framecorner{\framedparameter\c!framecorner}% +% \ifx\p_framed_framecorner\v!rectangular +% \pack_framed_stroked_box_normal +% \else +% \pack_framed_stroked_box_radius +% \fi} +% +% \def\pack_framed_stroked_box_radius +% {\edef\p_framed_frameradius{\framedparameter\c!frameradius}% +% \ifzeropt\dimexpr\p_framed_frameradius\relax % just in case of .x\bodyfontsize +% \pack_framed_stroked_box_normal +% \orelse\ifx\p_framed_frame\v!on +% \pack_framed_stroked_box_round +% \fi} +% +% % \pack_framed_stroked_box_normal % later +% +% \def\pack_framed_stroked_box_round +% {\raise\d_framed_target_dp\hpack{\frule +% width \d_framed_target_wd +% height \d_framed_target_ht +% depth \d_framed_target_dp +% line \d_framed_linewidth +% radius \p_framed_frameradius\space +% corner {\p_framed_framecorner} +% \relax}} +% +% corner is the parent of framecorner and backgroundcorner (round value never checked) +% when 'round' is passed it is not a number and therefore we get four sides + \def\pack_framed_stroked_box {\edef\p_framed_framecorner{\framedparameter\c!framecorner}% \ifx\p_framed_framecorner\v!rectangular \pack_framed_stroked_box_normal - \else - \pack_framed_stroked_box_radius - \fi} - -\def\pack_framed_stroked_box_radius - {\edef\p_framed_frameradius{\framedparameter\c!frameradius}% - \ifzeropt\dimexpr\p_framed_frameradius\relax % just in case of .x\bodyfontsize - \pack_framed_stroked_box_normal \orelse\ifx\p_framed_frame\v!on \pack_framed_stroked_box_round \fi} -% \pack_framed_stroked_box_normal % later - -\def\pack_framed_stroked_box_round - {\raise\d_framed_target_dp\hpack{\frule - width \d_framed_target_wd - height \d_framed_target_ht - depth \d_framed_target_dp - line \d_framed_linewidth - radius \p_framed_frameradius\space - corner {\p_framed_framecorner} +\def\pack_framed_stroked_box_round % todo: variant without keywords + {\raise\d_framed_target_dp + \hpack{\clf_roundedoutline % we could access these at the lua end! + \d_framed_target_wd + \d_framed_target_ht + \d_framed_target_dp + \d_framed_linewidth + \framedparameter\c!frameradius + {\p_framed_framecorner} \relax}} % a lot of weird corners diff --git a/tex/context/base/mkxl/page-lay.mkxl b/tex/context/base/mkxl/page-lay.mkxl index d56becbc6..5e2281a2f 100644 --- a/tex/context/base/mkxl/page-lay.mkxl +++ b/tex/context/base/mkxl/page-lay.mkxl @@ -814,6 +814,9 @@ \permanent\def\layoutcolumnoffset#1% can travel around so we can't use \lastnamedcs {\csname\??layoutcolumn\ifcsname\??layoutcolumn#1\endcsname#1\else0\fi\endcsname} +\permanent\protected\def\layoutlineoffset#1% + {\the\dimexpr\topskip-\strutht+#1\lineheight-\lineheight\relax} + \def\page_layouts_synchronize_at_start {\ifdim\makeupheight=\layoutlines\lineheight \else % weird check \page_layouts_synchronize diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl index 6ca9e5e55..c7d2fb657 100644 --- a/tex/context/base/mkxl/spac-ali.mkxl +++ b/tex/context/base/mkxl/spac-ali.mkxl @@ -827,6 +827,10 @@ \defcsname\??aligncommand\v!always\endcsname{\toksapp\t_spac_align_collected{\bitwiseflip\hyphenationmode\forcecheckhyphenationcode}} +% experiment + +\defcsname\??aligncommand\v!profile\endcsname{\toksapp\t_spac_align_collected{\setmainlineprofile}} + \definehspace [\v!final] [\emspaceamount] \def\spac_align_flush_parfill diff --git a/tex/context/base/mkxl/spac-prf.lmt b/tex/context/base/mkxl/spac-prf.lmt index c38cdc97b..66a75cba0 100644 --- a/tex/context/base/mkxl/spac-prf.lmt +++ b/tex/context/base/mkxl/spac-prf.lmt @@ -16,7 +16,6 @@ local formatters = string.formatters local nodecodes = nodes.nodecodes local gluecodes = nodes.gluecodes -local listcodes = nodes.listcodes local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc @@ -34,10 +33,14 @@ local leaders_code = gluecodes.leaders local lineskip_code = gluecodes.lineskip local baselineskip_code = gluecodes.baselineskip -local linelist_code = listcodes.line +local strutrule_code = nodes.rulecodes.strut +local linelist_code = nodes.listcodes.line local texlists = tex.lists local settexattribute = tex.setattribute +local texgetdimen = tex.getdimen + +local newindex = lua.newindex local nuts = nodes.nuts local tonut = nodes.tonut @@ -46,6 +49,7 @@ local tonode = nuts.tonode local getreplace = nuts.getreplace local getattr = nuts.getattr local getid = nuts.getid +local getboth = nuts.getboth local getnext = nuts.getnext local getprev = nuts.getprev local getsubtype = nuts.getsubtype @@ -59,6 +63,11 @@ local getwidth = nuts.getwidth local getheight = nuts.getheight local getdepth = nuts.getdepth local getboxglue = nuts.getboxglue +local effectiveglue = nuts.effectiveglue +local findattribute = nuts.findattribute + +local nextnode = nuts.traversers.node +local nextglue = nuts.traversers.glue local setlink = nuts.setlink local setlist = nuts.setlist @@ -76,6 +85,8 @@ local theprop = nuts.theprop local floor = math.floor local ceiling = math.ceil +local min = math.min +local max = math.max local new_rule = nuts.pool.rule local new_glue = nuts.pool.glue @@ -119,7 +130,7 @@ local function getprofile(line,step) return end - local glue_set, glue_order, glue_sign = getboxglue(line) +-- local glue_set, glue_order, glue_sign = getboxglue(line) local heights = { } local depths = { } @@ -140,71 +151,24 @@ local function getprofile(line,step) -- remember p - local function progress() - position = width - width = position + wd - p = floor((position - margin)/step + 0.5) - w = floor((width + margin)/step - 0.5) - if p < 0 then - p = 0 - end - if w < 0 then - w = 0 - end - if p > w then - w, p = p, w - end - if w > max then - for i=max+1,w+1 do - heights[i] = 0 - depths [i] = 0 - end - max = w - end - for i=p,w do - if ht > heights[i] then - heights[i] = ht - end - if dp > depths[i] then - depths[i] = dp - end - end - end - local function process(current) -- called nested in disc replace - while current do - local id = getid(current) + for current, id, subtype in nextnode, current do if id == glyph_code then wd, ht, dp = getwhd(current) - progress() elseif id == kern_code then wd = getkern(current) ht = 0 dp = 0 - progress() elseif id == disc_code then local replace = getreplace(current) if replace then process(replace) end + goto done elseif id == glue_code then - local width, stretch, shrink, stretch_order, shrink_order = getglue(current) - if glue_sign == 1 then - if stretch_order == glue_order then - wd = width + stretch * glue_set - else - wd = width - end - elseif glue_sign == 2 then - if shrink_order == glue_order then - wd = width - shrink * glue_set - else - wd = width - end - else - wd = width - end - if getsubtype(current) >= leaders_code then + wd = effectiveglue(current, line) -- geteffectivewhd + -- tricky + if subtype >= leaders_code then local leader = getleader(current) local w w, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 @@ -212,12 +176,11 @@ local function getprofile(line,step) ht = 0 dp = 0 end - progress() elseif id == hlist_code then + -- maybe: offsets -- we could do a nested check .. but then we need to push / pop glue local shift = getshift(current) local w, h, d = getwhd(current) - -- if getattr(current,a_specialcontent) then if getprop(current,"specialcontent") then -- like a margin note, maybe check for wd wd = w @@ -228,29 +191,49 @@ local function getprofile(line,step) ht = h - shift dp = d + shift end - progress() elseif id == vlist_code or id == unset_code then local shift = getshift(current) -- todo - wd, ht, dp = getwhd(current) - progress() + wd, ht, dp = getwhd(current) -- todo: use combined getter elseif id == rule_code then wd, ht, dp = getwhd(current) - progress() elseif id == math_code then + -- todo get glue wd = getkern(current) + getwidth(current) -- surround ht = 0 dp = 0 - progress() - elseif id == marginkern_code then - -- not in lmtx - wd = getwidth(current) - ht = 0 - dp = 0 - progress() else --- print(nodecodes[id]) + goto done end - current = getnext(current) + -- progress + position = width + width = position + wd + p = floor((position - margin)/step + 0.5) + w = floor((width + margin)/step - 0.5) + if p < 0 then + p = 0 + end + if w < 0 then + w = 0 + end + if p > w then + w, p = p, w + end + if w > max then + for i=max+1,w+1 do + heights[i] = 0 + depths [i] = 0 + end + max = w + end + for i=p,w do + if ht > heights[i] then + heights[i] = ht + end + if dp > depths[i] then + depths[i] = dp + end + end + ::done:: end end @@ -362,6 +345,7 @@ local function addprofile(node,profile,step) return end local what = nil + -- beware: basically end of line so we actually need to put it elsewhere if lastht == 0 and lastdp == 0 then what = new_kern(lastwd) else @@ -470,12 +454,17 @@ end -- lineskip | lineskiplimit local function inject(top,bot,amount) -- todo: look at penalties - local glue = new_glue(amount) - -- - setattr(glue,a_profilemethod,0) - setattr(glue,a_visual,getattr(top,a_visual)) - -- - setlink(top,glue,bot) + if amount ~= 0 then + local glue = new_glue(amount) + -- + setattr(glue,a_profilemethod,0) + -- setattr(glue,a_visual,getattr(top,a_visual)) + setattr(glue,a_visual,nodes.visualizers.modes.glue) + -- + setlink(top,glue,bot) + -- + report("injected correction %p at page",amount,tex.getcount("realpageno")) + end end methods[v_none] = function() @@ -487,8 +476,8 @@ methods[v_strict] = function(top,bot,t_profile,b_profile,specification) local top = tonut(top) local bot = tonut(bot) - local strutht = specification.height or texdimen.strutht - local strutdp = specification.depth or texdimen.strutdp + local strutht = specification.height or texgetdimen.strutht + local strutdp = specification.depth or texgetdimen.strutdp local lineheight = strutht + strutdp local depth = getdepth(top) @@ -523,8 +512,8 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) local top = tonut(top) local bot = tonut(bot) - local strutht = specification.height or texdimen.strutht - local strutdp = specification.depth or texdimen.strutdp + local strutht = specification.height or texgetdimen.strutht + local strutdp = specification.depth or texgetdimen.strutdp local lineheight = strutht + strutdp local depth = getdepth(top) @@ -545,7 +534,7 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) return true end - local delta = getdelta(t_profile,b_profile) + local delta = getdelta(t_profile,b_profile) local dp = strutdp while depth > lineheight - strutdp do @@ -642,8 +631,6 @@ end local function profilelist(line,mvl) - local current = line - local top = nil local bot = nil @@ -666,11 +653,8 @@ local function profilelist(line,mvl) pagehead, pagetail = getpagelist() if pagetail then - local current = pagetail - while current do - local id = getid(current) + for current, id, subtype in nextnode, pagetail do if id == hlist_code then - local subtype = getsubtype(current) if subtype == linelist_code then t_profile = hasprofile(current) if t_profile then @@ -690,13 +674,12 @@ local function profilelist(line,mvl) else break end - current = getnext(current) end end end - while current do + for current, id, subtype in nextnode, line do local attr = getattr(current,a_profilemethod) @@ -709,10 +692,7 @@ local function profilelist(line,mvl) lastattr = attr end - local id = getid(current) - if id == hlist_code then -- check subtype - local subtype = getsubtype(current) if subtype == linelist_code then if top == current then -- skip @@ -751,7 +731,6 @@ local function profilelist(line,mvl) end elseif id == glue_code then if top then - local subtype = getsubtype(current) -- if subtype == lineskip_code or subtype == baselineskip_code then local wd = getwidth(current) if wd > 0 then @@ -781,7 +760,6 @@ local function profilelist(line,mvl) top = nil bot = nil end - current = getnext(current) end if top then t_profile = setprofile(top) @@ -795,6 +773,8 @@ profiling.list = profilelist local enabled = false +-- todo: use attribute storage + function profiling.set(specification) if not enabled then enableaction("mvlbuilders", "builders.profiling.pagehandler") @@ -818,10 +798,8 @@ function profiling.profilebox(specification) local action = method and methods[method] or methods[v_strict] local lastglue = nil local distance = 0 - while current do - local id = getid(current) + for current, id, subtype in nextnode, current do if id == hlist_code then - local subtype = getsubtype(current) if subtype == linelist_code then if top then bot = current @@ -855,7 +833,6 @@ function profiling.profilebox(specification) bot = nil end elseif id == glue_code then - local subtype = getsubtype(current) if subtype == lineskip_code or subtype == baselineskip_code then if top then local wd = getwidth(current) @@ -882,7 +859,6 @@ function profiling.profilebox(specification) top = nil bot = nil end - current = getnext(current) end if top then @@ -947,3 +923,367 @@ interfaces.implement { } } } + +-- The following is an experiment that I picked up after demoing this already old but never +-- used feature and in the process it got applied to document of hundreds of pages. Actually +-- performance is quite okay but this mechanism is not really meant for that scenario. We'll +-- see where this ends. We could (an d might) integrate it in the above but the next is more +-- lightweight while the previous was basically some exploration with lots of options. + +do + + -- we could share the two arrays if needed + + local a_lineprofile = attributes.private("lineprofile") + + local registervalue = attributes.registervalue + local getvalue = attributes.getvalue + local texsetattribute = tex.setattribute + + local function getdepthprofile(line,step,margin,max,list) + + local width = 0 + local position = 0 + local profile = newindex(max+2,0) + local wd = 0 + local ht = 0 + local dp = 0 + + profile[0] = 0 + + local function process(current) -- called nested in disc replace + for current, id, subtype in nextnode, current do + if id == glyph_code then + wd, ht, dp = getwhd(current) + elseif id == kern_code then + wd = getkern(current) + dp = 0 + elseif id == disc_code then + local replace = getreplace(current) + if replace then + process(replace) + end + goto done + elseif id == glue_code then + wd = effectiveglue(current, line) -- geteffectivewhd + -- tricky + if subtype >= leaders_code then + local leader = getleader(current) + local w + w, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 + else + dp = 0 + end + elseif id == hlist_code then + -- maybe: offsets + -- we could do a nested check .. but then we need to push / pop glue + local shift = getshift(current) + local w, h, d = getwhd(current) + if getprop(current,"specialcontent") then + -- like a margin note, maybe check for wd + wd = w + dp = 0 + else + wd = w + dp = d + shift + end + elseif id == vlist_code then + local shift = getshift(current) -- todo + wd, ht, dp = getwhd(current) -- todo: use combined getter + elseif id == rule_code then + if subtype == strutrule_code then + dp = 0 + else + wd, ht, dp = getwhd(current) + end + elseif id == math_code then + -- todo get glue + wd = getkern(current) + getwidth(current) -- surround + dp = 0 + else + goto done + end + -- progress + position = width + width = position + wd + p = floor((position - margin)/step + 0.5) + w = floor((width + margin)/step - 0.5) + if p < 0 then + p = 0 + end + if w < 0 then + w = 0 + end + if p > w then + w, p = p, w + end + if w > max then + for i=max+1,w+1 do + profile[i] = 0 + end + max = w + end + for i=p,w do + if dp > profile[i] then + profile[i] = dp + end + end + ::done:: + end + end + + process(list) + + return profile + + end + + local function getheightprofile(line,step,margin,max,list) + + local width = 0 + local position = 0 + local profile = newindex(max+2,0) + local wd = 0 + local ht = 0 + local dp = 0 + + profile[0] = 0 + + local function process(current) -- called nested in disc replace + for current, id, subtype in nextnode, current do + if id == glyph_code then + wd, ht, dp = getwhd(current) + elseif id == kern_code then + wd = getkern(current) + ht = 0 + elseif id == disc_code then + local replace = getreplace(current) + if replace then + process(replace) + end + goto done + elseif id == glue_code then + wd = effectiveglue(current, line) -- geteffectivewhd + -- tricky + if subtype >= leaders_code then + local leader = getleader(current) + local w + w, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 + else + ht = 0 + end + elseif id == hlist_code then + -- maybe: offsets + -- we could do a nested check .. but then we need to push / pop glue + local shift = getshift(current) + local w, h, d = getwhd(current) + if getprop(current,"specialcontent") then + -- like a margin note, maybe check for wd + wd = w + ht = 0 + else + wd = w + ht = h - shift + end + elseif id == vlist_code then + local shift = getshift(current) -- todo + wd, ht, dp = getwhd(current) -- todo: use combined getter + elseif id == rule_code then + if subtype == strutrule_code then + ht = 0 + else + wd, ht, dp = getwhd(current) + end + elseif id == math_code then + -- todo get glue + wd = getkern(current) + getwidth(current) -- surround + ht = 0 + else + goto done + end + -- progress + position = width + width = position + wd + p = floor((position - margin)/step + 0.5) + w = floor((width + margin)/step - 0.5) + if p < 0 then + p = 0 + end + if w < 0 then + w = 0 + end + if p > w then + w, p = p, w + end + if w > max then + for i=max+1,w+1 do + profile[i] = 0 + end + max = w + end + for i=p,w do + if ht > profile[i] then + profile[i] = ht + end + end + ::done:: + end + end + + process(list) + + return profile + + end + + local show_lineprofile = false + local show_linedetails = false + + trackers.register("profiling.lines.show", function(v) + local visualizers = nodes.visualizers + glue_mode = visualizers.modes.glue + line_mode = visualizers.modes.line + show_lineprofile = v + visualizers.enable() + end) + + trackers.register("profiling.lines.details", function(v) + show_linedetail = v + end) + + local defaultstep = 65536 * 2 -- 2pt + local defaultmethod = "a" + local defaultfactor = 1 + + -- I played with different methods (like only get depths and then on the fly check with heights + -- but there is no gain and it is also fuzzy. So for now we just do the whole scan. + + function profilelines(list) + + if not list then + return + end + + local _, start = findattribute(list,a_lineprofile) + if not start then + return + end + + -- no height or depth ... skip + + for current, subtype in nextglue, start do + if subtype == lineskip_code and not getprop(current,"profiled") then + local detail = getattr(current,a_lineprofile) + if detail then + -- + local amount = getwidth(current) + -- + local top, bot = getboth(current) + setprop(current,"profiled",amount) -- original amount + if top then + if getid(top) == penalty_code then + top = getprev(top) + end + if top and bot then + if getid(top) == hlist_code and getsubtype(top) == linelist_code then + if getid(bot) == hlist_code and getsubtype(bot) == linelist_code then + local toplist = getlist(top) + local botlist = getlist(bot) + if toplist and botlist then + -- + local detail = getvalue(a_lineprofile,detail) or { } + local step = detail.step or defaultstep + local factor = tonumber(detail.factor) or defaultfactor + local method = detail.method or defaultmethod + local margin = step / 4 + -- + if factor > 1 then + factor = 1 + elseif factor <= 0 then + factor = 0 -- we could actually go the other way + end + -- + local natural = getdepth(top) + getheight(bot) + local added = factor * amount + local possible = natural - added + local overshoot = 0 + local topmax = ceiling(getwidth(top)/step) + 1 + local botmax = ceiling(getwidth(bot)/step) + 1 + -- if method == "a" then + local depths = getdepthprofile (top,step,margin,topmax,toplist) + local heights = getheightprofile(bot,step,margin,botmax,botlist) + local steps = min(#depths,#heights) + for i=1,steps do + local o = heights[i] + depths[i] - possible + if o > overshoot then + -- we can quit when >= added + overshoot = o +-- if overshoot > added then +-- break +-- end + end + end + -- end + -- if overshoot < added / 2 then + -- overshoot = added / 2 + -- end + if overshoot ~= amount then -- shouldn't we round + setwidth(current,overshoot) + if show_lineprofile then + setattr(current,a_visual,glue_mode) + setattr(bot,a_visual,line_mode) + setattr(top,a_visual,line_mode) + end + if show_linedetail then + report("lineskip changed from %p to %p on page %i",amount,overshoot,tex.getcount("realpageno")) + end + end + end + end + end + end + end + end + end + end + end + + builders.profiling.profilelines = profilelines + + function profiling.boxlinehandler(head) + if head then + profilelines(head) + end + return head + end + + function profiling.pagelinehandler(head) + if head then + profilelines(head) + end + return head + end + + function profiling.setlines(specification) + if not enabled then + enableaction("mvlbuilders", "builders.profiling.pagelinehandler") + enableaction("vboxbuilders", "builders.profiling.boxlinehandler") + enabled = true + end + texsetattribute(a_lineprofile,registervalue(a_lineprofile,specification)) + end + + interfaces.implement { + name = "setlineprofile", + actions = profiling.setlines, + arguments = { + { + { "name" }, + { "method" }, + { "step", "dimension" }, + { "factor" }, + } + } + } + +end diff --git a/tex/context/base/mkxl/spac-prf.mklx b/tex/context/base/mkxl/spac-prf.mklx index 824b14ca7..fc3e4ae22 100644 --- a/tex/context/base/mkxl/spac-prf.mklx +++ b/tex/context/base/mkxl/spac-prf.mklx @@ -20,11 +20,7 @@ \unprotect -\doiffileelse{spac-prf-new.lmt}{ - \registerctxluafile{spac-prf-new}{autosuffix} -} { - \registerctxluafile{spac-prf}{autosuffix} -} +\registerctxluafile{spac-prf}{autosuffix} \definesystemattribute[profilemethod][public] @@ -86,7 +82,7 @@ \edef\currentprofile{#profile}% \fi \spac_profile_set - \par + \profileparameter\c!before} \protected\def\spac_profile_stop @@ -150,4 +146,40 @@ \defineprofile[quarterfixed][\v!fixed][\c!factor=\plusfour] \defineprofile[eightsfixed] [\v!fixed][\c!factor=\pluseight] +% Finally some follow up on this experiment: + +\definesystemattribute[lineprofile] [public] + +\installcorenamespace {lineprofile} + +\installcommandhandler \??lineprofile {lineprofile} \??lineprofile + +\setuplineprofile + [\c!method=\v!a, + \c!step=.5\emwidth, % maybe 2pt + \c!factor=.125] % maybe 0.250 + +\def\spac_line_profile_set + {\clf_setlineprofile + name {\currentlineprofile}% + step \dimexpr\lineprofileparameter\c!step\relax + factor {\lineprofileparameter\c!factor} + method {\lineprofileparameter\c!method}% + \relax} + +\permanent\tolerant\protected\def\setlineprofile[#profile]% + {\edef\currentlineprofile{#profile}% + \spac_line_profile_set} + +\permanent\protected\def\resetlineprofile + {\c_attr_lineprofile\attributeunsetvalue} + +\permanent\protected\def\setmainlineprofile + {\lettonothing\currentlineprofile + \clf_setlineprofile} + +\appendtoks + \c_attr_lineprofile\attributeunsetvalue % or in general resetter +\to \everyforgetall + \protect \endinput diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt index 01690b7ae..a0b1d5a94 100644 --- a/tex/context/base/mkxl/spac-ver.lmt +++ b/tex/context/base/mkxl/spac-ver.lmt @@ -117,6 +117,8 @@ local d_globalbodyfontstrutdepth = tex.isdimen("globalbodyfontstrutdepth") ----- d_strutht = tex.isdimen("strutht") local d_strutdp = tex.isdimen("strutdp") +local d_spac_overlay = tex.isdimen("d_spac_overlay") + local nuts = nodes.nuts local tonut = nuts.tonut @@ -1455,7 +1457,7 @@ do end -- local delta = n_ht + skips + p_dp - texsetdimen("global","d_spac_overlay",-delta) -- for tracing + texsetdimen("global",d_spac_overlay,-delta) -- for tracing -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak local k = new_kern(-delta) setvisual(k) diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl index 89632bd84..76dc97dc5 100644 --- a/tex/context/base/mkxl/spac-ver.mkxl +++ b/tex/context/base/mkxl/spac-ver.mkxl @@ -20,10 +20,11 @@ \newdimen \bodyfontstrutdepth \newgluespec\globalbodyfontlineheight % why a skip -\newdimen \globalbodyfontstrutheight +\newdimen \globalbodyfontstrutheight \newdimen \globalbodyfontstrutdepth -\newgluespec\s_spac_vspacing_predefined +\newgluespec \s_spac_vspacing_predefined +\newdimension\d_spac_overlay % \overloaded\let\strutht \undefined \newdimen\strutht % already defined % \overloaded\let\strutdp \undefined \newdimen\strutdp @@ -2020,8 +2021,6 @@ %D used in itemize \unknown\ always test this: -\newdimension\d_spac_overlay - \def\spac_overlay_lines {\directcheckedvspacing{\v!back,\v!overlay}% \blank[\v!back,\v!overlay]% \nointerlineskip} diff --git a/tex/context/base/mkxl/strc-mat.mkxl b/tex/context/base/mkxl/strc-mat.mkxl index 025021edb..86e77e63c 100644 --- a/tex/context/base/mkxl/strc-mat.mkxl +++ b/tex/context/base/mkxl/strc-mat.mkxl @@ -1352,13 +1352,6 @@ % a limitation is that this only works in a regular setting, so no shapes -\newinteger \c_strc_math_n_of_lines -\newdimension\d_strc_math_max_width -\newdimension\d_strc_math_first_width -\newdimension\d_strc_math_last_width -\newdimension\d_strc_math_first_height -\newdimension\d_strc_math_last_depth - \appendtoks \global\d_strc_math_indent \zeropoint \global\c_strc_math_n_of_lines \zerocount diff --git a/tex/context/base/mkxl/strc-tag.lmt b/tex/context/base/mkxl/strc-tag.lmt index 2a0699924..ec6455cc6 100644 --- a/tex/context/base/mkxl/strc-tag.lmt +++ b/tex/context/base/mkxl/strc-tag.lmt @@ -182,34 +182,34 @@ local properties = allocate { -- todo: more "record = true" to improve forma margintext = { pdf = "Span", nature = "inline" }, marginanchor = { pdf = "Span", nature = "inline" }, - math = { pdf = "Div", nature = "inline" }, -- no display - mn = { pdf = "Span", nature = "mixed" }, - mi = { pdf = "Span", nature = "mixed" }, - mo = { pdf = "Span", nature = "mixed" }, - ms = { pdf = "Span", nature = "mixed" }, - mrow = { pdf = "Span", nature = "display" }, - msubsup = { pdf = "Span", nature = "display" }, - msub = { pdf = "Span", nature = "display" }, - msup = { pdf = "Span", nature = "display" }, - merror = { pdf = "Span", nature = "mixed" }, - munderover = { pdf = "Span", nature = "display" }, - munder = { pdf = "Span", nature = "display" }, - mover = { pdf = "Span", nature = "display" }, - mtext = { pdf = "Span", nature = "mixed" }, - mfrac = { pdf = "Span", nature = "display" }, - mroot = { pdf = "Span", nature = "display" }, - msqrt = { pdf = "Span", nature = "display" }, - mfenced = { pdf = "Span", nature = "display" }, - maction = { pdf = "Span", nature = "display" }, + math = { pdf = "Div", nature = "inline", namespace = "mathml" }, -- no display + mn = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + mi = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + mo = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + ms = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + mrow = { pdf = "Span", nature = "display", namespace = "mathml" }, + msubsup = { pdf = "Span", nature = "display", namespace = "mathml" }, + msub = { pdf = "Span", nature = "display", namespace = "mathml" }, + msup = { pdf = "Span", nature = "display", namespace = "mathml" }, + merror = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + munderover = { pdf = "Span", nature = "display", namespace = "mathml" }, + munder = { pdf = "Span", nature = "display", namespace = "mathml" }, + mover = { pdf = "Span", nature = "display", namespace = "mathml" }, + mtext = { pdf = "Span", nature = "mixed", namespace = "mathml" }, + mfrac = { pdf = "Span", nature = "display", namespace = "mathml" }, + mroot = { pdf = "Span", nature = "display", namespace = "mathml" }, + msqrt = { pdf = "Span", nature = "display", namespace = "mathml" }, + mfenced = { pdf = "Span", nature = "display", namespace = "mathml" }, + maction = { pdf = "Span", nature = "display", namespace = "mathml" }, mstacker = { pdf = "Span", nature = "display" }, -- these are only internally used mstackertop = { pdf = "Span", nature = "display" }, -- these are only internally used mstackerbot = { pdf = "Span", nature = "display" }, -- these are only internally used mstackermid = { pdf = "Span", nature = "display" }, -- these are only internally used - mtable = { pdf = "Table", nature = "display" }, -- might change - mtr = { pdf = "TR", nature = "display" }, -- might change - mtd = { pdf = "TD", nature = "display" }, -- might change + mtable = { pdf = "Table", nature = "display", namespace = "mathml" }, -- might change + mtr = { pdf = "TR", nature = "display", namespace = "mathml" }, -- might change + mtd = { pdf = "TD", nature = "display", namespace = "mathml" }, -- might change ignore = { pdf = "Span", nature = "mixed" }, -- used internally private = { pdf = "Span", nature = "mixed" }, -- for users (like LS) when they need it @@ -576,7 +576,8 @@ implement { public = true, protected = true, actions = tags.setproperty, - arguments = { "optional", "'backend'", "optional" }, +-- arguments = { "optional", "'backend'", "optional" }, + arguments = { "optional", "'pdf'", "optional" }, } implement { diff --git a/tex/context/base/mkxl/supp-box.lmt b/tex/context/base/mkxl/supp-box.lmt index 28c1d44f9..a5bfe1394 100644 --- a/tex/context/base/mkxl/supp-box.lmt +++ b/tex/context/base/mkxl/supp-box.lmt @@ -101,9 +101,18 @@ local setlistcolor = nodes.tracers.colors.setlist local texget = tex.get local texgetbox = tex.getbox +local texisdimen = tex.isdimen local texsetdimen = tex.setdimen local texgetnest = tex.getnest +local d_lastnaturalboxwd = texisdimen("lastnaturalboxwd") +local d_lastnaturalboxht = texisdimen("lastnaturalboxht") +local d_lastnaturalboxdp = texisdimen("lastnaturalboxdp") + +local d_givenwidth = texisdimen("givenwidth") +local d_givenheight = texisdimen("givenheight") +local d_givendepth = texisdimen("givendepth") + local function hyphenatedlist(head,usecolor) local current = head and tonut(head) while current do @@ -409,9 +418,9 @@ do if l then w, h, d = getdimensions(l) end - texsetdimen("lastnaturalboxwd",w) - texsetdimen("lastnaturalboxht",h) - texsetdimen("lastnaturalboxdp",d) + texsetdimen(d_lastnaturalboxwd,w) + texsetdimen(d_lastnaturalboxht,h) + texsetdimen(d_lastnaturalboxdp,d) return w, h, d end @@ -845,9 +854,9 @@ implement { }, }, actions = function(t) - texsetdimen("givenwidth", t.width or 0) - texsetdimen("givenheight",t.height or 0) - texsetdimen("givendepth", t.depth or 0) + texsetdimen(d_givenwidth, t.width or 0) + texsetdimen(d_givenheight,t.height or 0) + texsetdimen(d_givendepth, t.depth or 0) end, } diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl index bbbc7591e..802815416 100644 --- a/tex/context/base/mkxl/supp-box.mkxl +++ b/tex/context/base/mkxl/supp-box.mkxl @@ -15,8 +15,6 @@ \unprotect -\registerctxluafile{supp-box}{autosuffix,optimize} - \permanent\integerdef\negatelistsigncode\numexpr \negatexlistsigncode +\negateylistsigncode @@ -32,6 +30,12 @@ \newdimension\givenheight \newdimension\givendepth +\newdimension\lastnaturalboxwd % maybe alias ! +\newdimension\lastnaturalboxht +\newdimension\lastnaturalboxdp + +\registerctxluafile{supp-box}{autosuffix,optimize} + % \fixupboxesmode\plusone % gone: is now the default %D This module implements some box manipulation macros. Some are quite simple, some @@ -2761,9 +2765,9 @@ %D \setbox0\hbox to 10cm{foo} \the\naturalwd0 %D \stoptyping -\newdimension\lastnaturalboxwd -\newdimension\lastnaturalboxht -\newdimension\lastnaturalboxdp +% \newdimension\lastnaturalboxwd +% \newdimension\lastnaturalboxht +% \newdimension\lastnaturalboxdp %D We can define these public in lua: diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl index eec1edf9c..d4ad013d5 100644 --- a/tex/context/base/mkxl/tabl-tbl.mkxl +++ b/tex/context/base/mkxl/tabl-tbl.mkxl @@ -1227,8 +1227,11 @@ \def\tabl_tabulate_start_foot_yes[#1]% {\processcontent{\e!stop\v!tabulatetail}\m_tabl_tabulate_data{\letcsname\??tabulatefoot#1\endcsname\m_tabl_tabulate_data}} -\def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[\v!tabulate]} -\def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[\v!tabulate]} +% \def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[\v!tabulate]} +% \def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[\v!tabulate]} + +\def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[]} +\def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[]} \protected\def\tabl_start_defined[#1]% {\bgroup @@ -2100,7 +2103,16 @@ % % can we omit the next one in the first run? probably % \noalign{\the\t_tabl_tabulate_every_after_row#2}} -\permanent\tolerant\protected\def\tabl_tabulate_NR_common#1#2#.#3% #. gobbles pars and spaces +% test case for ignorepar error +% +% \starttabulatehead +% \NC A \NC B \NC \NR +% \stoptabulatehead +% \starttabulate[|l|l|] +% \NC 1 \NC 2 \NC \NR +% \stoptabulate + +\permanent\tolerant\protected\def\tabl_tabulate_NR_common#1#2% #. gobbles pars and spaces {\global\advanceby\c_tabl_tabulate_noflines\plusone \global\setfalse\c_tabl_tabulate_firstflushed \global\setfalse\c_tabl_tabulate_equal @@ -2111,7 +2123,8 @@ \tabl_tabulate_pheight_reset \unskip\unskip\crcr\tabl_tabulate_flush_collected % can we omit the next one in the first run? probably - \noalign{\the\t_tabl_tabulate_every_after_row#2}#3} + % todo: move \ignorepars ourside so no alignment error then + \noalign{\the\t_tabl_tabulate_every_after_row#2\ignorepars}} \def\tabl_tabulate_check_penalties {\ifconditional\c_tabl_tabulate_tolerant_break\else diff --git a/tex/context/base/mkxl/tabl-xtb.lmt b/tex/context/base/mkxl/tabl-xtb.lmt index 3d91ccb85..2a3b9a3b0 100644 --- a/tex/context/base/mkxl/tabl-xtb.lmt +++ b/tex/context/base/mkxl/tabl-xtb.lmt @@ -37,8 +37,10 @@ local implement = interfaces.implement local tex = tex local texgetcount = tex.getcount local texsetcount = tex.setcount +local texiscount = tex.iscount local texgetdimen = tex.getdimen local texsetdimen = tex.setdimen +local texisdimen = tex.isdimen local texget = tex.get local format = string.format @@ -108,7 +110,19 @@ local report_xtable = logs.reporter("xtable") trackers.register("xtable.construct", function(v) trace_xtable = v end) -local null_mode = 0 +local c_tabl_x_nx = texiscount("c_tabl_x_nx") +local c_tabl_x_ny = texiscount("c_tabl_x_ny") +local c_tabl_x_state = texiscount("c_tabl_x_state") +local c_tabl_x_mode = texiscount("c_tabl_x_mode") +local c_tabl_x_skip_mode = texiscount("c_tabl_x_skip_mode") +local d_tabl_x_final_width = texisdimen("d_tabl_x_final_width") +local d_tabl_x_distance = texisdimen("d_tabl_x_distance") +local d_tabl_x_width = texisdimen("d_tabl_x_width") +local d_tabl_x_height = texisdimen("d_tabl_x_height") +local d_tabl_x_depth = texisdimen("d_tabl_x_depth") + +local c_frameddimensionstate = texiscount("frameddimensionstate") + local head_mode = 1 local foot_mode = 2 local more_mode = 3 @@ -228,10 +242,10 @@ function xtables.initialize_reflow_width(option,width) local r = data.currentrow local c = data.currentcolumn + 1 local drc = data.rows[r][c] - drc.nx = texgetcount("c_tabl_x_nx") - drc.ny = texgetcount("c_tabl_x_ny") + drc.nx = texgetcount(c_tabl_x_nx) + drc.ny = texgetcount(c_tabl_x_ny) local distances = data.distances - local distance = texgetdimen("d_tabl_x_distance") + local distance = texgetdimen(d_tabl_x_distance) if distance > distances[c] then distances[c] = distance end @@ -419,21 +433,21 @@ function xtables.initialize_reflow_height() for x=1,drc.nx-1 do w = w + widths[c+x] end - texsetdimen("d_tabl_x_width",w) + texsetdimen(d_tabl_x_width,w) local dimensionstate = drc.dimensionstate or 0 if dimensionstate == 1 or dimensionstate == 3 then -- width was fixed so height is known - texsetcount("c_tabl_x_skip_mode",1) + texsetcount(c_tabl_x_skip_mode,1) elseif dimensionstate == 2 then -- height is enforced - texsetcount("c_tabl_x_skip_mode",1) + texsetcount(c_tabl_x_skip_mode,1) elseif data.autowidths[c] then -- width has changed so we need to recalculate the height - texsetcount("c_tabl_x_skip_mode",0) + texsetcount(c_tabl_x_skip_mode,0) elseif data.fixedcolumns[c] then - texsetcount("c_tabl_x_skip_mode",0) -- new + texsetcount(c_tabl_x_skip_mode,0) -- new else - texsetcount("c_tabl_x_skip_mode",1) + texsetcount(c_tabl_x_skip_mode,1) end end @@ -524,9 +538,9 @@ function xtables.initialize_construct() end end -- - texsetdimen("d_tabl_x_width",width) - texsetdimen("d_tabl_x_height",total) - texsetdimen("d_tabl_x_depth",0) -- for now + texsetdimen(d_tabl_x_width,width) + texsetdimen(d_tabl_x_height,total) + texsetdimen(d_tabl_x_depth,0) -- for now end function xtables.set_construct() @@ -936,11 +950,11 @@ function xtables.construct() [body_mode] = body, } if #body == 0 then - texsetcount("global","c_tabl_x_state",0) - texsetdimen("global","d_tabl_x_final_width",0) + texsetcount("global",c_tabl_x_state,0) + texsetdimen("global",d_tabl_x_final_width,0) else - texsetcount("global","c_tabl_x_state",1) - texsetdimen("global","d_tabl_x_final_width",getwidth(body[1][1])) + texsetcount("global",c_tabl_x_state,1) + texsetdimen("global",d_tabl_x_final_width,getwidth(body[1][1])) end end @@ -1105,7 +1119,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. results[foot_mode] = { } end results[body_mode] = { } - texsetcount("global","c_tabl_x_state",0) + texsetcount("global",c_tabl_x_state,0) else -- some is left so footer is delayed -- todo: try to flush a few more lines @@ -1119,7 +1133,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. else -- todo: try to fit more of body end - texsetcount("global","c_tabl_x_state",2) + texsetcount("global",c_tabl_x_state,2) end else if firstsize > height then @@ -1130,10 +1144,10 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. bodystart = bodystart + 1 end end - texsetcount("global","c_tabl_x_state",2) -- 1 + texsetcount("global",c_tabl_x_state,2) -- 1 end else - texsetcount("global","c_tabl_x_state",0) + texsetcount("global",c_tabl_x_state,0) end data.bodystart = bodystart data.bodystop = bodystop @@ -1179,7 +1193,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. results[head_mode] = { } results[body_mode] = { } results[foot_mode] = { } - texsetcount("global","c_tabl_x_state",0) + texsetcount("global",c_tabl_x_state,0) end end @@ -1209,7 +1223,7 @@ end function xtables.next_row(specification) local r = data.currentrow + 1 - data.modes[r] = texgetcount("c_tabl_x_mode") + data.modes[r] = texgetcount(c_tabl_x_mode) data.currentrow = r data.currentcolumn = 0 data.rowproperties[r] = specification diff --git a/tex/context/base/mkxl/task-ini.lmt b/tex/context/base/mkxl/task-ini.lmt index 17555d7e2..0e96c1e8e 100644 --- a/tex/context/base/mkxl/task-ini.lmt +++ b/tex/context/base/mkxl/task-ini.lmt @@ -149,6 +149,7 @@ appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox", ------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler", nil, "nut", "disabled" ) appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler", nil, "nut", "enabled" ) appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler", nil, "nut", "disabled" ) +appendaction("vboxbuilders", "normalizers", "builders.profiling.boxlinehandler", nil, "nut", "disabled" ) appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) appendaction("vboxbuilders", "normalizers", "typesetters.synchronize.handler", nil, "nut", "disabled" ) @@ -157,6 +158,7 @@ appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler", appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate", nil, "nut", "disabled" ) appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler", nil, "nut", "enabled" ) appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "builders.profiling.pagelinehandler", nil, "nut", "disabled" ) appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) appendaction("mvlbuilders", "normalizers", "typesetters.synchronize.handler", nil, "nut", "disabled" ) diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt index 0cf6cb6a3..68310ef69 100644 --- a/tex/context/base/mkxl/trac-vis.lmt +++ b/tex/context/base/mkxl/trac-vis.lmt @@ -93,6 +93,7 @@ local pt_factor = number.dimenfactors.pt local nodepool = nuts.pool local new_rule = nodepool.rule +local new_virtual_rule = nodepool.virtualrule local new_kern = nodepool.kern local new_glue = nodepool.glue local new_hlist = nodepool.hlist @@ -249,6 +250,12 @@ local function enable() tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end end +function visualizers.enable() + if not enabled then + enable() + end +end + local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in if not n or n == "reset" then return unsetvalue @@ -400,33 +407,88 @@ directives.register("visualizers.fraction", function(v) fraction = (v and tonumb -- ... if okay it will replace the current hpack_string in node_typ +-- local function sometext(str,layer,color,textcolor,lap,variant) +-- local text = hpack_string(str,usedfont) +-- local size = getwidth(text) +-- local rule = new_rule(size,2*exheight,exheight/2) +-- local kern = new_kern(-size) +-- if color then +-- setcolor(rule,color) +-- end +-- if textcolor then +-- setlistcolor(getlist(text),textcolor) +-- end +-- local info = setlink(rule,kern,text) +-- setlisttransparency(info,"trace:g") +-- info = hpack_nodes(info) +-- local width = getwidth(info) +-- if variant then +-- setoffsets(info,0,variant*exheight) +-- end +-- if lap then +-- info = new_hlist(setlink(new_kern(-width),info)) -- use xoffset and set info wd to 0 +-- else +-- info = new_hlist(info) -- a bit overkill: double wrapped +-- end +-- if layer then +-- setattr(info,a_layer,layer) +-- end +-- return info, width +-- end + +-- local function sometext(str,layer,color,textcolor,lap,variant) +-- local text = hpack_string(str,usedfont) +-- local size = getwidth(text) +-- local rule = new_virtual_rule(size,2*exheight,exheight/2) +-- if color then +-- setcolor(rule,color) +-- end +-- if textcolor then +-- setlistcolor(getlist(text),textcolor) +-- end +-- local info = setlink(rule,text) +-- setlisttransparency(info,"trace:g") +-- info = hpack_nodes(info) +-- if variant then +-- setoffsets(info,0,variant*exheight) +-- end +-- info = new_hlist(info) -- a bit overkill: double wrapped +-- if lap then +-- setoffsets(info,-size) +-- end +-- if layer then +-- setattr(info,a_layer,layer) +-- end +-- return info, size +-- end + local function sometext(str,layer,color,textcolor,lap,variant) local text = hpack_string(str,usedfont) local size = getwidth(text) - local rule = new_rule(size,2*exheight,exheight/2) - local kern = new_kern(-size) + local rule = new_virtual_rule(size,2*exheight,exheight/2) if color then setcolor(rule,color) end if textcolor then setlistcolor(getlist(text),textcolor) end - local info = setlink(rule,kern,text) + local info = setlink(rule,text) setlisttransparency(info,"trace:g") - info = hpack_nodes(info) - local width = getwidth(info) + info = new_hlist(info) + local x, y + if lap then + x = -size + end if variant then - setoffsets(info,0,variant*exheight) + y = variant * exheight end - if lap then - info = new_hlist(setlink(new_kern(-width),info)) - else - info = new_hlist(info) -- a bit overkill: double wrapped + if x or y then + setoffsets(info,x,y) end if layer then setattr(info,a_layer,layer) end - return info, width + return info, size end local function someblob(str,layer,color,textcolor,width) diff --git a/tex/context/base/mkxl/trac-vis.mkxl b/tex/context/base/mkxl/trac-vis.mkxl index 3b088d05f..ec51ad4b0 100644 --- a/tex/context/base/mkxl/trac-vis.mkxl +++ b/tex/context/base/mkxl/trac-vis.mkxl @@ -32,13 +32,13 @@ \writestatus{loading}{ConTeXt Tracing Macros / Visualization} -\registerctxluafile{trac-vis}{autosuffix} - \unprotect \newconstant\c_syst_visualizers_state \newtoks \t_syst_visualizers_optimize +\registerctxluafile{trac-vis}{autosuffix} + % \definesystemattribute[visual][public,global] % already defined % no, but can become an option: diff --git a/tex/context/base/mkxl/typo-ada.lmt b/tex/context/base/mkxl/typo-ada.lmt index 17e18f01e..37393ca77 100644 --- a/tex/context/base/mkxl/typo-ada.lmt +++ b/tex/context/base/mkxl/typo-ada.lmt @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['typo-adj'] = { } local setdimen = tex.setdimen -local setcount = tex.setcount +local isdimen = tex.isdimen local setmacro = tokens.setters.macro local expandmacro = token.expandmacro @@ -46,7 +46,12 @@ local adaptive = nodes.adaptive or { } nodes.adaptive = adaptive local enabled = false -local enableaction = nodes.tasks.enableaction +local enableaction = nodes.tasks.enableaction + +local d_adaptive_width = isdimen("d_adaptive_width") +local d_adaptive_height = isdimen("d_adaptive_height") +local d_adaptive_depth = isdimen("d_adaptive_depth") +local d_adaptive_line = isdimen("d_adaptive_line") function adaptive.set(settings) if not enabled then @@ -58,10 +63,10 @@ function adaptive.set(settings) end local function setadaptive(w,h,d,l,c) - setdimen("d_adaptive_width",w) - setdimen("d_adaptive_height",h) - setdimen("d_adaptive_depth",d) - setdimen("d_adaptive_line",l) + setdimen(d_adaptive_width,w) + setdimen(d_adaptive_height,h) + setdimen(d_adaptive_depth,d) + setdimen(d_adaptive_line,l) setmacro("m_adaptive_color",c) end diff --git a/tex/context/base/mkxl/typo-ada.mkxl b/tex/context/base/mkxl/typo-ada.mkxl index 6e686a932..733b2ca5b 100644 --- a/tex/context/base/mkxl/typo-ada.mkxl +++ b/tex/context/base/mkxl/typo-ada.mkxl @@ -13,8 +13,6 @@ \writestatus{loading}{ConTeXt Typesetting Macros / Adaptive} -\registerctxluafile{typo-ada}{autosuffix} - % Musical timestamp: the postponed by COVID concert of Gazpacho in Zwolle NL: a joy % to see dedicated and talented musicians perform their work in perfection and as a % well balanced and equiped team. @@ -36,6 +34,8 @@ \aliasdimension\usedadaptiveline \d_adaptive_line \aliasdimension\usedadaptivehsize \d_adaptive_hsize +\registerctxluafile{typo-ada}{autosuffix} + \aliased\let\usedadaptivebox\b_adaptive_box \mutable\lettonothing\m_adaptive_color diff --git a/tex/context/base/mkxl/typo-chr.lmt b/tex/context/base/mkxl/typo-chr.lmt index 160981ab7..56218440f 100644 --- a/tex/context/base/mkxl/typo-chr.lmt +++ b/tex/context/base/mkxl/typo-chr.lmt @@ -228,6 +228,8 @@ interfaces.implement { -- not needed in lmtx ... +local c_syst_last_node_id = tex.iscount("c_syst_last_node_id") + interfaces.implement { name = "lastnodeid", actions = function() @@ -239,7 +241,7 @@ interfaces.implement { okay = tail.id end end - texsetcount("c_syst_last_node_id",okay) + texsetcount(c_syst_last_node_id,okay) end, } diff --git a/tex/context/base/mkxl/typo-chr.mkxl b/tex/context/base/mkxl/typo-chr.mkxl index e59be1e29..ad5314801 100644 --- a/tex/context/base/mkxl/typo-chr.mkxl +++ b/tex/context/base/mkxl/typo-chr.mkxl @@ -33,6 +33,8 @@ %D for instance when combining bit and pieces where keeping a state is complex compared %D to cleaning up unwanted stuff. +\newinteger\c_syst_last_node_id + \registerctxluafile{typo-chr}{autosuffix} \definesystemattribute[marked][public] @@ -78,8 +80,6 @@ %D test test\number\lastnodeid test %D \stoptyping -\newinteger\c_syst_last_node_id - \permanent\protected\def\doifelselastnode {\clf_lastnodeequals} % can be public implementors \permanent\protected\def\doifelseatwordboundary{\clf_atwordboundary} % can be public implementors \permanent\protected\def\lastnodeid {\clf_lastnodeid\c_syst_last_node_id} % can be public implementors diff --git a/tex/context/fonts/mkiv/lucida-math.lfg b/tex/context/fonts/mkiv/lucida-math.lfg index c95a32c5d..31589f5b3 100644 --- a/tex/context/fonts/mkiv/lucida-math.lfg +++ b/tex/context/fonts/mkiv/lucida-math.lfg @@ -13,10 +13,10 @@ return { copyright = "ConTeXt development team", mathematics = { parameters = { - FractionRuleThickness = 55, - AccentBaseDepth = 250, - DelimiterPercent = 90, - DelimiterShortfall = 400, + FractionRuleThickness = 55, + AccentBaseDepth = 250, + DelimiterPercent = 90, + DelimiterShortfall = 400, SuperscriptBottomMaxWithSubscript = 325, PrimeShiftUp = "1.4*SuperscriptShiftUp", PrimeShiftUpCramped = "1.4*SuperscriptShiftUp", @@ -32,6 +32,18 @@ return { tweak = "fixoldschool", version = "Version 1.802", }, +{ + tweak = "parameters", + feature = "boldmath", + list = { +-- RadicalRuleThickness = 55, + RadicalRuleThickness = 60, +-- RadicalRuleThickness = "1.09*RadicalRuleThickness", +-- FractionRuleThickness = 65, +-- OverRuleThickness = 65, +-- UnderRuleThickness = 65, + } +}, { tweak = "addmirrors", }, diff --git a/tex/context/fonts/mkiv/type-imp-lucida.mkiv b/tex/context/fonts/mkiv/type-imp-lucida.mkiv index 363b0d223..1e4c35abc 100644 --- a/tex/context/fonts/mkiv/type-imp-lucida.mkiv +++ b/tex/context/fonts/mkiv/type-imp-lucida.mkiv @@ -21,7 +21,7 @@ \starttypescriptcollection[lucida-opentype] - \doifunknownfontfeature {lucida-math-bold} {\definefontfeature[lucida-math-bold][boldened]} + \doifunknownfontfeature {lucida-math-bold} {\definefontfeature[lucida-math-bold][boldened][boldmath=yes]} \starttypescript [lucida,lucidaot,lucidadk,lucidaot-nt,lucida-nt] \loadfontgoodies[lucida-opentype-math] diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index ffffb9611..e456732ef 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -453,6 +453,7 @@ <cd:variable name='printable' value='stampabile'/> <cd:variable name='process' value='process'/> <cd:variable name='product' value='prodotto'/> + <cd:variable name='profile' value='profile'/> <cd:variable name='program' value='programma'/> <cd:variable name='project' value='progetto'/> <cd:variable name='protected' value='protetto'/> @@ -725,6 +726,7 @@ <cd:constant name='bookmark' value='segnalibro'/> <cd:constant name='bottom' value='fondo'/> <cd:constant name='bottomafter' value='bottomafter'/> + <cd:constant name='bottomalign' value='bottomalign'/> <cd:constant name='bottombefore' value='bottombefore'/> <cd:constant name='bottomcolor' value='bottomcolor'/> <cd:constant name='bottomcommand' value='bottomcommand'/> @@ -1339,6 +1341,7 @@ <cd:constant name='toffset' value='toffset'/> <cd:constant name='tolerance' value='tolleranza'/> <cd:constant name='top' value='cima'/> + <cd:constant name='topalign' value='topalign'/> <cd:constant name='topcolor' value='topcolor'/> <cd:constant name='topcommand' value='topcommand'/> <cd:constant name='topdistance' value='distanzacima'/> diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 9cd8c0431..2abf5c5b9 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -453,6 +453,7 @@ <cd:variable name='printable' value='tiparibil'/> <cd:variable name='process' value='process'/> <cd:variable name='product' value='produs'/> + <cd:variable name='profile' value='profile'/> <cd:variable name='program' value='program'/> <cd:variable name='project' value='proiect'/> <cd:variable name='protected' value='protejat'/> @@ -725,6 +726,7 @@ <cd:constant name='bookmark' value='semncarte'/> <cd:constant name='bottom' value='jos'/> <cd:constant name='bottomafter' value='bottomafter'/> + <cd:constant name='bottomalign' value='bottomalign'/> <cd:constant name='bottombefore' value='bottombefore'/> <cd:constant name='bottomcolor' value='bottomcolor'/> <cd:constant name='bottomcommand' value='bottomcommand'/> @@ -1339,6 +1341,7 @@ <cd:constant name='toffset' value='toffset'/> <cd:constant name='tolerance' value='toleranta'/> <cd:constant name='top' value='sus'/> + <cd:constant name='topalign' value='topalign'/> <cd:constant name='topcolor' value='topcolor'/> <cd:constant name='topcommand' value='topcommand'/> <cd:constant name='topdistance' value='distantasus'/> diff --git a/tex/context/modules/mkiv/s-math-repertoire.mkiv b/tex/context/modules/mkiv/s-math-repertoire.mkiv index 59a2b828b..56d56bb6a 100644 --- a/tex/context/modules/mkiv/s-math-repertoire.mkiv +++ b/tex/context/modules/mkiv/s-math-repertoire.mkiv @@ -541,7 +541,7 @@ % \enabledirectives[math.nogoodies] % \showmathcharacterssetbodyfonts{lucidaot,cambria,xits,stixtwo,modern,pagella,termes,bonum,schola,dejavu} -\showmathcharacterssetbodyfonts{lucidaot,cambria,stixtwo,modern,pagella,termes,bonum,schola,ebgaramond,dejavu,modernlatin} +\showmathcharacterssetbodyfonts{lucida,cambria,stixtwo,modern,pagella,termes,bonum,schola,ebgaramond,dejavu}% ,modernlatin} % \showmathcharacterssetbodyfonts{newcomputermodern-book,lucidaot,cambria,stixtwo,modern,pagella,termes,bonum,schola,dejavu} % \showmathcharacterssetbodyfonts{newcomputermodern-book,stixtwo,modern,pagella,termes,bonum,schola,dejavu} % \showmathcharacterssetbodyfonts{newcomputermodern-book,lucidaot,cambria,stixtwo,modern,pagella,termes,schola,dejavu} @@ -551,7 +551,7 @@ \doifelse {\getdocumentargument{bodyfont}} {} { - \setupbodyfont[cambria, 12pt] + % \setupbodyfont[cambria, 12pt] % \setupbodyfont[modern, 12pt] % \setupbodyfont[lmvirtual, 12pt] % \setupbodyfont[pxvirtual, 12pt] @@ -566,7 +566,7 @@ % \setupbodyfont[bonum, 12pt] % \setupbodyfont[schola, 12pt] % \setupbodyfont[dejavu, 12pt] - % \setupbodyfont[lucidaot, 12pt] + \setupbodyfont[lucida, 12pt] % \setupbodyfont[newcomputermodern-book, 12pt] } { diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 71dafd320..045081e2b 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 : 2023-01-15 13:53 +-- merge date : 2023-01-24 13:47 do -- begin closure to overcome local limits and interference |